Adding a gateway project to demonstrate routing to a virtual network.
The work is not complete yet; this is an interim checkin. Ultimately the device.c file will be merged with the regular one or the deltas will be separated into some other file.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
all: library readprop writeprop readfile writefile reinit server dcc \
|
||||
whohas whois ucov timesync epics readpropm mstpcap \
|
||||
whoisrouter iamrouter initrouter
|
||||
whoisrouter iamrouter initrouter gateway
|
||||
@echo "utilities are in the bin directory"
|
||||
|
||||
clean: lib/Makefile\
|
||||
@@ -20,7 +20,8 @@ clean: lib/Makefile\
|
||||
demo/whoisrouter/Makefile \
|
||||
demo/iamrouter/Makefile \
|
||||
demo/initrouter/Makefile \
|
||||
demo/mstpcap/Makefile
|
||||
demo/mstpcap/Makefile \
|
||||
demo/gateway/Makefile
|
||||
make -C lib clean
|
||||
make -C demo/readprop clean
|
||||
make -C demo/readpropm clean
|
||||
@@ -39,6 +40,7 @@ clean: lib/Makefile\
|
||||
make -C demo/iamrouter clean
|
||||
make -C demo/initrouter clean
|
||||
make -C demo/mstpcap clean
|
||||
make -C demo/gateway clean
|
||||
|
||||
library: lib/Makefile
|
||||
make -C lib all
|
||||
@@ -106,6 +108,8 @@ at91sam7s: ports/at91sam7s/makefile
|
||||
bdk-atxx4-mstp: ports/bdk-atxx4-mstp/Makefile
|
||||
make -C ports/bdk-atxx4-mstp clean all
|
||||
|
||||
gateway: demo/gateway/Makefile
|
||||
( cd demo/gateway ; make ; cp bacgateway ../../bin )
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
#Makefile to build BACnet Gateway Demonstration Application for the Linux Port
|
||||
|
||||
# tools - only if you need them.
|
||||
# Most platforms have this already defined
|
||||
# CC = gcc
|
||||
|
||||
# Executable file name
|
||||
TARGET = bacgateway
|
||||
|
||||
# Configure the BACnet Datalink Layer
|
||||
#BACDL_DEFINE = -DBACDL_ETHERNET
|
||||
#BACDL_DEFINE = -DBACDL_ARCNET
|
||||
#BACDL_DEFINE = -DBACDL_MSTP
|
||||
BACDL_DEFINE = -DBACDL_BIP
|
||||
BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL -DBACFILE
|
||||
DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE)
|
||||
|
||||
# Directories
|
||||
BACNET_PORT = linux
|
||||
BACNET_PORT_DIR = ../../ports/${BACNET_PORT}
|
||||
BACNET_INCLUDE = ../../include
|
||||
|
||||
# BACnet Library
|
||||
BACNET_LIB_DIR = ../../lib
|
||||
BACNET_LIB_NAME = bacnet
|
||||
BACNET_LIB_TARGET = $(BACNET_LIB_DIR)/lib$(BACNET_LIB_NAME).a
|
||||
# Compiler Setup
|
||||
INCLUDES = -I$(BACNET_INCLUDE) -I$(BACNET_PORT_DIR)
|
||||
ifeq (${BACNET_PORT},linux)
|
||||
PFLAGS = -pthread
|
||||
TARGET_BIN = ${TARGET}
|
||||
LIBRARIES=-lc,-lgcc,-lrt,-lm,-L$(BACNET_LIB_DIR),-l$(BACNET_LIB_NAME)
|
||||
endif
|
||||
ifeq (${BACNET_PORT},win32)
|
||||
TARGET_BIN = ${TARGET}.exe
|
||||
LIBRARY1=-L$(BACNET_LIB_DIR),-l$(BACNET_LIB_NAME)
|
||||
LIBRARY2=-lws2_32,-lgcc,-lm,-liphlpapi,-lwinmm
|
||||
LIBRARIES=$(LIBRARY1),$(LIBRARY2)
|
||||
endif
|
||||
|
||||
#build for release (default) or debug
|
||||
ifeq (${BUILD},debug)
|
||||
# Use -g to put info for gdb in the executable
|
||||
DEBUGGING = -g -DDEBUG_ENABLED=1
|
||||
OPTIMIZATION = -O0
|
||||
LINK_OPTIMIZATION =
|
||||
ifeq (${BACDL_DEFINE},-DBACDL_BIP=1)
|
||||
DEFINES += -DBIP_DEBUG
|
||||
endif
|
||||
else
|
||||
DEBUGGING =
|
||||
# Use -f optimizations and then link option --gc-sections to reduce executable size.
|
||||
# Of course, not when you want debug output for gdb!
|
||||
OPTIMIZATION = -Os -fdata-sections -ffunction-sections
|
||||
LINK_OPTIMIZATION = -Wl,--gc-sections
|
||||
endif
|
||||
|
||||
# put all the flags together
|
||||
CFLAGS = -Wall $(DEBUGGING) $(OPTIMIZATION) $(INCLUDES) $(DEFINES)
|
||||
LFLAGS = -Wl,-Map=$(TARGET).map,$(LIBRARIES) $(LINK_OPTIMIZATION)
|
||||
|
||||
SRCS = main.c device.c
|
||||
|
||||
OBJS = ${SRCS:.c=.o}
|
||||
|
||||
all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN}
|
||||
size ${TARGET_BIN}
|
||||
|
||||
${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET}
|
||||
${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@
|
||||
|
||||
lib: ${BACNET_LIB_TARGET}
|
||||
|
||||
${BACNET_LIB_TARGET}:
|
||||
( cd ${BACNET_LIB_DIR} ; make clean ; make )
|
||||
|
||||
.c.o:
|
||||
${CC} -c ${CFLAGS} $*.c -o $@
|
||||
|
||||
depend:
|
||||
rm -f .depend
|
||||
${CC} -MM ${CFLAGS} *.c >> .depend
|
||||
|
||||
clean:
|
||||
rm -f core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} $(TARGET).map
|
||||
|
||||
include: .depend
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,314 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005 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.
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
/** @file device.h Defines functions for handling all BACnet objects belonging
|
||||
* to a BACnet device, as well as Device-specific properties. */
|
||||
|
||||
#ifndef DEVICE_H
|
||||
#define DEVICE_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "bacdef.h"
|
||||
#include "bacenum.h"
|
||||
#include "wp.h"
|
||||
#include "rd.h"
|
||||
#include "rp.h"
|
||||
#include "rpm.h"
|
||||
#include "readrange.h"
|
||||
|
||||
/** Called so a BACnet object can perform any necessary initialization.
|
||||
* @ingroup ObjHelpers
|
||||
*/
|
||||
typedef void (
|
||||
*object_init_function) (
|
||||
void);
|
||||
|
||||
/** Counts the number of objects of this type.
|
||||
* @ingroup ObjHelpers
|
||||
* @return Count of implemented objects of this type.
|
||||
*/
|
||||
typedef unsigned (
|
||||
*object_count_function) (
|
||||
void);
|
||||
|
||||
/** Maps an object index position to its corresponding BACnet object instance number.
|
||||
* @ingroup ObjHelpers
|
||||
* @param index [in] The index of the object, in the array of objects of its type.
|
||||
* @return The BACnet object instance number to be used in a BACNET_OBJECT_ID.
|
||||
*/
|
||||
typedef uint32_t(
|
||||
*object_index_to_instance_function)
|
||||
(
|
||||
unsigned index);
|
||||
|
||||
/** Provides the BACnet Object_Name for a given object instance of this type.
|
||||
* @ingroup ObjHelpers
|
||||
* @param [in] The object instance number to be looked up.
|
||||
* @return Pointer to a string containing the unique Object_Name. This string
|
||||
* is temporary and should be copied upon the return. It is
|
||||
* allocated by the system and does not need to be freed.
|
||||
*/
|
||||
typedef char *(
|
||||
*object_name_function)
|
||||
(
|
||||
uint32_t object_instance);
|
||||
|
||||
/** Look in the table of objects of this type, and see if this is a valid
|
||||
* instance number.
|
||||
* @ingroup ObjHelpers
|
||||
* @param [in] The object instance number to be looked up.
|
||||
* @return True if the object instance refers to a valid object of this type.
|
||||
*/
|
||||
typedef bool(
|
||||
*object_valid_instance_function) (
|
||||
uint32_t object_instance);
|
||||
|
||||
/** Helper function to step through an array of objects and find either the
|
||||
* first one or the next one of a given type. Used to step through an array
|
||||
* of objects which is not necessarily contiguous for each type i.e. the
|
||||
* index for the 'n'th object of a given type is not necessarily 'n'.
|
||||
* @ingroup ObjHelpers
|
||||
* @param [in] The index of the current object or a value of ~0 to indicate
|
||||
* start at the beginning.
|
||||
* @return The index of the next object of the required type or ~0 (all bits
|
||||
* == 1) to indicate no more objects found.
|
||||
*/
|
||||
typedef unsigned (
|
||||
*object_iterate_function) (
|
||||
unsigned current_index);
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* String Lengths - excluding any nul terminator */
|
||||
#define MAX_DEV_NAME_LEN 32
|
||||
#define MAX_DEV_LOC_LEN 64
|
||||
#define MAX_DEV_MOD_LEN 32
|
||||
#define MAX_DEV_VER_LEN 16
|
||||
#define MAX_DEV_DESC_LEN 64
|
||||
|
||||
/** Structure to define the Object Properties common to all Objects. */
|
||||
typedef struct commonBacObj_s
|
||||
{
|
||||
|
||||
/** The BACnet type of this object (ie, what class is this object from?).
|
||||
* This property, of type BACnetObjectType, indicates membership in a
|
||||
* particular object type class. Each inherited class will be of one type.
|
||||
*/
|
||||
BACNET_OBJECT_TYPE mObject_Type;
|
||||
|
||||
/** The instance number for this class instance. */
|
||||
uint32_t Object_Instance_Number;
|
||||
|
||||
/** Object Name, taken from its BACnet/WS node path; must be unique.
|
||||
* This property, of type CharacterString, shall represent a name for
|
||||
* the object that is unique within the BACnet Device that maintains it.
|
||||
* We will use the object's node path as its Name.
|
||||
*/
|
||||
char Object_Name[MAX_DEV_NAME_LEN + 1];
|
||||
} COMMON_BAC_OBJECT;
|
||||
|
||||
|
||||
/** Structure to define the variable Properties of Device Objects.
|
||||
* This structure only defines variables for properties that are unique to
|
||||
* a given Device object. The rest are fixed in device.c or hard-coded in
|
||||
* into the read-property encoding.
|
||||
*/
|
||||
typedef struct devObj_s
|
||||
{
|
||||
/** The BACnet Device Address for this device; ->len depends on DLL type. */
|
||||
BACNET_ADDRESS bacDevAddr;
|
||||
|
||||
/** Structure for the Object Properties common to all Objects. */
|
||||
COMMON_BAC_OBJECT bacObj;
|
||||
|
||||
/** Device Description. */
|
||||
char Description[MAX_DEV_DESC_LEN + 1];
|
||||
|
||||
} DEVICE_OBJECT_DATA;
|
||||
|
||||
|
||||
|
||||
void Device_Init(
|
||||
void);
|
||||
void Devices_Init(
|
||||
uint32_t first_object_instance );
|
||||
void Initialize_Device_Addresses( );
|
||||
|
||||
|
||||
bool Device_Reinitialize(
|
||||
BACNET_REINITIALIZE_DEVICE_DATA * rd_data);
|
||||
|
||||
BACNET_REINITIALIZED_STATE Device_Reinitialized_State(
|
||||
void);
|
||||
|
||||
rr_info_function Device_Objects_RR_Info(
|
||||
BACNET_OBJECT_TYPE object_type);
|
||||
|
||||
void Device_Property_Lists(
|
||||
const int **pRequired,
|
||||
const int **pOptional,
|
||||
const int **pProprietary);
|
||||
void Device_Objects_Property_List(
|
||||
BACNET_OBJECT_TYPE object_type,
|
||||
struct special_property_list_t *pPropertyList);
|
||||
|
||||
uint32_t Device_Object_Instance_Number(
|
||||
void);
|
||||
bool Device_Set_Object_Instance_Number(
|
||||
uint32_t object_id);
|
||||
bool Device_Valid_Object_Instance_Number(
|
||||
uint32_t object_id);
|
||||
unsigned Device_Object_List_Count(
|
||||
void);
|
||||
bool Device_Object_List_Identifier(
|
||||
unsigned array_index,
|
||||
int *object_type,
|
||||
uint32_t * instance);
|
||||
|
||||
unsigned Device_Count(
|
||||
void);
|
||||
uint32_t Device_Index_To_Instance(
|
||||
unsigned index);
|
||||
char *Device_Name(
|
||||
uint32_t object_instance);
|
||||
|
||||
BACNET_DEVICE_STATUS Device_System_Status(
|
||||
void);
|
||||
int Device_Set_System_Status(
|
||||
BACNET_DEVICE_STATUS status,
|
||||
bool local);
|
||||
|
||||
const char *Device_Vendor_Name(
|
||||
void);
|
||||
|
||||
uint16_t Device_Vendor_Identifier(
|
||||
void);
|
||||
void Device_Set_Vendor_Identifier(
|
||||
uint16_t vendor_id);
|
||||
|
||||
const char *Device_Model_Name(
|
||||
void);
|
||||
bool Device_Set_Model_Name(
|
||||
const char *name,
|
||||
size_t length);
|
||||
|
||||
const char *Device_Firmware_Revision(
|
||||
void);
|
||||
|
||||
const char *Device_Application_Software_Version(
|
||||
void);
|
||||
bool Device_Set_Application_Software_Version(
|
||||
const char *name,
|
||||
size_t length);
|
||||
|
||||
/* bool Device_Set_Object_Name(
|
||||
* const char *name,
|
||||
* size_t length); */
|
||||
const char *Device_Object_Name(
|
||||
void);
|
||||
|
||||
const char *Device_Description(
|
||||
void);
|
||||
/* bool Device_Set_Description(
|
||||
* const char *name,
|
||||
* size_t length); */
|
||||
|
||||
const char *Device_Location(
|
||||
void);
|
||||
bool Device_Set_Location(
|
||||
const char *name,
|
||||
size_t length);
|
||||
|
||||
/* some stack-centric constant values - no set methods */
|
||||
uint8_t Device_Protocol_Version(
|
||||
void);
|
||||
uint8_t Device_Protocol_Revision(
|
||||
void);
|
||||
BACNET_SEGMENTATION Device_Segmentation_Supported(
|
||||
void);
|
||||
|
||||
uint32_t Device_Database_Revision(
|
||||
void);
|
||||
void Device_Set_Database_Revision(
|
||||
uint32_t revision);
|
||||
void Device_Inc_Database_Revision(
|
||||
void);
|
||||
|
||||
bool Device_Valid_Object_Name(
|
||||
const char *object_name,
|
||||
int *object_type,
|
||||
uint32_t * object_instance);
|
||||
char *Device_Valid_Object_Id(
|
||||
int object_type,
|
||||
uint32_t object_instance);
|
||||
|
||||
int Device_Read_Property(
|
||||
BACNET_READ_PROPERTY_DATA * rpdata);
|
||||
bool Device_Write_Property(
|
||||
BACNET_WRITE_PROPERTY_DATA * wp_data);
|
||||
|
||||
bool DeviceGetRRInfo(
|
||||
BACNET_READ_RANGE_DATA * pRequest, /* Info on the request */
|
||||
RR_PROP_INFO * pInfo); /* Where to put the information */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
/** @defgroup ObjFrmwk Object Framework
|
||||
* The modules in this section describe the BACnet-stack's framework for
|
||||
* BACnet-defined Objects (Device, Analog Input, etc). There are two submodules
|
||||
* to describe this arrangement:
|
||||
* - The "object helper functions" which provide C++-like common functionality
|
||||
* to all supported object types.
|
||||
* - The interface between the implemented Objects and the BAC-stack services,
|
||||
* specifically the handlers, which are mediated through function calls to
|
||||
* the Device object.
|
||||
*//** @defgroup ObjHelpers Object Helper Functions
|
||||
* @ingroup ObjFrmwk
|
||||
* This section describes the function templates for the helper functions that
|
||||
* provide common object support.
|
||||
*//** @defgroup ObjIntf Handler-to-Object Interface Functions
|
||||
* @ingroup ObjFrmwk
|
||||
* This section describes the fairly limited set of functions that link the
|
||||
* BAC-stack handlers to the BACnet Object instances. All of these calls are
|
||||
* situated in the Device Object, which "knows" how to reach its child Objects.
|
||||
*
|
||||
* Most of these calls have a common operation:
|
||||
* -# Call Device_Objects_Find_Functions( for the desired Object_Type )
|
||||
* - Gets a pointer to the object_functions for this Type of Object.
|
||||
* -# Call the Object's Object_Valid_Instance( for the desired object_instance )
|
||||
* to make sure there is such an instance.
|
||||
* -# Call the Object helper function needed by the handler,
|
||||
* eg Object_Read_Property() for the RP handler.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
@@ -0,0 +1,49 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef GATEWAY_H_
|
||||
#define GATEWAY_H_
|
||||
|
||||
/** @file gateway/gateway.h Header for example gateway (ie, BACnet Router
|
||||
* and Devices) using the BACnet Stack. */
|
||||
|
||||
/** @defgroup GatewayDemo Demo of a BACnet virtual gateway (multiple Device).
|
||||
* @ingroup Demos
|
||||
* This is a basic demonstration of a BACnet Router with child devices (ie,
|
||||
* gateway) appearing on a virtual BACnet network behind the Router.
|
||||
* This is an extension of the ServerDemo project.
|
||||
*/
|
||||
|
||||
/* Device configuration definitions. */
|
||||
#define NUM_DEVICES 3 /* Gateway + two remote devices */
|
||||
#define FIRST_DEVICE_NUMBER 260001
|
||||
#define VIRTUAL_DNET 2709 /* your choice of number here */
|
||||
#define DEV_NAME_BASE "Gateway Demo Device"
|
||||
#define DEV_DESCR_GATEWAY "Gateway Device and Router"
|
||||
#define DEV_DESCR_REMOTE "Routed Remote Device"
|
||||
|
||||
|
||||
|
||||
#endif /* GATEWAY_H_ */
|
||||
@@ -0,0 +1,230 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*********************************************************************/
|
||||
/**
|
||||
* Code for this project began with code from the demo/server project and
|
||||
* Paul Chapman's vmac project.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include "config.h"
|
||||
#include "gateway.h"
|
||||
#include "address.h"
|
||||
#include "bacdef.h"
|
||||
#include "handlers.h"
|
||||
#include "client.h"
|
||||
#include "dlenv.h"
|
||||
#include "bacdcode.h"
|
||||
#include "npdu.h"
|
||||
#include "apdu.h"
|
||||
#include "iam.h"
|
||||
#include "tsm.h"
|
||||
#include "device.h"
|
||||
#include "bacfile.h"
|
||||
#include "datalink.h"
|
||||
#include "dcc.h"
|
||||
#include "net.h"
|
||||
#include "txbuf.h"
|
||||
#include "lc.h"
|
||||
#include "debug.h"
|
||||
#include "version.h"
|
||||
/* include the device object */
|
||||
#include "device.h"
|
||||
//#include "vmac.h"
|
||||
|
||||
/** @file gateway/main.c Example virtual gateway application using the BACnet Stack. */
|
||||
|
||||
/* Prototypes */
|
||||
extern void routing_npdu_handler( BACNET_ADDRESS * src, uint8_t * pdu, uint16_t pdu_len);
|
||||
|
||||
/* (Doxygen note: The next two lines pull all the following Javadoc
|
||||
* into the GatewayDemo module.) */
|
||||
/** @addtogroup GatewayDemo */
|
||||
/*@{*/
|
||||
|
||||
/** Buffer used for receiving */
|
||||
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
|
||||
|
||||
/** The list of DNETs that our router can reach.
|
||||
* Only one entry since we don't support downstream routers.
|
||||
*/
|
||||
int DNET_list[2] = {
|
||||
VIRTUAL_DNET, -1 /* Need -1 terminator */
|
||||
};
|
||||
/** Initialize the handlers we will utilize.
|
||||
* @see Device_Init, apdu_set_unconfirmed_handler, apdu_set_confirmed_handler
|
||||
*/
|
||||
static void Init_Service_Handlers(
|
||||
uint32_t first_object_instance )
|
||||
{
|
||||
Devices_Init( first_object_instance );
|
||||
/* we need to handle who-is to support dynamic device binding */
|
||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_HAS, handler_who_has);
|
||||
/* set the handler for all the services we don't implement */
|
||||
/* It is required to send the proper reject message... */
|
||||
apdu_set_unrecognized_service_handler_handler
|
||||
(handler_unrecognized_service);
|
||||
/* Set the handlers for any confirmed services that we support. */
|
||||
/* We must implement read property - it's required! */
|
||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
||||
handler_read_property);
|
||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE,
|
||||
handler_read_property_multiple);
|
||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY,
|
||||
handler_write_property);
|
||||
#if defined(BACFILE)
|
||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_ATOMIC_READ_FILE,
|
||||
handler_atomic_read_file);
|
||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_ATOMIC_WRITE_FILE,
|
||||
handler_atomic_write_file);
|
||||
#endif
|
||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_REINITIALIZE_DEVICE,
|
||||
handler_reinitialize_device);
|
||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_UTC_TIME_SYNCHRONIZATION,
|
||||
handler_timesync_utc);
|
||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_TIME_SYNCHRONIZATION,
|
||||
handler_timesync);
|
||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_SUBSCRIBE_COV,
|
||||
handler_cov_subscribe);
|
||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_COV_NOTIFICATION,
|
||||
handler_ucov_notification);
|
||||
/* handle communication so we can shutup when asked */
|
||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
|
||||
handler_device_communication_control);
|
||||
}
|
||||
|
||||
/** Handler registered with atexit() inside main function to, well, cleanup.
|
||||
* Especially if we don't end normally.
|
||||
* @see datalink_cleanup
|
||||
*/
|
||||
static void cleanup(
|
||||
void)
|
||||
{
|
||||
datalink_cleanup();
|
||||
}
|
||||
|
||||
/** Main function of server demo.
|
||||
*
|
||||
* @see Device_Set_Object_Instance_Number, dlenv_init, Send_I_Am,
|
||||
* datalink_receive, npdu_handler,
|
||||
* dcc_timer_seconds, bvlc_maintenance_timer,
|
||||
* Load_Control_State_Machine_Handler, handler_cov_task,
|
||||
* tsm_timer_milliseconds
|
||||
*
|
||||
* @param argc [in] Arg count.
|
||||
* @param argv [in] Takes one argument: the Device Instance #.
|
||||
* @return 0 on success.
|
||||
*/
|
||||
int main(
|
||||
int argc,
|
||||
char *argv[])
|
||||
{
|
||||
BACNET_ADDRESS src = {
|
||||
0
|
||||
}; /* address where message came from */
|
||||
uint16_t pdu_len = 0;
|
||||
unsigned timeout = 1000; /* milliseconds */
|
||||
time_t last_seconds = 0;
|
||||
time_t current_seconds = 0;
|
||||
uint32_t elapsed_seconds = 0;
|
||||
uint32_t elapsed_milliseconds = 0;
|
||||
uint32_t first_object_instance = FIRST_DEVICE_NUMBER;
|
||||
|
||||
/* Router data */
|
||||
// BACNET_DEVICE_PROFILE* device;
|
||||
// BACNET_VMAC_ADDRESS adr;
|
||||
|
||||
/* allow the device ID to be set */
|
||||
if (argc > 1) {
|
||||
first_object_instance = strtol(argv[1], NULL, 0);
|
||||
if ( ( first_object_instance == 0 ) ||
|
||||
( first_object_instance >= BACNET_MAX_INSTANCE ) ) {
|
||||
printf( "Error: Invalid Object Instance %s \n", argv[1] );
|
||||
printf( "Provide a number from 1 to %ul \n", BACNET_MAX_INSTANCE -1 );
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
printf("BACnet Router Demo\n" "BACnet Stack Version %s\n"
|
||||
"BACnet Device ID: %u\n" "Max APDU: %d\n", BACnet_Version,
|
||||
first_object_instance, MAX_APDU);
|
||||
Init_Service_Handlers( first_object_instance );
|
||||
dlenv_init();
|
||||
atexit(cleanup);
|
||||
Initialize_Device_Addresses( );
|
||||
|
||||
// /* initialize vmac table and router device */
|
||||
// device = vmac_initialize(99, 2001);
|
||||
//
|
||||
// debug_printf(device->name, "ROUTER:%u", vmac_get_subnet());
|
||||
|
||||
/* configure the timeout values */
|
||||
last_seconds = time(NULL);
|
||||
/* broadcast an I-Am on startup */
|
||||
Send_I_Am(&Handler_Transmit_Buffer[0]);
|
||||
|
||||
/* broadcast an I-am-router-to-network on startup */
|
||||
printf( "Remote Network DNET Number %d \n", DNET_list[0] );
|
||||
Send_I_Am_Router_To_Network( DNET_list );
|
||||
|
||||
/* loop forever */
|
||||
for (;;) {
|
||||
/* input */
|
||||
current_seconds = time(NULL);
|
||||
|
||||
/* returns 0 bytes on timeout */
|
||||
pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
|
||||
|
||||
/* process */
|
||||
if (pdu_len) {
|
||||
routing_npdu_handler(&src, &Rx_Buf[0], pdu_len);
|
||||
}
|
||||
/* at least one second has passed */
|
||||
elapsed_seconds = current_seconds - last_seconds;
|
||||
if (elapsed_seconds) {
|
||||
last_seconds = current_seconds;
|
||||
dcc_timer_seconds(elapsed_seconds);
|
||||
#if defined(BACDL_BIP) && BBMD_ENABLED
|
||||
bvlc_maintenance_timer(elapsed_seconds);
|
||||
#endif
|
||||
dlenv_maintenance_timer(elapsed_seconds);
|
||||
Load_Control_State_Machine_Handler();
|
||||
elapsed_milliseconds = elapsed_seconds * 1000;
|
||||
handler_cov_task(elapsed_seconds);
|
||||
tsm_timer_milliseconds(elapsed_milliseconds);
|
||||
}
|
||||
/* output */
|
||||
|
||||
/* blink LEDs, Turn on or off outputs, etc */
|
||||
}
|
||||
}
|
||||
|
||||
/* @} */
|
||||
|
||||
/* End group GatewayDemo */
|
||||
@@ -0,0 +1,144 @@
|
||||
#
|
||||
# Simple makefile to build an executable for Win32
|
||||
#
|
||||
# This makefile assumes Borland bcc32 development environment
|
||||
# on Windows NT/9x/2000/XP
|
||||
#
|
||||
|
||||
!ifndef BORLAND_DIR
|
||||
BORLAND_DIR_Not_Defined:
|
||||
@echo .
|
||||
@echo You must define environment variable BORLAND_DIR to compile.
|
||||
!endif
|
||||
|
||||
# target
|
||||
PRODUCT = bacgateway
|
||||
PRODUCT_EXE = $(PRODUCT).exe
|
||||
|
||||
# tools
|
||||
CC = $(BORLAND_DIR)\bin\bcc32
|
||||
MAKE=$(BORLAND_DIR)\bin\make.exe
|
||||
#LINK = $(BORLAND_DIR)\bin\tlink32
|
||||
LINK = $(BORLAND_DIR)\bin\ilink32
|
||||
|
||||
BACNET_LIB_DIR = ..\..\lib
|
||||
BACNET_LIB = $(BACNET_LIB_DIR)\bacnet.lib
|
||||
# getting back from the library
|
||||
BACNET_DEMO_DIR = ..\demo\gateway
|
||||
|
||||
# directories
|
||||
BACNET_PORT = ..\..\ports\win32
|
||||
BACNET_INCLUDE = ..\..\include
|
||||
INCLUDES = \
|
||||
-I$(BACNET_INCLUDE) \
|
||||
-I$(BACNET_PORT) \
|
||||
-I$(BORLAND_DIR)\include
|
||||
|
||||
#
|
||||
BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACFILE -DBACAPP_ALL
|
||||
#BACDL_DEFINE=-DBACDL_MSTP -DCRC_USE_TABLE
|
||||
BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1
|
||||
DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE)
|
||||
|
||||
SRCS = main.c device.c
|
||||
|
||||
OBJS = $(SRCS:.c=.obj)
|
||||
|
||||
#
|
||||
# Compiler definitions
|
||||
#
|
||||
BCC_CFG = bcc32.cfg
|
||||
|
||||
#
|
||||
# Include directories
|
||||
#
|
||||
CFLAGS = $(INCLUDES) $(DEFINES)
|
||||
|
||||
#
|
||||
# Libraries
|
||||
#
|
||||
C_LIB_DIR = $(BORLAND_DIR)\lib
|
||||
|
||||
LIBS = $(BACNET_LIB) \
|
||||
$(C_LIB_DIR)\IMPORT32.lib \
|
||||
$(C_LIB_DIR)\CW32MT.lib \
|
||||
|
||||
#
|
||||
# Main target
|
||||
#
|
||||
# This should be the first one in the makefile
|
||||
|
||||
all : $(BACNET_LIB) $(BCC_CFG) $(OBJS) $(PRODUCT_EXE)
|
||||
del $(BCC_CFG)
|
||||
|
||||
install: $(PRODUCT_EXE)
|
||||
copy $(PRODUCT_EXE) ..\..\bin\$(PRODUCT_EXE)
|
||||
|
||||
$(BACNET_LIB):
|
||||
cd $(BACNET_LIB_DIR)
|
||||
$(MAKE) -i -f makefile.b32 clean
|
||||
$(MAKE) -f makefile.b32 all
|
||||
cd $(BACNET_DEMO_DIR)
|
||||
|
||||
# Linker specific: the link below is for BCC linker/compiler. If you link
|
||||
# with a different linker - please change accordingly.
|
||||
#
|
||||
|
||||
# need a temp response file (@&&| ... |) because command line is too long
|
||||
# $** lists each dependency
|
||||
# $< target name
|
||||
# $* target name without extension
|
||||
$(PRODUCT_EXE) : $(OBJS)
|
||||
@echo Running Linker for $(PRODUCT_EXE)
|
||||
$(LINK) -L$(C_LIB_DIR) -L$(BACNET_LIB_DIR) -m -c -s -v @&&|
|
||||
$(BORLAND_DIR)\lib\c0x32.obj $**
|
||||
$<
|
||||
$*.map
|
||||
$(LIBS)
|
||||
|
|
||||
|
||||
#
|
||||
# Utilities
|
||||
|
||||
clean :
|
||||
del $(OBJS)
|
||||
del $(PRODUCT_EXE)
|
||||
del $(PRODUCT).map
|
||||
del $(PRODUCT).ilc
|
||||
del $(PRODUCT).ild
|
||||
del $(PRODUCT).ilf
|
||||
del $(PRODUCT).ils
|
||||
del $(PRODUCT).tds
|
||||
del $(BCC_CFG)
|
||||
|
||||
#
|
||||
# Generic rules
|
||||
#
|
||||
.SUFFIXES: .cpp .c .sbr .obj
|
||||
|
||||
#
|
||||
# cc generic rule
|
||||
#
|
||||
.c.obj:
|
||||
$(CC) +$(BCC_CFG) -o$@ $<
|
||||
|
||||
# Compiler configuration file
|
||||
$(BCC_CFG) :
|
||||
Copy &&|
|
||||
$(CFLAGS)
|
||||
-c
|
||||
-y #include line numbers in OBJ's
|
||||
-v #include debug info
|
||||
-w+ #turn on all warnings
|
||||
#-Od #disable all optimizations
|
||||
-O2 #disable all optimizations
|
||||
-WM #multithread
|
||||
#-WM- #not multithread
|
||||
-w-aus # ignore warning assigned a value that is never used
|
||||
-w-sig # ignore warning conversion may lose sig digits
|
||||
#-a4 #32 bit data alignment
|
||||
#-M # generate link map
|
||||
#-ls # linker options
|
||||
| $@
|
||||
|
||||
# EOF: makefile
|
||||
Reference in New Issue
Block a user