Add multi-device support for BACnet gateway routing (#1279)
* Expanded Object_List to Object_List[MAX_NUM_DEVICES] array to support per-device objects for virtual remote devices * Added multi-device iteration for COV handler, device timer, and intrinsic reporting * Added apps/gateway2 demo application * When MAX_NUM_DEVICES == 1, behavior is identical to the original implementation * Conditional compilation with macros ensures no impact on non-gateway applications --------- Signed-off-by: Hyeongjun Kim <hjun1.kim@samsung.com> Co-authored-by: haemeok-kang <haemeok.kang@samsung.com>
This commit is contained in:
@@ -1022,6 +1022,15 @@ if(BACNET_STACK_BUILD_APPS)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(BAC_ROUTING)
|
||||
add_executable(gateway2 apps/gateway2/main.c apps/gateway2/gateway.h)
|
||||
target_link_libraries(gateway2 PRIVATE ${PROJECT_NAME})
|
||||
target_compile_options(gateway2 PRIVATE
|
||||
# Unreachable code because we have endless loop.
|
||||
$<$<C_COMPILER_ID:MSVC>:/wd4702>
|
||||
)
|
||||
endif()
|
||||
|
||||
add_executable(getevent apps/getevent/main.c)
|
||||
target_link_libraries(getevent PRIVATE ${PROJECT_NAME})
|
||||
|
||||
|
||||
@@ -160,6 +160,14 @@ gateway:
|
||||
gateway-win32:
|
||||
$(MAKE) BACNET_PORT=win32 -s -B -C apps gateway
|
||||
|
||||
.PHONY: gateway2
|
||||
gateway2:
|
||||
$(MAKE) -s -B -C apps $@
|
||||
|
||||
.PHONY: gateway2-win32
|
||||
gateway2-win32:
|
||||
$(MAKE) BACNET_PORT=win32 -s -B -C apps gateway2
|
||||
|
||||
.PHONY: piface
|
||||
piface:
|
||||
$(MAKE) CSTANDARD="-std=gnu11" LEGACY=true -s -C apps $@
|
||||
@@ -543,6 +551,7 @@ clean: ports-clean
|
||||
$(MAKE) -s -C apps/router-ipv6 clean
|
||||
$(MAKE) -s -C apps/router-mstp clean
|
||||
$(MAKE) -s -C apps/gateway clean
|
||||
$(MAKE) -s -C apps/gateway2 clean
|
||||
$(MAKE) -s -C apps/sc-hub clean
|
||||
$(MAKE) -s -C apps/fuzz-afl clean
|
||||
$(MAKE) -s -C apps/fuzz-libfuzzer clean
|
||||
|
||||
@@ -334,6 +334,10 @@ clean:
|
||||
gateway: $(BACNET_LIB_TARGET)
|
||||
$(MAKE) -B -C $@
|
||||
|
||||
.PHONY: gateway2
|
||||
gateway2: $(BACNET_LIB_TARGET)
|
||||
$(MAKE) -B -C $@
|
||||
|
||||
.PHONY: abort
|
||||
abort: $(BACNET_LIB_TARGET)
|
||||
$(MAKE) -B -C $@
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
#Makefile to build BACnet Application using GCC compiler
|
||||
|
||||
# Executable file name
|
||||
TARGET = bacgateway2
|
||||
|
||||
SRC := main.c
|
||||
|
||||
BACNET_SRC_DIR ?= $(realpath ../../src)
|
||||
BACNET_OBJECT_DIR = $(BACNET_SRC_DIR)/bacnet/basic/object
|
||||
|
||||
BACNET_OBJECT_SRC := \
|
||||
$(BACNET_OBJECT_DIR)/gateway/gw_device.c \
|
||||
$(BACNET_OBJECT_DIR)/device.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)/ai.c \
|
||||
$(BACNET_OBJECT_DIR)/ao.c \
|
||||
$(BACNET_OBJECT_DIR)/av.c \
|
||||
$(BACNET_OBJECT_DIR)/acc.c \
|
||||
$(BACNET_OBJECT_DIR)/auditlog.c \
|
||||
$(BACNET_OBJECT_DIR)/bacfile.c \
|
||||
$(BACNET_OBJECT_DIR)/bi.c \
|
||||
$(BACNET_OBJECT_DIR)/bitstring_value.c \
|
||||
$(BACNET_OBJECT_DIR)/bo.c \
|
||||
$(BACNET_OBJECT_DIR)/blo.c \
|
||||
$(BACNET_OBJECT_DIR)/bv.c \
|
||||
$(BACNET_OBJECT_DIR)/calendar.c \
|
||||
$(BACNET_OBJECT_DIR)/channel.c \
|
||||
$(BACNET_OBJECT_DIR)/color_object.c \
|
||||
$(BACNET_OBJECT_DIR)/color_temperature.c \
|
||||
$(BACNET_OBJECT_DIR)/command.c \
|
||||
$(BACNET_OBJECT_DIR)/credential_data_input.c \
|
||||
$(BACNET_OBJECT_DIR)/csv.c \
|
||||
$(BACNET_OBJECT_DIR)/iv.c \
|
||||
$(BACNET_OBJECT_DIR)/lc.c \
|
||||
$(BACNET_OBJECT_DIR)/lo.c \
|
||||
$(BACNET_OBJECT_DIR)/loop.c \
|
||||
$(BACNET_OBJECT_DIR)/lsp.c \
|
||||
$(BACNET_OBJECT_DIR)/lsz.c \
|
||||
$(BACNET_OBJECT_DIR)/ms-input.c \
|
||||
$(BACNET_OBJECT_DIR)/mso.c \
|
||||
$(BACNET_OBJECT_DIR)/msv.c \
|
||||
$(BACNET_OBJECT_DIR)/nc.c \
|
||||
$(BACNET_OBJECT_DIR)/netport.c \
|
||||
$(BACNET_OBJECT_DIR)/osv.c \
|
||||
$(BACNET_OBJECT_DIR)/piv.c \
|
||||
$(BACNET_OBJECT_DIR)/program.c \
|
||||
$(BACNET_OBJECT_DIR)/schedule.c \
|
||||
$(BACNET_OBJECT_DIR)/structured_view.c \
|
||||
$(BACNET_OBJECT_DIR)/time_value.c \
|
||||
$(BACNET_OBJECT_DIR)/timer.c \
|
||||
$(BACNET_OBJECT_DIR)/trendlog.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_routed_npdu.c \
|
||||
$(BACNET_SRC_DIR)/bacnet/basic/npdu/s_router.c \
|
||||
$(BACNET_SRC_DIR)/bacnet/basic/tsm/tsm.c \
|
||||
$(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_OBJECT_SRC) $(BACNET_BASIC_SRC)
|
||||
|
||||
OBJS := $(SRCS:.c=.o)
|
||||
|
||||
CFLAGS += -DBAC_ROUTING
|
||||
|
||||
.PHONY: all
|
||||
all: Makefile ${TARGET_BIN}
|
||||
|
||||
${TARGET_BIN}: ${OBJS}
|
||||
${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@
|
||||
size $@
|
||||
cp $@ ../../bin
|
||||
|
||||
.c.o:
|
||||
${CC} -c ${CFLAGS} $*.c -o $@
|
||||
|
||||
.PHONY: depend
|
||||
depend:
|
||||
rm -f .depend
|
||||
${CC} -MM ${CFLAGS} *.c >> .depend
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f core ${TARGET_BIN} ${OBJS} $(TARGET).map
|
||||
|
||||
.PHONY: include
|
||||
include: .depend
|
||||
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Header for example gateway (ie, BACnet Router and Devices)
|
||||
* using the BACnet Stack.
|
||||
* @author Tom Brennan <tbrennan3@users.sourceforge.net>
|
||||
* @date 2010
|
||||
* @copyright SPDX-License-Identifier: MIT
|
||||
*/
|
||||
#ifndef BACNET_GATEWAY_H_
|
||||
#define BACNET_GATEWAY_H_
|
||||
|
||||
#include "bacnet/config.h"
|
||||
|
||||
/** @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 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"
|
||||
#define VIRTUAL_DEVICE_COUNT 10
|
||||
#define VIRTUAL_DEVICE_INDEX_OFFSET 1
|
||||
|
||||
#if VIRTUAL_DEVICE_COUNT >= MAX_NUM_DEVICES
|
||||
#ifdef _MSC_VER
|
||||
#pragma message( \
|
||||
"VIRTUAL_DEVICE_COUNT >= MAX_NUM_DEVICES, adjusting to MAX_NUM_DEVICES-1")
|
||||
#else
|
||||
#warning \
|
||||
"VIRTUAL_DEVICE_COUNT >= MAX_NUM_DEVICES, adjusting to MAX_NUM_DEVICES-1"
|
||||
#endif
|
||||
#undef VIRTUAL_DEVICE_COUNT
|
||||
#define VIRTUAL_DEVICE_COUNT (MAX_NUM_DEVICES - 1)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,339 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Example virtual gateway application using the BACnet Stack.
|
||||
* Code for this project began with code from the demo/server project and
|
||||
* Paul Chapman's vmac project.
|
||||
* @author Tom Brennan <tbrennan3@users.sourceforge.net>
|
||||
* @author Hyeongjun Kim <sicad3@gmail.com>
|
||||
* @date 2026
|
||||
* @copyright SPDX-License-Identifier: MIT
|
||||
*/
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
/* BACnet Stack defines - first */
|
||||
#include "bacnet/bacdef.h"
|
||||
/* BACnet Stack API */
|
||||
#include "bacnet/bacdcode.h"
|
||||
#include "bacnet/npdu.h"
|
||||
#include "bacnet/apdu.h"
|
||||
#include "bacnet/iam.h"
|
||||
#include "bacnet/dcc.h"
|
||||
#include "bacnet/version.h"
|
||||
/* some demo stuff needed */
|
||||
#include "bacnet/basic/binding/address.h"
|
||||
#include "bacnet/basic/tsm/tsm.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
#include "bacnet/basic/sys/debug.h"
|
||||
#include "bacnet/datalink/datalink.h"
|
||||
#include "bacnet/datalink/dlenv.h"
|
||||
/* include the device object */
|
||||
#include "bacnet/basic/object/device.h"
|
||||
#include "bacnet/basic/object/bacfile.h"
|
||||
#include "bacnet/basic/object/lc.h"
|
||||
#include "bacnet/basic/object/ai.h"
|
||||
#include "bacnet/basic/object/ao.h"
|
||||
#ifdef BACNET_TEST_VMAC
|
||||
#include "bacnet/basic/bbmd6/vmac.h"
|
||||
#endif
|
||||
/* me! */
|
||||
#include "gateway.h"
|
||||
|
||||
/* Prototypes */
|
||||
|
||||
/* (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 */
|
||||
};
|
||||
|
||||
/* current version of the BACnet stack */
|
||||
static const char *BACnet_Version = BACNET_VERSION_TEXT;
|
||||
|
||||
/* Virtual devices start at index 1 (gateway is at 0) */
|
||||
static unsigned Routed_Device_Index = 1;
|
||||
|
||||
/** Initialize the Device Objects and each of the child Object instances.
|
||||
* @param first_object_instance Set the first (gateway) Device to this
|
||||
instance number, and subsequent devices to incremented values.
|
||||
*/
|
||||
static void Devices_Init(uint32_t first_object_instance)
|
||||
{
|
||||
int i;
|
||||
int dev_idx;
|
||||
int instance_number = 0;
|
||||
char nameText[MAX_DEV_NAME_LEN];
|
||||
char descText[MAX_DEV_DESC_LEN];
|
||||
BACNET_CHARACTER_STRING name_string;
|
||||
|
||||
/* Gateway Device has already been initialized.
|
||||
* But give it a better Description. */
|
||||
Routed_Device_Set_Description(DEV_DESCR_GATEWAY, strlen(DEV_DESCR_GATEWAY));
|
||||
|
||||
/* Gateway - analog_input */
|
||||
instance_number = 1000;
|
||||
Analog_Input_Create(instance_number);
|
||||
Analog_Input_Name_Set(instance_number, "Gateway Analog Input");
|
||||
Analog_Input_Present_Value_Set(instance_number, 100.0);
|
||||
|
||||
/* Gateway - analog_onput */
|
||||
instance_number = 1001;
|
||||
Analog_Output_Create(instance_number);
|
||||
Analog_Output_Name_Set(instance_number, "Gateway Analog Output");
|
||||
|
||||
Analog_Output_Present_Value_Set(instance_number, 50.0, BACNET_MAX_PRIORITY);
|
||||
|
||||
/* Now initialize the remote Device objects. */
|
||||
for (i = 0; i < VIRTUAL_DEVICE_COUNT; i++) {
|
||||
dev_idx = i + 1;
|
||||
snprintf(
|
||||
nameText, MAX_DEV_NAME_LEN, "%s %d", DEV_NAME_BASE, dev_idx + 1);
|
||||
snprintf(
|
||||
descText, MAX_DEV_DESC_LEN, "%s %d", DEV_DESCR_REMOTE, dev_idx);
|
||||
characterstring_init_ansi(&name_string, nameText);
|
||||
|
||||
Add_Routed_Device(
|
||||
(first_object_instance + dev_idx), &name_string, descText);
|
||||
|
||||
/* Gateway - analog_input */
|
||||
instance_number = dev_idx * 10000 + 1000;
|
||||
Analog_Input_Create(instance_number);
|
||||
Analog_Input_Name_Set(instance_number, "Gateway Analog Input");
|
||||
Analog_Input_Present_Value_Set(instance_number, 0.1 + (float)dev_idx);
|
||||
|
||||
/* Gateway - analog_onput */
|
||||
instance_number = dev_idx * 10000 + 1001;
|
||||
Analog_Output_Create(instance_number);
|
||||
Analog_Output_Name_Set(instance_number, "Gateway Analog Output");
|
||||
Analog_Output_Relinquish_Default_Set(instance_number, 100);
|
||||
Analog_Output_Present_Value_Set(
|
||||
instance_number, 0.9 + (float)i, BACNET_MAX_PRIORITY);
|
||||
}
|
||||
}
|
||||
|
||||
/** Initialize the BACnet Device Addresses for each Device object.
|
||||
* The gateway has already gotten the normal address (eg, PC's IP for BIP) and
|
||||
* the remote devices get
|
||||
* - For BIP, the IP address reversed, and 4th byte equal to index.
|
||||
* (Eg, 11.22.33.44 for the gateway becomes 44.33.22.01 for the first remote
|
||||
* device.) This is sure to be unique! The port number stays the same.
|
||||
* - For MS/TP, [Steve inserts a good idea here]
|
||||
*/
|
||||
static void Initialize_Device_Addresses(void)
|
||||
{
|
||||
int i = 0; /* First entry is Gateway Device */
|
||||
uint32_t virtual_mac = 0;
|
||||
BACNET_ADDRESS virtual_address = { 0 };
|
||||
DEVICE_OBJECT_DATA *pDev = NULL;
|
||||
/* Setup info for the main gateway device first */
|
||||
pDev = Get_Routed_Device_Object(i);
|
||||
|
||||
/* we can't use datalink_get_my_address() since it is
|
||||
mapped to routed_get_my_address() in this app
|
||||
to get the parent device address */
|
||||
#if defined(BACDL_BIP)
|
||||
bip_get_my_address(&virtual_address);
|
||||
#elif defined(BACDL_MSTP)
|
||||
dlmstp_get_my_address(&virtual_address);
|
||||
#elif defined(BACDL_ARCNET)
|
||||
arcnet_get_my_address(&virtual_address);
|
||||
#elif defined(BACDL_ETHERNET)
|
||||
ethernet_get_my_address(&virtual_address);
|
||||
#elif defined(BACDL_BIP6)
|
||||
bip6_get_my_address(&virtual_address);
|
||||
#else
|
||||
#error "No support for this Data Link Layer type "
|
||||
#endif
|
||||
bacnet_address_copy(&pDev->bacDevAddr, &virtual_address);
|
||||
/* broadcast an I-Am on startup */
|
||||
Send_I_Am(&Handler_Transmit_Buffer[0]);
|
||||
|
||||
/* Virtual devices start at index 1 (gateway is at 0) */
|
||||
for (i = 1; i < Get_Num_Managed_Devices(); i++) {
|
||||
pDev = Get_Routed_Device_Object(i);
|
||||
if (pDev == NULL) {
|
||||
continue;
|
||||
}
|
||||
/* start with the router address */
|
||||
bacnet_address_copy(&pDev->bacDevAddr, &virtual_address);
|
||||
/* add the network number to each gateway device */
|
||||
pDev->bacDevAddr.net = VIRTUAL_DNET;
|
||||
/* use a virtual MAC for each gateway device */
|
||||
virtual_mac = pDev->bacObj.Object_Instance_Number;
|
||||
encode_unsigned24(&pDev->bacDevAddr.adr[0], virtual_mac);
|
||||
pDev->bacDevAddr.len = 3;
|
||||
}
|
||||
}
|
||||
|
||||
/** 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)
|
||||
{
|
||||
Device_Init(NULL);
|
||||
Routing_Device_Init(first_object_instance);
|
||||
|
||||
/* we need to handle who-is to support dynamic device binding
|
||||
* For the gateway, we will use the unicast variety so we can
|
||||
* get back through switches to different subnets.
|
||||
* Don't need the routed versions, since the npdu handler calls
|
||||
* each device in turn.
|
||||
*/
|
||||
apdu_set_unconfirmed_handler(
|
||||
SERVICE_UNCONFIRMED_WHO_IS, handler_who_is_unicast);
|
||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_HAS, handler_who_has);
|
||||
/* set the handler for all the services we don't implement */
|
||||
/* It is required to send the proper reject message... */
|
||||
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
||||
/* Set the handlers for any confirmed services that we support. */
|
||||
/* We must implement read property - it's required! */
|
||||
apdu_set_confirmed_handler(
|
||||
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
|
||||
apdu_set_confirmed_handler(
|
||||
SERVICE_CONFIRMED_READ_PROP_MULTIPLE, handler_read_property_multiple);
|
||||
apdu_set_confirmed_handler(
|
||||
SERVICE_CONFIRMED_WRITE_PROPERTY, handler_write_property);
|
||||
apdu_set_confirmed_handler(
|
||||
SERVICE_CONFIRMED_READ_RANGE, handler_read_range);
|
||||
#if defined BACNET_BACKUP_RESTORE
|
||||
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);
|
||||
/* handle communication so we can shutup when asked */
|
||||
apdu_set_confirmed_handler(
|
||||
SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
|
||||
handler_device_communication_control);
|
||||
}
|
||||
|
||||
/** Main function of server demo.
|
||||
*
|
||||
* @see Device_Set_Object_Instance_Number, dlenv_init, Send_I_Am,
|
||||
* datalink_receive, npdu_handler,
|
||||
* dcc_timer_seconds, datalink_maintenance_timer,
|
||||
* 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 = 1; /* 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;
|
||||
#ifdef BACNET_TEST_VMAC
|
||||
/* Router data */
|
||||
BACNET_DEVICE_PROFILE *device;
|
||||
BACNET_VMAC_ADDRESS adr;
|
||||
#endif
|
||||
|
||||
/* 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 %lu \n",
|
||||
(unsigned long)BACNET_MAX_INSTANCE);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
printf(
|
||||
"BACnet Router Demo\n"
|
||||
"BACnet Stack Version %s\n"
|
||||
"BACnet Device ID: %u\n"
|
||||
"Max APDU: %d\n"
|
||||
"Max Devices: %d\n"
|
||||
"Virtual Devices Count: %d\n",
|
||||
BACnet_Version, first_object_instance, MAX_APDU, MAX_NUM_DEVICES,
|
||||
VIRTUAL_DEVICE_COUNT);
|
||||
Init_Service_Handlers(first_object_instance);
|
||||
dlenv_init();
|
||||
atexit(datalink_cleanup);
|
||||
Devices_Init(first_object_instance);
|
||||
Initialize_Device_Addresses();
|
||||
|
||||
#ifdef BACNET_TEST_VMAC
|
||||
/* initialize vmac table and router device */
|
||||
device = vmac_initialize(99, 2001);
|
||||
debug_printf(device->name, "ROUTER:%u", vmac_get_subnet());
|
||||
#endif
|
||||
/* configure the timeout values */
|
||||
last_seconds = time(NULL);
|
||||
|
||||
/* 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);
|
||||
Send_Network_Number_Is(NULL, DNET_list[0], NETWORK_NUMBER_CONFIGURED);
|
||||
|
||||
handler_cov_init();
|
||||
|
||||
/* 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, DNET_list, &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);
|
||||
datalink_maintenance_timer(elapsed_seconds);
|
||||
dlenv_maintenance_timer(elapsed_seconds);
|
||||
elapsed_milliseconds = elapsed_seconds * 1000;
|
||||
tsm_timer_milliseconds(elapsed_milliseconds);
|
||||
Device_Timer(elapsed_milliseconds);
|
||||
}
|
||||
|
||||
handler_cov_task();
|
||||
|
||||
if (Routed_Device_Index < Get_Num_Managed_Devices()) {
|
||||
Get_Routed_Device_Object(Routed_Device_Index);
|
||||
/* broadcast an I-Am for each routed Device now */
|
||||
Send_I_Am(&Handler_Transmit_Buffer[0]);
|
||||
Routed_Device_Index++;
|
||||
}
|
||||
}
|
||||
/* Dummy return */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* @} */
|
||||
|
||||
/* End group GatewayDemo */
|
||||
@@ -17,10 +17,18 @@
|
||||
#include "bacnet/rp.h"
|
||||
#include "bacnet/wp.h"
|
||||
#include "bacnet/basic/sys/keylist.h"
|
||||
/* BACnet Stack Objects */
|
||||
#include "bacnet/basic/object/device.h"
|
||||
/* me! */
|
||||
#include "bacnet/basic/object/acc.h"
|
||||
|
||||
/* Key List for storing the object data sorted by instance number */
|
||||
static OS_Keylist Object_List = NULL;
|
||||
static OS_Keylist Object_Lists[MAX_NUM_DEVICES];
|
||||
#ifdef BAC_ROUTING
|
||||
#define Object_List (Object_Lists[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define Object_List (Object_Lists[0])
|
||||
#endif
|
||||
/* common object type */
|
||||
static const BACNET_OBJECT_TYPE Object_Type = OBJECT_ACCUMULATOR;
|
||||
|
||||
|
||||
@@ -14,14 +14,23 @@
|
||||
/* BACnet Stack API */
|
||||
#include "bacnet/bacdcode.h"
|
||||
#include "bacnet/bacapp.h"
|
||||
#include "bacnet/bacenum.h"
|
||||
#include "bacnet/wp.h"
|
||||
#include "bacnet/proplist.h"
|
||||
#include "bacnet/basic/object/access_credential.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
/* BACnet Stack Objects */
|
||||
#include "bacnet/basic/object/device.h"
|
||||
|
||||
static bool Access_Credential_Initialized = false;
|
||||
|
||||
static ACCESS_CREDENTIAL_DESCR ac_descr[MAX_ACCESS_CREDENTIALS];
|
||||
static ACCESS_CREDENTIAL_DESCR ac_descrs[MAX_NUM_DEVICES]
|
||||
[MAX_ACCESS_CREDENTIALS];
|
||||
#ifdef BAC_ROUTING
|
||||
#define ac_descr (ac_descrs[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define ac_descr (ac_descrs[0])
|
||||
#endif
|
||||
|
||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||
static const int32_t Properties_Required[] = {
|
||||
@@ -90,24 +99,38 @@ void Access_Credential_Writable_Property_List(
|
||||
void Access_Credential_Init(void)
|
||||
{
|
||||
unsigned i;
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
if (!Access_Credential_Initialized) {
|
||||
Access_Credential_Initialized = true;
|
||||
|
||||
for (i = 0; i < MAX_ACCESS_CREDENTIALS; i++) {
|
||||
ac_descr[i].global_identifier =
|
||||
0; /* set to some meaningful value */
|
||||
ac_descr[i].reliability = RELIABILITY_NO_FAULT_DETECTED;
|
||||
ac_descr[i].credential_status = false;
|
||||
ac_descr[i].reasons_count = 0;
|
||||
ac_descr[i].auth_factors_count = 0;
|
||||
memset(&ac_descr[i].activation_time, 0, sizeof(BACNET_DATE_TIME));
|
||||
memset(&ac_descr[i].expiration_time, 0, sizeof(BACNET_DATE_TIME));
|
||||
ac_descr[i].credential_disable = ACCESS_CREDENTIAL_DISABLE_NONE;
|
||||
ac_descr[i].assigned_access_rights_count = 0;
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
for (i = 0; i < MAX_ACCESS_CREDENTIALS; i++) {
|
||||
ac_descr[i].global_identifier =
|
||||
0; /* set to some meaningful value */
|
||||
ac_descr[i].reliability = RELIABILITY_NO_FAULT_DETECTED;
|
||||
ac_descr[i].credential_status = false;
|
||||
ac_descr[i].reasons_count = 0;
|
||||
ac_descr[i].auth_factors_count = 0;
|
||||
memset(
|
||||
&ac_descr[i].activation_time, 0, sizeof(BACNET_DATE_TIME));
|
||||
memset(
|
||||
&ac_descr[i].expiration_time, 0, sizeof(BACNET_DATE_TIME));
|
||||
ac_descr[i].credential_disable = ACCESS_CREDENTIAL_DISABLE_NONE;
|
||||
ac_descr[i].assigned_access_rights_count = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,10 +16,17 @@
|
||||
#include "bacnet/wp.h"
|
||||
#include "access_door.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
/* BACnet Stack Objects */
|
||||
#include "bacnet/basic/object/device.h"
|
||||
|
||||
static bool Access_Door_Initialized = false;
|
||||
|
||||
static ACCESS_DOOR_DESCR ad_descr[MAX_ACCESS_DOORS];
|
||||
static ACCESS_DOOR_DESCR ad_descrs[MAX_NUM_DEVICES][MAX_ACCESS_DOORS];
|
||||
#ifdef BAC_ROUTING
|
||||
#define ad_descr (ad_descrs[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define ad_descr (ad_descrs[0])
|
||||
#endif
|
||||
|
||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||
static const int32_t Properties_Required[] = {
|
||||
@@ -94,32 +101,45 @@ void Access_Door_Writable_Property_List(
|
||||
void Access_Door_Init(void)
|
||||
{
|
||||
unsigned i, j;
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
if (!Access_Door_Initialized) {
|
||||
Access_Door_Initialized = true;
|
||||
|
||||
/* initialize all the access door priority arrays to NULL */
|
||||
for (i = 0; i < MAX_ACCESS_DOORS; i++) {
|
||||
ad_descr[i].relinquish_default = DOOR_VALUE_LOCK;
|
||||
ad_descr[i].event_state = EVENT_STATE_NORMAL;
|
||||
ad_descr[i].reliability = RELIABILITY_NO_FAULT_DETECTED;
|
||||
ad_descr[i].out_of_service = false;
|
||||
ad_descr[i].door_status = DOOR_STATUS_CLOSED;
|
||||
ad_descr[i].lock_status = LOCK_STATUS_LOCKED;
|
||||
ad_descr[i].secured_status = DOOR_SECURED_STATUS_SECURED;
|
||||
ad_descr[i].door_pulse_time = 30; /* 3s */
|
||||
ad_descr[i].door_extended_pulse_time = 50; /* 5s */
|
||||
ad_descr[i].door_unlock_delay_time = 0; /* 0s */
|
||||
ad_descr[i].door_open_too_long_time = 300; /* 30s */
|
||||
ad_descr[i].door_alarm_state = DOOR_ALARM_STATE_NORMAL;
|
||||
for (j = 0; j < BACNET_MAX_PRIORITY; j++) {
|
||||
ad_descr[i].value_active[j] = false;
|
||||
/* just to fill in */
|
||||
ad_descr[i].priority_array[j] = DOOR_VALUE_LOCK;
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
/* initialize all the access door priority arrays to NULL */
|
||||
for (i = 0; i < MAX_ACCESS_DOORS; i++) {
|
||||
ad_descr[i].relinquish_default = DOOR_VALUE_LOCK;
|
||||
ad_descr[i].event_state = EVENT_STATE_NORMAL;
|
||||
ad_descr[i].reliability = RELIABILITY_NO_FAULT_DETECTED;
|
||||
ad_descr[i].out_of_service = false;
|
||||
ad_descr[i].door_status = DOOR_STATUS_CLOSED;
|
||||
ad_descr[i].lock_status = LOCK_STATUS_LOCKED;
|
||||
ad_descr[i].secured_status = DOOR_SECURED_STATUS_SECURED;
|
||||
ad_descr[i].door_pulse_time = 30; /* 3s */
|
||||
ad_descr[i].door_extended_pulse_time = 50; /* 5s */
|
||||
ad_descr[i].door_unlock_delay_time = 0; /* 0s */
|
||||
ad_descr[i].door_open_too_long_time = 300; /* 30s */
|
||||
ad_descr[i].door_alarm_state = DOOR_ALARM_STATE_NORMAL;
|
||||
for (j = 0; j < BACNET_MAX_PRIORITY; j++) {
|
||||
ad_descr[i].value_active[j] = false;
|
||||
/* just to fill in */
|
||||
ad_descr[i].priority_array[j] = DOOR_VALUE_LOCK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,10 +16,17 @@
|
||||
#include "bacnet/wp.h"
|
||||
#include "access_point.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
/* BACnet Stack Objects */
|
||||
#include "bacnet/basic/object/device.h"
|
||||
|
||||
static bool Access_Point_Initialized = false;
|
||||
|
||||
static ACCESS_POINT_DESCR ap_descr[MAX_ACCESS_POINTS];
|
||||
static ACCESS_POINT_DESCR ap_descrs[MAX_NUM_DEVICES][MAX_ACCESS_POINTS];
|
||||
#ifdef BAC_ROUTING
|
||||
#define ap_descr (ap_descrs[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define ap_descr (ap_descrs[0])
|
||||
#endif
|
||||
|
||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||
static const int32_t Properties_Required[] = {
|
||||
@@ -93,27 +100,43 @@ void Access_Point_Writable_Property_List(
|
||||
void Access_Point_Init(void)
|
||||
{
|
||||
unsigned i;
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
if (!Access_Point_Initialized) {
|
||||
Access_Point_Initialized = true;
|
||||
|
||||
for (i = 0; i < MAX_ACCESS_POINTS; i++) {
|
||||
ap_descr[i].event_state = EVENT_STATE_NORMAL;
|
||||
ap_descr[i].reliability = RELIABILITY_NO_FAULT_DETECTED;
|
||||
ap_descr[i].out_of_service = false;
|
||||
ap_descr[i].authentication_status = AUTHENTICATION_STATUS_NOT_READY;
|
||||
ap_descr[i].active_authentication_policy = 0;
|
||||
ap_descr[i].number_of_authentication_policies = 0;
|
||||
ap_descr[i].authorization_mode = AUTHORIZATION_MODE_AUTHORIZE;
|
||||
ap_descr[i].access_event = ACCESS_EVENT_NONE;
|
||||
/* timestamp uninitialized */
|
||||
/* access_event_credential should be set to some meaningful value */
|
||||
ap_descr[i].num_doors = 0;
|
||||
/* fill in the access doors with proper ids */
|
||||
ap_descr[i].priority_for_writing = 16; /* lowest possible for now */
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
for (i = 0; i < MAX_ACCESS_POINTS; i++) {
|
||||
ap_descr[i].event_state = EVENT_STATE_NORMAL;
|
||||
ap_descr[i].reliability = RELIABILITY_NO_FAULT_DETECTED;
|
||||
ap_descr[i].out_of_service = false;
|
||||
ap_descr[i].authentication_status =
|
||||
AUTHENTICATION_STATUS_NOT_READY;
|
||||
ap_descr[i].active_authentication_policy = 0;
|
||||
ap_descr[i].number_of_authentication_policies = 0;
|
||||
ap_descr[i].authorization_mode = AUTHORIZATION_MODE_AUTHORIZE;
|
||||
ap_descr[i].access_event = ACCESS_EVENT_NONE;
|
||||
/* timestamp uninitialized */
|
||||
/* access_event_credential should be set to some meaningful
|
||||
* value */
|
||||
ap_descr[i].num_doors = 0;
|
||||
/* fill in the access doors with proper ids */
|
||||
ap_descr[i].priority_for_writing =
|
||||
16; /* lowest possible for now */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,12 +17,19 @@
|
||||
#include "bacnet/proplist.h"
|
||||
#include "bacnet/wp.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
/* BACnet Stack Objects */
|
||||
#include "bacnet/basic/object/device.h"
|
||||
/* me! */
|
||||
#include "access_rights.h"
|
||||
|
||||
static bool Access_Rights_Initialized = false;
|
||||
|
||||
static ACCESS_RIGHTS_DESCR ar_descr[MAX_ACCESS_RIGHTS];
|
||||
static ACCESS_RIGHTS_DESCR ar_descrs[MAX_NUM_DEVICES][MAX_ACCESS_RIGHTS];
|
||||
#ifdef BAC_ROUTING
|
||||
#define ar_descr (ar_descrs[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define ar_descr (ar_descrs[0])
|
||||
#endif
|
||||
|
||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||
static const int32_t Properties_Required[] = {
|
||||
@@ -90,21 +97,35 @@ void Access_Rights_Writable_Property_List(
|
||||
void Access_Rights_Init(void)
|
||||
{
|
||||
unsigned i;
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
if (!Access_Rights_Initialized) {
|
||||
Access_Rights_Initialized = true;
|
||||
|
||||
for (i = 0; i < MAX_ACCESS_RIGHTS; i++) {
|
||||
ar_descr[i].global_identifier =
|
||||
0; /* set to some meaningful value */
|
||||
ar_descr[i].reliability = RELIABILITY_NO_FAULT_DETECTED;
|
||||
ar_descr[i].enable = false;
|
||||
ar_descr[i].negative_access_rules_count = 0;
|
||||
ar_descr[i].positive_access_rules_count = 0;
|
||||
/* fill in the positive and negative access rules with proper ids */
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
for (i = 0; i < MAX_ACCESS_RIGHTS; i++) {
|
||||
ar_descr[i].global_identifier =
|
||||
0; /* set to some meaningful value */
|
||||
ar_descr[i].reliability = RELIABILITY_NO_FAULT_DETECTED;
|
||||
ar_descr[i].enable = false;
|
||||
ar_descr[i].negative_access_rules_count = 0;
|
||||
ar_descr[i].positive_access_rules_count = 0;
|
||||
/* fill in the positive and negative access rules with proper
|
||||
* ids */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,10 +17,17 @@
|
||||
#include "bacnet/wp.h"
|
||||
#include "access_user.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
/* BACnet Stack Objects */
|
||||
#include "bacnet/basic/object/device.h"
|
||||
|
||||
static bool Access_User_Initialized = false;
|
||||
|
||||
static ACCESS_USER_DESCR au_descr[MAX_ACCESS_USERS];
|
||||
static ACCESS_USER_DESCR au_descrs[MAX_NUM_DEVICES][MAX_ACCESS_USERS];
|
||||
#ifdef BAC_ROUTING
|
||||
#define au_descr (au_descrs[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define au_descr (au_descrs[0])
|
||||
#endif
|
||||
|
||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||
static const int32_t Properties_Required[] = {
|
||||
@@ -79,20 +86,33 @@ void Access_User_Writable_Property_List(
|
||||
void Access_User_Init(void)
|
||||
{
|
||||
unsigned i;
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
if (!Access_User_Initialized) {
|
||||
Access_User_Initialized = true;
|
||||
|
||||
for (i = 0; i < MAX_ACCESS_USERS; i++) {
|
||||
au_descr[i].global_identifier =
|
||||
0; /* set to some meaningful value */
|
||||
au_descr[i].reliability = RELIABILITY_NO_FAULT_DETECTED;
|
||||
au_descr[i].user_type = ACCESS_USER_TYPE_PERSON;
|
||||
au_descr[i].credentials_count = 0;
|
||||
/* fill in the credentials with proper ids */
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
for (i = 0; i < MAX_ACCESS_USERS; i++) {
|
||||
au_descr[i].global_identifier =
|
||||
0; /* set to some meaningful value */
|
||||
au_descr[i].reliability = RELIABILITY_NO_FAULT_DETECTED;
|
||||
au_descr[i].user_type = ACCESS_USER_TYPE_PERSON;
|
||||
au_descr[i].credentials_count = 0;
|
||||
/* fill in the credentials with proper ids */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,12 +15,19 @@
|
||||
#include "bacnet/bacapp.h"
|
||||
#include "bacnet/wp.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
/* BACnet Stack Objects */
|
||||
#include "bacnet/basic/object/device.h"
|
||||
/* me! */
|
||||
#include "access_zone.h"
|
||||
|
||||
static bool Access_Zone_Initialized = false;
|
||||
|
||||
static ACCESS_ZONE_DESCR az_descr[MAX_ACCESS_ZONES];
|
||||
static ACCESS_ZONE_DESCR az_descrs[MAX_NUM_DEVICES][MAX_ACCESS_ZONES];
|
||||
#ifdef BAC_ROUTING
|
||||
#define az_descr (az_descrs[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define az_descr (az_descrs[0])
|
||||
#endif
|
||||
|
||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||
static const int32_t Properties_Required[] = {
|
||||
@@ -81,23 +88,37 @@ void Access_Zone_Writable_Property_List(
|
||||
void Access_Zone_Init(void)
|
||||
{
|
||||
unsigned i;
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
if (!Access_Zone_Initialized) {
|
||||
Access_Zone_Initialized = true;
|
||||
|
||||
for (i = 0; i < MAX_ACCESS_ZONES; i++) {
|
||||
az_descr[i].global_identifier =
|
||||
0; /* set to some meaningful value */
|
||||
az_descr[i].occupancy_state = ACCESS_ZONE_OCCUPANCY_STATE_DISABLED;
|
||||
az_descr[i].event_state = EVENT_STATE_NORMAL;
|
||||
az_descr[i].reliability = RELIABILITY_NO_FAULT_DETECTED;
|
||||
az_descr[i].out_of_service = false;
|
||||
az_descr[i].entry_points_count = 0;
|
||||
az_descr[i].exit_points_count = 0;
|
||||
/* fill in the entry points and exit points with proper ids */
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
for (i = 0; i < MAX_ACCESS_ZONES; i++) {
|
||||
az_descr[i].global_identifier =
|
||||
0; /* set to some meaningful value */
|
||||
az_descr[i].occupancy_state =
|
||||
ACCESS_ZONE_OCCUPANCY_STATE_DISABLED;
|
||||
az_descr[i].event_state = EVENT_STATE_NORMAL;
|
||||
az_descr[i].reliability = RELIABILITY_NO_FAULT_DETECTED;
|
||||
az_descr[i].out_of_service = false;
|
||||
az_descr[i].entry_points_count = 0;
|
||||
az_descr[i].exit_points_count = 0;
|
||||
/* fill in the entry points and exit points with proper ids */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,11 +22,18 @@
|
||||
#include "bacnet/basic/services.h"
|
||||
#include "bacnet/basic/sys/keylist.h"
|
||||
#include "bacnet/basic/sys/debug.h"
|
||||
/* BACnet Stack Objects */
|
||||
#include "bacnet/basic/object/device.h"
|
||||
/* me! */
|
||||
#include "bacnet/basic/object/ai.h"
|
||||
|
||||
/* Key List for storing the object data sorted by instance number */
|
||||
static OS_Keylist Object_List;
|
||||
static OS_Keylist Object_Lists[MAX_NUM_DEVICES];
|
||||
#ifdef BAC_ROUTING
|
||||
#define Object_List (Object_Lists[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define Object_List (Object_Lists[0])
|
||||
#endif
|
||||
/* common object type */
|
||||
static const BACNET_OBJECT_TYPE Object_Type = OBJECT_ANALOG_INPUT;
|
||||
|
||||
@@ -2138,17 +2145,30 @@ bool Analog_Input_Delete(uint32_t object_instance)
|
||||
void Analog_Input_Cleanup(void)
|
||||
{
|
||||
struct analog_input_descr *pObject;
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2156,9 +2176,23 @@ void Analog_Input_Cleanup(void)
|
||||
*/
|
||||
void Analog_Input_Init(void)
|
||||
{
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
#if defined(INTRINSIC_REPORTING)
|
||||
/* Set handler for GetEventInformation function */
|
||||
handler_get_event_information_set(
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
#include "bacnet/wp.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
#include "bacnet/basic/sys/keylist.h"
|
||||
/* BACnet Stack Objects */
|
||||
#include "bacnet/basic/object/device.h"
|
||||
/* me! */
|
||||
#include "ao.h"
|
||||
|
||||
@@ -49,7 +51,12 @@ struct object_data {
|
||||
void *Context;
|
||||
};
|
||||
/* Key List for storing the object data sorted by instance number */
|
||||
static OS_Keylist Object_List;
|
||||
static OS_Keylist Object_Lists[MAX_NUM_DEVICES];
|
||||
#ifdef BAC_ROUTING
|
||||
#define Object_List (Object_Lists[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define Object_List (Object_Lists[0])
|
||||
#endif
|
||||
/* common object type */
|
||||
static const BACNET_OBJECT_TYPE Object_Type = OBJECT_ANALOG_OUTPUT;
|
||||
/* callback for present value writes */
|
||||
@@ -1399,17 +1406,30 @@ bool Analog_Output_Delete(uint32_t object_instance)
|
||||
void Analog_Output_Cleanup(void)
|
||||
{
|
||||
struct object_data *pObject;
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1417,7 +1437,21 @@ void Analog_Output_Cleanup(void)
|
||||
*/
|
||||
void Analog_Output_Init(void)
|
||||
{
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -88,6 +88,8 @@
|
||||
#include "bacnet/wp.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
#include "bacnet/basic/sys/keylist.h"
|
||||
/* BACnet Stack Objects */
|
||||
#include "bacnet/basic/object/device.h"
|
||||
/* me! */
|
||||
#include "auditlog.h"
|
||||
|
||||
@@ -106,7 +108,12 @@ struct object_data {
|
||||
void *Context;
|
||||
};
|
||||
/* Key List for storing the object data sorted by instance number */
|
||||
static OS_Keylist Object_List;
|
||||
static OS_Keylist Object_Lists[MAX_NUM_DEVICES];
|
||||
#ifdef BAC_ROUTING
|
||||
#define Object_List (Object_Lists[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define Object_List (Object_Lists[0])
|
||||
#endif
|
||||
|
||||
static const int32_t Properties_Required[] = {
|
||||
/* required properties that are supported for this object */
|
||||
@@ -1519,18 +1526,31 @@ bool Audit_Log_Delete(uint32_t object_instance)
|
||||
void Audit_Log_Cleanup(void)
|
||||
{
|
||||
struct object_data *pObject;
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
Audit_Log_Records_Cleanup(pObject->Records);
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
Audit_Log_Records_Cleanup(pObject->Records);
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1538,7 +1558,21 @@ void Audit_Log_Cleanup(void)
|
||||
*/
|
||||
void Audit_Log_Init(void)
|
||||
{
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -25,11 +25,18 @@
|
||||
#include "bacnet/basic/services.h"
|
||||
#include "bacnet/basic/sys/keylist.h"
|
||||
#include "bacnet/basic/sys/debug.h"
|
||||
/* BACnet Stack Objects */
|
||||
#include "bacnet/basic/object/device.h"
|
||||
/* me! */
|
||||
#include "bacnet/basic/object/av.h"
|
||||
|
||||
/* Key List for storing the object data sorted by instance number */
|
||||
static OS_Keylist Object_List;
|
||||
static OS_Keylist Object_Lists[MAX_NUM_DEVICES];
|
||||
#ifdef BAC_ROUTING
|
||||
#define Object_List (Object_Lists[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define Object_List (Object_Lists[0])
|
||||
#endif
|
||||
/* common object type */
|
||||
static const BACNET_OBJECT_TYPE Object_Type = OBJECT_ANALOG_VALUE;
|
||||
/* callback for present value writes */
|
||||
@@ -1897,17 +1904,30 @@ bool Analog_Value_Delete(uint32_t object_instance)
|
||||
void Analog_Value_Cleanup(void)
|
||||
{
|
||||
struct analog_value_descr *pObject;
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1915,9 +1935,23 @@ void Analog_Value_Cleanup(void)
|
||||
*/
|
||||
void Analog_Value_Init(void)
|
||||
{
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
#if defined(INTRINSIC_REPORTING)
|
||||
/* Set handler for GetEventInformation function */
|
||||
handler_get_event_information_set(
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
#include "bacnet/basic/services.h"
|
||||
#include "bacnet/basic/sys/keylist.h"
|
||||
#include "bacnet/basic/tsm/tsm.h"
|
||||
/* BACnet Stack Objects */
|
||||
#include "bacnet/basic/object/device.h"
|
||||
|
||||
struct object_data {
|
||||
char *Object_Name;
|
||||
@@ -40,7 +42,12 @@ struct object_data {
|
||||
bool Archive : 1;
|
||||
};
|
||||
/* Key List for storing the object data sorted by instance number */
|
||||
static OS_Keylist Object_List;
|
||||
static OS_Keylist Object_Lists[MAX_NUM_DEVICES];
|
||||
#ifdef BAC_ROUTING
|
||||
#define Object_List (Object_Lists[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define Object_List (Object_Lists[0])
|
||||
#endif
|
||||
/* common object type */
|
||||
static const BACNET_OBJECT_TYPE Object_Type = OBJECT_FILE;
|
||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||
@@ -1315,20 +1322,33 @@ bool bacfile_delete(uint32_t object_instance)
|
||||
void bacfile_cleanup(void)
|
||||
{
|
||||
struct object_data *pObject;
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject->Pathname);
|
||||
free(pObject->File_Type);
|
||||
free(pObject->Object_Name);
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject->Pathname);
|
||||
free(pObject->File_Type);
|
||||
free(pObject->Object_Name);
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1336,7 +1356,21 @@ void bacfile_cleanup(void)
|
||||
*/
|
||||
void bacfile_init(void)
|
||||
{
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include "bacnet/basic/services.h"
|
||||
#include "bacnet/basic/sys/keylist.h"
|
||||
#include "bacnet/basic/sys/debug.h"
|
||||
/* BACnet Stack Objects */
|
||||
#include "bacnet/basic/object/device.h"
|
||||
/* me! */
|
||||
#include "bacnet/basic/object/bi.h"
|
||||
|
||||
@@ -61,7 +63,12 @@ struct object_data {
|
||||
#endif
|
||||
};
|
||||
/* Key List for storing the object data sorted by instance number */
|
||||
static OS_Keylist Object_List;
|
||||
static OS_Keylist Object_Lists[MAX_NUM_DEVICES];
|
||||
#ifdef BAC_ROUTING
|
||||
#define Object_List (Object_Lists[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define Object_List (Object_Lists[0])
|
||||
#endif
|
||||
/* common object type */
|
||||
static const BACNET_OBJECT_TYPE Object_Type = OBJECT_BINARY_INPUT;
|
||||
/* callback for present value writes */
|
||||
@@ -1424,17 +1431,30 @@ uint32_t Binary_Input_Create(uint32_t object_instance)
|
||||
void Binary_Input_Cleanup(void)
|
||||
{
|
||||
struct object_data *pObject;
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1461,9 +1481,23 @@ bool Binary_Input_Delete(uint32_t object_instance)
|
||||
*/
|
||||
void Binary_Input_Init(void)
|
||||
{
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
#include "bacnet/wp.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
#include "bacnet/basic/sys/keylist.h"
|
||||
/* BACnet Stack Objects */
|
||||
#include "bacnet/basic/object/device.h"
|
||||
/* me! */
|
||||
#include "bitstring_value.h"
|
||||
|
||||
@@ -36,7 +38,12 @@ struct object_data {
|
||||
void *Context;
|
||||
};
|
||||
/* Key List for storing the object data sorted by instance number */
|
||||
static OS_Keylist Object_List;
|
||||
static OS_Keylist Object_Lists[MAX_NUM_DEVICES];
|
||||
#ifdef BAC_ROUTING
|
||||
#define Object_List (Object_Lists[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define Object_List (Object_Lists[0])
|
||||
#endif
|
||||
/* callback for present value writes */
|
||||
static bitstring_value_write_present_value_callback
|
||||
BitString_Value_Write_Present_Value_Callback;
|
||||
@@ -920,17 +927,30 @@ bool BitString_Value_Delete(uint32_t object_instance)
|
||||
void BitString_Value_Cleanup(void)
|
||||
{
|
||||
struct object_data *pObject;
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -938,7 +958,21 @@ void BitString_Value_Cleanup(void)
|
||||
*/
|
||||
void BitString_Value_Init(void)
|
||||
{
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#include "bacnet/basic/services.h"
|
||||
#include "bacnet/basic/sys/keylist.h"
|
||||
#include "bacnet/proplist.h"
|
||||
/* BACnet Stack Objects */
|
||||
#include "bacnet/basic/object/device.h"
|
||||
/* me! */
|
||||
#include "bacnet/basic/object/blo.h"
|
||||
|
||||
@@ -51,7 +53,12 @@ struct object_data {
|
||||
bool Polarity : 1;
|
||||
};
|
||||
/* Key List for storing the object data sorted by instance number */
|
||||
static OS_Keylist Object_List;
|
||||
static OS_Keylist Object_Lists[MAX_NUM_DEVICES];
|
||||
#ifdef BAC_ROUTING
|
||||
#define Object_List (Object_Lists[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define Object_List (Object_Lists[0])
|
||||
#endif
|
||||
/* callback for present value writes */
|
||||
static binary_lighting_output_write_value_callback
|
||||
Binary_Lighting_Output_Write_Value_Callback;
|
||||
@@ -1656,17 +1663,30 @@ bool Binary_Lighting_Output_Delete(uint32_t object_instance)
|
||||
void Binary_Lighting_Output_Cleanup(void)
|
||||
{
|
||||
struct object_data *pObject;
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1674,7 +1694,21 @@ void Binary_Lighting_Output_Cleanup(void)
|
||||
*/
|
||||
void Binary_Lighting_Output_Init(void)
|
||||
{
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
#include "bacnet/wp.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
#include "bacnet/basic/sys/keylist.h"
|
||||
/* BACnet Stack Objects */
|
||||
#include "bacnet/basic/object/device.h"
|
||||
/* me! */
|
||||
#include "bo.h"
|
||||
|
||||
@@ -49,7 +51,12 @@ struct object_data {
|
||||
void *Context;
|
||||
};
|
||||
/* Key List for storing the object data sorted by instance number */
|
||||
static OS_Keylist Object_List;
|
||||
static OS_Keylist Object_Lists[MAX_NUM_DEVICES];
|
||||
#ifdef BAC_ROUTING
|
||||
#define Object_List (Object_Lists[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define Object_List (Object_Lists[0])
|
||||
#endif
|
||||
/* common object type */
|
||||
static const BACNET_OBJECT_TYPE Object_Type = OBJECT_BINARY_OUTPUT;
|
||||
/* callback for present value writes */
|
||||
@@ -1354,17 +1361,30 @@ uint32_t Binary_Output_Create(uint32_t object_instance)
|
||||
void Binary_Output_Cleanup(void)
|
||||
{
|
||||
struct object_data *pObject;
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1389,7 +1409,21 @@ bool Binary_Output_Delete(uint32_t object_instance)
|
||||
*/
|
||||
void Binary_Output_Init(void)
|
||||
{
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -60,7 +60,12 @@ struct object_data {
|
||||
#endif
|
||||
};
|
||||
/* Key List for storing the object data sorted by instance number */
|
||||
static OS_Keylist Object_List;
|
||||
static OS_Keylist Object_Lists[MAX_NUM_DEVICES];
|
||||
#ifdef BAC_ROUTING
|
||||
#define Object_List (Object_Lists[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define Object_List (Object_Lists[0])
|
||||
#endif
|
||||
/* common object type */
|
||||
static const BACNET_OBJECT_TYPE Object_Type = OBJECT_BINARY_VALUE;
|
||||
/* callback for present value writes */
|
||||
@@ -1328,17 +1333,30 @@ uint32_t Binary_Value_Create(uint32_t object_instance)
|
||||
void Binary_Value_Cleanup(void)
|
||||
{
|
||||
struct object_data *pObject;
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1363,9 +1381,23 @@ bool Binary_Value_Delete(uint32_t object_instance)
|
||||
*/
|
||||
void Binary_Value_Init(void)
|
||||
{
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
#include "bacnet/wp.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
#include "bacnet/basic/sys/keylist.h"
|
||||
/* BACnet Stack Objects */
|
||||
#include "bacnet/basic/object/device.h"
|
||||
/* me! */
|
||||
#include "calendar.h"
|
||||
|
||||
@@ -43,7 +45,12 @@ struct object_data {
|
||||
void *Context;
|
||||
};
|
||||
/* Key List for storing the object data sorted by instance number */
|
||||
static OS_Keylist Object_List;
|
||||
static OS_Keylist Object_Lists[MAX_NUM_DEVICES];
|
||||
#ifdef BAC_ROUTING
|
||||
#define Object_List (Object_Lists[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define Object_List (Object_Lists[0])
|
||||
#endif
|
||||
/* callback for present value writes */
|
||||
static calendar_write_present_value_callback
|
||||
Calendar_Write_Present_Value_Callback;
|
||||
@@ -802,19 +809,32 @@ bool Calendar_Delete(uint32_t object_instance)
|
||||
void Calendar_Cleanup(void)
|
||||
{
|
||||
struct object_data *pObject;
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
Calendar_Date_List_Clean(pObject->Date_List);
|
||||
Keylist_Delete(pObject->Date_List);
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
Calendar_Date_List_Clean(pObject->Date_List);
|
||||
Keylist_Delete(pObject->Date_List);
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -822,7 +842,21 @@ void Calendar_Cleanup(void)
|
||||
*/
|
||||
void Calendar_Init(void)
|
||||
{
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
#if defined(CHANNEL_LIGHTING_COMMAND) || defined(CHANNEL_COLOR_COMMAND)
|
||||
#include "bacnet/lighting.h"
|
||||
#endif
|
||||
/* BACnet Stack Objects */
|
||||
#include "bacnet/basic/object/device.h"
|
||||
/* me! */
|
||||
#include "bacnet/basic/object/channel.h"
|
||||
|
||||
@@ -51,7 +53,12 @@ struct object_data {
|
||||
};
|
||||
|
||||
/* Key List for storing the object data sorted by instance number */
|
||||
static OS_Keylist Object_List;
|
||||
static OS_Keylist Object_Lists[MAX_NUM_DEVICES];
|
||||
#ifdef BAC_ROUTING
|
||||
#define Object_List (Object_Lists[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define Object_List (Object_Lists[0])
|
||||
#endif
|
||||
/* Internal write property callback */
|
||||
static write_property_function Write_Property_Internal_Callback;
|
||||
/* Write Property notification callbacks for logging or other purposes */
|
||||
@@ -1567,17 +1574,30 @@ bool Channel_Delete(uint32_t object_instance)
|
||||
void Channel_Cleanup(void)
|
||||
{
|
||||
struct object_data *pObject;
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1585,7 +1605,21 @@ void Channel_Cleanup(void)
|
||||
*/
|
||||
void Channel_Init(void)
|
||||
{
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -58,7 +58,12 @@ struct object_data {
|
||||
void *Context;
|
||||
};
|
||||
/* Key List for storing the object data sorted by instance number */
|
||||
static OS_Keylist Object_List;
|
||||
static OS_Keylist Object_Lists[MAX_NUM_DEVICES];
|
||||
#ifdef BAC_ROUTING
|
||||
#define Object_List (Object_Lists[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define Object_List (Object_Lists[0])
|
||||
#endif
|
||||
/* callback for present value writes */
|
||||
static color_write_present_value_callback Color_Write_Present_Value_Callback;
|
||||
|
||||
@@ -1275,17 +1280,30 @@ bool Color_Delete(uint32_t object_instance)
|
||||
void Color_Cleanup(void)
|
||||
{
|
||||
struct object_data *pObject;
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1293,7 +1311,21 @@ void Color_Cleanup(void)
|
||||
*/
|
||||
void Color_Init(void)
|
||||
{
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
#include "bacnet/basic/services.h"
|
||||
#include "bacnet/basic/sys/keylist.h"
|
||||
#include "bacnet/basic/sys/linear.h"
|
||||
/* BACnet Stack Objects */
|
||||
#include "bacnet/basic/object/device.h"
|
||||
/* me! */
|
||||
#include "color_temperature.h"
|
||||
|
||||
@@ -51,7 +53,12 @@ struct object_data {
|
||||
void *Context;
|
||||
};
|
||||
/* Key List for storing the object data sorted by instance number */
|
||||
static OS_Keylist Object_List;
|
||||
static OS_Keylist Object_Lists[MAX_NUM_DEVICES];
|
||||
#ifdef BAC_ROUTING
|
||||
#define Object_List (Object_Lists[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define Object_List (Object_Lists[0])
|
||||
#endif
|
||||
/* callback for present value writes */
|
||||
static color_temperature_write_present_value_callback
|
||||
Color_Temperature_Write_Present_Value_Callback;
|
||||
@@ -1725,17 +1732,30 @@ bool Color_Temperature_Delete(uint32_t object_instance)
|
||||
void Color_Temperature_Cleanup(void)
|
||||
{
|
||||
struct object_data *pObject;
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1743,7 +1763,21 @@ void Color_Temperature_Cleanup(void)
|
||||
*/
|
||||
void Color_Temperature_Init(void)
|
||||
{
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -28,10 +28,17 @@
|
||||
#include "bacnet/proplist.h"
|
||||
#include "bacnet/timestamp.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
/* BACnet Stack Objects */
|
||||
#include "bacnet/basic/object/device.h"
|
||||
/* me!*/
|
||||
#include "bacnet/basic/object/command.h"
|
||||
|
||||
static COMMAND_DESCR Command_Descr[MAX_COMMANDS];
|
||||
static COMMAND_DESCR Command_Descrs[MAX_NUM_DEVICES][MAX_COMMANDS];
|
||||
#ifdef BAC_ROUTING
|
||||
#define Command_Descr (Command_Descrs[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define Command_Descr (Command_Descrs[0])
|
||||
#endif
|
||||
|
||||
/* These arrays are used by the ReadPropertyMultiple handler */
|
||||
static const int32_t Command_Properties_Required[] = {
|
||||
@@ -107,12 +114,27 @@ void Command_Writable_Property_List(
|
||||
*/
|
||||
void Command_Init(void)
|
||||
{
|
||||
uint16_t dev_id;
|
||||
unsigned i;
|
||||
for (i = 0; i < MAX_COMMANDS; i++) {
|
||||
Command_Descr[i].Present_Value = 0;
|
||||
Command_Descr[i].In_Process = false;
|
||||
Command_Descr[i].All_Writes_Successful = true; /* Optimistic default */
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
for (i = 0; i < MAX_COMMANDS; i++) {
|
||||
Command_Descr[i].Present_Value = 0;
|
||||
Command_Descr[i].In_Process = false;
|
||||
Command_Descr[i].All_Writes_Successful =
|
||||
true; /* Optimistic default */
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,12 +16,20 @@
|
||||
#include "bacnet/bacapp.h"
|
||||
#include "bacnet/wp.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
/* BACnet Stack Objects */
|
||||
#include "bacnet/basic/object/device.h"
|
||||
/* me! */
|
||||
#include "bacnet/basic/object/credential_data_input.h"
|
||||
|
||||
static bool Credential_Data_Input_Initialized = false;
|
||||
|
||||
static CREDENTIAL_DATA_INPUT_DESCR cdi_descr[MAX_CREDENTIAL_DATA_INPUTS];
|
||||
static CREDENTIAL_DATA_INPUT_DESCR cdi_descrs[MAX_NUM_DEVICES]
|
||||
[MAX_CREDENTIAL_DATA_INPUTS];
|
||||
#ifdef BAC_ROUTING
|
||||
#define cdi_descr (cdi_descrs[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define cdi_descr (cdi_descrs[0])
|
||||
#endif
|
||||
|
||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||
static const int32_t Properties_Required[] = {
|
||||
@@ -93,25 +101,37 @@ void Credential_Data_Input_Writable_Property_List(
|
||||
*/
|
||||
void Credential_Data_Input_Init(void)
|
||||
{
|
||||
uint16_t dev_id;
|
||||
unsigned i;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
if (!Credential_Data_Input_Initialized) {
|
||||
Credential_Data_Input_Initialized = true;
|
||||
|
||||
for (i = 0; i < MAX_CREDENTIAL_DATA_INPUTS; i++) {
|
||||
/* there should be a meaningful setup for present value */
|
||||
cdi_descr[i].present_value.format_type =
|
||||
AUTHENTICATION_FACTOR_UNDEFINED;
|
||||
cdi_descr[i].present_value.format_class = 0;
|
||||
octetstring_init(&cdi_descr[i].present_value.value, NULL, 0);
|
||||
cdi_descr[i].reliability = RELIABILITY_NO_FAULT_DETECTED;
|
||||
cdi_descr[i].out_of_service = false;
|
||||
/* set supported formats */
|
||||
cdi_descr[i].supported_formats_count = 0;
|
||||
/* timestamp uninitialized */
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
for (i = 0; i < MAX_CREDENTIAL_DATA_INPUTS; i++) {
|
||||
/* there should be a meaningful setup for present value */
|
||||
cdi_descr[i].present_value.format_type =
|
||||
AUTHENTICATION_FACTOR_UNDEFINED;
|
||||
cdi_descr[i].present_value.format_class = 0;
|
||||
octetstring_init(&cdi_descr[i].present_value.value, NULL, 0);
|
||||
cdi_descr[i].reliability = RELIABILITY_NO_FAULT_DETECTED;
|
||||
cdi_descr[i].out_of_service = false;
|
||||
/* set supported formats */
|
||||
cdi_descr[i].supported_formats_count = 0;
|
||||
/* timestamp uninitialized */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,9 +21,16 @@
|
||||
#include "bacnet/basic/object/csv.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
#include "bacnet/basic/sys/keylist.h"
|
||||
/* BACnet Stack Objects */
|
||||
#include "bacnet/basic/object/device.h"
|
||||
|
||||
/* Key List for storing the object data sorted by instance number */
|
||||
static OS_Keylist Object_List = NULL;
|
||||
static OS_Keylist Object_Lists[MAX_NUM_DEVICES];
|
||||
#ifdef BAC_ROUTING
|
||||
#define Object_List (Object_Lists[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define Object_List (Object_Lists[0])
|
||||
#endif
|
||||
/* common object type */
|
||||
static const BACNET_OBJECT_TYPE Object_Type = OBJECT_CHARACTERSTRING_VALUE;
|
||||
|
||||
@@ -207,18 +214,31 @@ bool CharacterString_Value_Delete(uint32_t object_instance)
|
||||
*/
|
||||
void CharacterString_Value_Cleanup(void)
|
||||
{
|
||||
struct object_data *pObject = NULL;
|
||||
struct object_data *pObject;
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -237,9 +257,23 @@ CharacterString_Value_Object(uint32_t object_instance)
|
||||
*/
|
||||
void CharacterString_Value_Init(void)
|
||||
{
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3942,12 +3942,31 @@ void Device_local_reporting(void)
|
||||
BACNET_OBJECT_TYPE object_type = OBJECT_NONE;
|
||||
uint32_t idx = 0;
|
||||
|
||||
/* loop for all objects */
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t dev_id = 0;
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
for (dev_id = 0; dev_id < Get_Num_Managed_Devices(); dev_id++) {
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
objects_count = Device_Object_List_Count();
|
||||
for (idx = 1; idx <= objects_count; idx++) {
|
||||
Device_Object_List_Identifier(idx, &object_type, &object_instance);
|
||||
pObject = Device_Object_Functions_Find(object_type);
|
||||
if (pObject != NULL) {
|
||||
if (pObject->Object_Valid_Instance &&
|
||||
pObject->Object_Valid_Instance(object_instance)) {
|
||||
if (pObject->Object_Intrinsic_Reporting) {
|
||||
pObject->Object_Intrinsic_Reporting(object_instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#else
|
||||
objects_count = Device_Object_List_Count();
|
||||
|
||||
/* loop for all objects */
|
||||
for (idx = 1; idx <= objects_count; idx++) {
|
||||
Device_Object_List_Identifier(idx, &object_type, &object_instance);
|
||||
|
||||
pObject = Device_Object_Functions_Find(object_type);
|
||||
if (pObject != NULL) {
|
||||
if (pObject->Object_Valid_Instance &&
|
||||
@@ -3958,6 +3977,7 @@ void Device_local_reporting(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -4090,6 +4110,45 @@ void Device_Timer(uint16_t milliseconds)
|
||||
unsigned count = 0;
|
||||
uint32_t instance;
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t dev_id = 0;
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
/* TODO: Multi-device Backup/Restore support
|
||||
* Currently only Gateway (dev_id=0) supports Backup/Restore.
|
||||
* Virtual devices are blocked by Routed_Device_Service_Approval().
|
||||
* Plan to support after discussing with maintainer.
|
||||
*
|
||||
* To enable per-device Backup/Restore:
|
||||
* 1. Move Backup-related static variables to DEVICE_OBJECT_DATA:
|
||||
* - Backup_State, Backup_Failure_Timeout_Milliseconds
|
||||
* - Backup_Failure_Timeout, Configuration_Files[]
|
||||
* - Last_Restore_Time, Backup/Restore_Preparation_Time
|
||||
* 2. Modify Routed_Device_Service_Approval() to allow RD on virtual devices
|
||||
* 3. Call Device_Backup_Failure_Timeout_Countdown() inside the for loop
|
||||
* for each device
|
||||
*/
|
||||
Device_Backup_Failure_Timeout_Countdown(milliseconds);
|
||||
for (dev_id = 0; dev_id < Get_Num_Managed_Devices(); dev_id++) {
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
pObject = Object_Table;
|
||||
while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) {
|
||||
count = 0;
|
||||
if (pObject->Object_Count) {
|
||||
count = pObject->Object_Count();
|
||||
}
|
||||
while (count) {
|
||||
count--;
|
||||
if ((pObject->Object_Timer) &&
|
||||
(pObject->Object_Index_To_Instance)) {
|
||||
instance = pObject->Object_Index_To_Instance(count);
|
||||
pObject->Object_Timer(instance, milliseconds);
|
||||
}
|
||||
}
|
||||
pObject++;
|
||||
}
|
||||
}
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#else
|
||||
Device_Backup_Failure_Timeout_Countdown(milliseconds);
|
||||
pObject = Object_Table;
|
||||
while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) {
|
||||
@@ -4107,6 +4166,7 @@ void Device_Timer(uint16_t milliseconds)
|
||||
}
|
||||
pObject++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
|
||||
@@ -536,6 +536,13 @@ int Routed_Device_Service_Approval(
|
||||
uint8_t *apdu_buff,
|
||||
uint8_t invoke_id);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
uint16_t Routed_Device_Object_Index(void);
|
||||
BACNET_STACK_EXPORT
|
||||
bool Set_Routed_Device_Object_Index(uint16_t idx);
|
||||
BACNET_STACK_EXPORT
|
||||
uint16_t Get_Num_Managed_Devices(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include "bacnet/basic/object/bacfile.h"
|
||||
/* os specific includes */
|
||||
#include "bacnet/basic/sys/mstimer.h"
|
||||
#include "bacnet/basic/sys/debug.h"
|
||||
|
||||
/* forward prototypes */
|
||||
int Routed_Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata);
|
||||
@@ -74,6 +75,43 @@ uint16_t Num_Managed_Devices = 0;
|
||||
*/
|
||||
uint16_t iCurrent_Device_Idx = 0;
|
||||
|
||||
/** Get the current routed device object index.
|
||||
* @return Index of the currently active routed device in Devices[] array
|
||||
*/
|
||||
uint16_t Routed_Device_Object_Index(void)
|
||||
{
|
||||
return iCurrent_Device_Idx;
|
||||
}
|
||||
|
||||
/** Get the number of managed devices.
|
||||
* @return Number of devices currently managed (including gateway)
|
||||
*/
|
||||
uint16_t Get_Num_Managed_Devices(void)
|
||||
{
|
||||
return Num_Managed_Devices;
|
||||
}
|
||||
|
||||
/** Set the current routed device object index.
|
||||
* @param idx [in] Index of the routed device to set as current
|
||||
* @return true if index is valid and set, false if index exceeds
|
||||
* MAX_NUM_DEVICES
|
||||
*/
|
||||
bool Set_Routed_Device_Object_Index(uint16_t idx)
|
||||
{
|
||||
if (idx >= MAX_NUM_DEVICES) {
|
||||
debug_fprintf(
|
||||
stderr,
|
||||
"Set_Routed_Device_Object_Index: idx(%u) >= MAX_NUM_DEVICES(%u)\n",
|
||||
(unsigned)idx, (unsigned)MAX_NUM_DEVICES);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
iCurrent_Device_Idx = idx;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* void Routing_Device_Init(uint32_t first_object_instance) is
|
||||
* found in device.c
|
||||
*/
|
||||
|
||||
@@ -29,7 +29,12 @@
|
||||
#include "bacnet/basic/object/iv.h"
|
||||
|
||||
/* Key List for storing the object data sorted by instance number */
|
||||
static OS_Keylist Object_List = NULL;
|
||||
static OS_Keylist Object_Lists[MAX_NUM_DEVICES];
|
||||
#ifdef BAC_ROUTING
|
||||
#define Object_List (Object_Lists[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define Object_List (Object_Lists[0])
|
||||
#endif
|
||||
/* common object type */
|
||||
static const BACNET_OBJECT_TYPE Object_Type = OBJECT_INTEGER_VALUE;
|
||||
/* callback for present value writes */
|
||||
@@ -855,19 +860,31 @@ bool Integer_Value_Delete(uint32_t object_instance)
|
||||
*/
|
||||
void Integer_Value_Cleanup(void)
|
||||
{
|
||||
if (Object_List) {
|
||||
struct integer_object *pObject;
|
||||
struct integer_object *pObject;
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -875,7 +892,21 @@ void Integer_Value_Cleanup(void)
|
||||
*/
|
||||
void Integer_Value_Init(void)
|
||||
{
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
#include "bacnet/basic/services.h"
|
||||
#include "bacnet/basic/sys/debug.h"
|
||||
#include "bacnet/basic/sys/keylist.h"
|
||||
/* BACnet Stack Objects */
|
||||
#include "bacnet/basic/object/device.h"
|
||||
|
||||
/* from Table 12-33. Requested_Shed_Level Default Values and Power Targets */
|
||||
#define DEFAULT_VALUE_PERCENT 100
|
||||
@@ -97,7 +99,12 @@ struct object_data {
|
||||
const char *Description;
|
||||
};
|
||||
/* Key List for storing the object data sorted by instance number */
|
||||
static OS_Keylist Object_List;
|
||||
static OS_Keylist Object_Lists[MAX_NUM_DEVICES];
|
||||
#ifdef BAC_ROUTING
|
||||
#define Object_List (Object_Lists[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define Object_List (Object_Lists[0])
|
||||
#endif
|
||||
|
||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||
static const int32_t Load_Control_Properties_Required[] = {
|
||||
@@ -2227,17 +2234,30 @@ bool Load_Control_Delete(uint32_t object_instance)
|
||||
void Load_Control_Cleanup(void)
|
||||
{
|
||||
struct object_data *pObject;
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2245,7 +2265,21 @@ void Load_Control_Cleanup(void)
|
||||
*/
|
||||
void Load_Control_Init(void)
|
||||
{
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
#include "bacnet/basic/sys/lighting_command.h"
|
||||
#include "bacnet/bactext.h"
|
||||
#include "bacnet/proplist.h"
|
||||
/* BACnet Stack Objects */
|
||||
#include "bacnet/basic/object/device.h"
|
||||
/* me! */
|
||||
#include "bacnet/basic/object/lo.h"
|
||||
|
||||
@@ -59,7 +61,12 @@ struct object_data {
|
||||
bool Color_Override : 1;
|
||||
};
|
||||
/* Key List for storing the object data sorted by instance number */
|
||||
static OS_Keylist Object_List;
|
||||
static OS_Keylist Object_Lists[MAX_NUM_DEVICES];
|
||||
#ifdef BAC_ROUTING
|
||||
#define Object_List (Object_Lists[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define Object_List (Object_Lists[0])
|
||||
#endif
|
||||
/* callback for present value writes */
|
||||
static lighting_command_tracking_value_callback
|
||||
Lighting_Command_Tracking_Value_Callback;
|
||||
@@ -3920,17 +3927,30 @@ bool Lighting_Output_Delete(uint32_t object_instance)
|
||||
void Lighting_Output_Cleanup(void)
|
||||
{
|
||||
struct object_data *pObject;
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3938,7 +3958,21 @@ void Lighting_Output_Cleanup(void)
|
||||
*/
|
||||
void Lighting_Output_Init(void)
|
||||
{
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -34,7 +34,12 @@
|
||||
#include "bacnet/basic/object/loop.h"
|
||||
|
||||
/* Key List for storing the object data sorted by instance number */
|
||||
static OS_Keylist Object_List = NULL;
|
||||
static OS_Keylist Object_Lists[MAX_NUM_DEVICES];
|
||||
#ifdef BAC_ROUTING
|
||||
#define Object_List (Object_Lists[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define Object_List (Object_Lists[0])
|
||||
#endif
|
||||
/* common object type */
|
||||
static const BACNET_OBJECT_TYPE Object_Type = OBJECT_LOOP;
|
||||
/* handling for manipulated and reference properties */
|
||||
@@ -2315,18 +2320,30 @@ bool Loop_Delete(uint32_t object_instance)
|
||||
void Loop_Cleanup(void)
|
||||
{
|
||||
struct object_data *pObject;
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2342,7 +2359,21 @@ size_t Loop_Size(void)
|
||||
*/
|
||||
void Loop_Init(void)
|
||||
{
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
#include "bacnet/bacapp.h"
|
||||
#include "bacnet/rp.h"
|
||||
#include "bacnet/wp.h"
|
||||
#include "bacnet/basic/object/lsp.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
#include "bacnet/basic/sys/keylist.h"
|
||||
#include "bacnet/proplist.h"
|
||||
/* BACnet Stack Objects */
|
||||
#include "bacnet/basic/object/device.h"
|
||||
/* me! */
|
||||
#include "bacnet/basic/object/lsp.h"
|
||||
|
||||
struct object_data {
|
||||
bool Out_Of_Service : 1;
|
||||
@@ -33,7 +36,12 @@ struct object_data {
|
||||
void *Context;
|
||||
};
|
||||
/* Key List for storing the object data sorted by instance number */
|
||||
static OS_Keylist Object_List;
|
||||
static OS_Keylist Object_Lists[MAX_NUM_DEVICES];
|
||||
#ifdef BAC_ROUTING
|
||||
#define Object_List (Object_Lists[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define Object_List (Object_Lists[0])
|
||||
#endif
|
||||
/* common object type */
|
||||
static const BACNET_OBJECT_TYPE Object_Type = OBJECT_LIFE_SAFETY_POINT;
|
||||
|
||||
@@ -799,17 +807,30 @@ bool Life_Safety_Point_Delete(uint32_t object_instance)
|
||||
void Life_Safety_Point_Cleanup(void)
|
||||
{
|
||||
struct object_data *pObject;
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -817,7 +838,21 @@ void Life_Safety_Point_Cleanup(void)
|
||||
*/
|
||||
void Life_Safety_Point_Init(void)
|
||||
{
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
#include "bacnet/basic/services.h"
|
||||
#include "bacnet/basic/sys/keylist.h"
|
||||
#include "bacnet/proplist.h"
|
||||
/* BACnet Stack Objects */
|
||||
#include "bacnet/basic/object/device.h"
|
||||
/* me! */
|
||||
#include "bacnet/basic/object/lsz.h"
|
||||
|
||||
@@ -43,7 +45,12 @@ struct object_data {
|
||||
void *Context;
|
||||
};
|
||||
/* Key List for storing the object data sorted by instance number */
|
||||
static OS_Keylist Object_List;
|
||||
static OS_Keylist Object_Lists[MAX_NUM_DEVICES];
|
||||
#ifdef BAC_ROUTING
|
||||
#define Object_List (Object_Lists[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define Object_List (Object_Lists[0])
|
||||
#endif
|
||||
/* common object type */
|
||||
static const BACNET_OBJECT_TYPE Object_Type = OBJECT_LIFE_SAFETY_ZONE;
|
||||
|
||||
@@ -985,17 +992,30 @@ bool Life_Safety_Zone_Delete(uint32_t object_instance)
|
||||
void Life_Safety_Zone_Cleanup(void)
|
||||
{
|
||||
struct object_data *pObject;
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1003,7 +1023,21 @@ void Life_Safety_Zone_Cleanup(void)
|
||||
*/
|
||||
void Life_Safety_Zone_Init(void)
|
||||
{
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#include "bacnet/wp.h"
|
||||
#include "bacnet/basic/sys/keylist.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
/* BACnet Stack Objects */
|
||||
#include "bacnet/basic/object/device.h"
|
||||
/* me! */
|
||||
#include "bacnet/basic/object/ms-input.h"
|
||||
|
||||
@@ -36,7 +38,12 @@ struct object_data {
|
||||
void *Context;
|
||||
};
|
||||
/* Key List for storing the object data sorted by instance number */
|
||||
static OS_Keylist Object_List;
|
||||
static OS_Keylist Object_Lists[MAX_NUM_DEVICES];
|
||||
#ifdef BAC_ROUTING
|
||||
#define Object_List (Object_Lists[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define Object_List (Object_Lists[0])
|
||||
#endif
|
||||
/* common object type */
|
||||
static const BACNET_OBJECT_TYPE Object_Type = OBJECT_MULTI_STATE_INPUT;
|
||||
/* callback for present value writes */
|
||||
@@ -1082,17 +1089,30 @@ bool Multistate_Input_Delete(uint32_t object_instance)
|
||||
void Multistate_Input_Cleanup(void)
|
||||
{
|
||||
struct object_data *pObject;
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1100,7 +1120,21 @@ void Multistate_Input_Cleanup(void)
|
||||
*/
|
||||
void Multistate_Input_Init(void)
|
||||
{
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
#include "bacnet/proplist.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
#include "bacnet/basic/sys/keylist.h"
|
||||
/* BACnet Stack Objects */
|
||||
#include "bacnet/basic/object/device.h"
|
||||
/* me! */
|
||||
#include "mso.h"
|
||||
|
||||
@@ -45,7 +47,12 @@ struct object_data {
|
||||
void *Context;
|
||||
};
|
||||
/* Key List for storing the object data sorted by instance number */
|
||||
static OS_Keylist Object_List;
|
||||
static OS_Keylist Object_Lists[MAX_NUM_DEVICES];
|
||||
#ifdef BAC_ROUTING
|
||||
#define Object_List (Object_Lists[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define Object_List (Object_Lists[0])
|
||||
#endif
|
||||
/* common object type */
|
||||
static const BACNET_OBJECT_TYPE Object_Type = OBJECT_MULTI_STATE_OUTPUT;
|
||||
/* callback for present value writes */
|
||||
@@ -1380,17 +1387,30 @@ bool Multistate_Output_Delete(uint32_t object_instance)
|
||||
void Multistate_Output_Cleanup(void)
|
||||
{
|
||||
struct object_data *pObject;
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1398,7 +1418,21 @@ void Multistate_Output_Cleanup(void)
|
||||
*/
|
||||
void Multistate_Output_Init(void)
|
||||
{
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#include "bacnet/wp.h"
|
||||
#include "bacnet/basic/sys/keylist.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
/* BACnet Stack Objects */
|
||||
#include "bacnet/basic/object/device.h"
|
||||
/* me! */
|
||||
#include "bacnet/basic/object/msv.h"
|
||||
|
||||
@@ -36,7 +38,12 @@ struct object_data {
|
||||
void *Context;
|
||||
};
|
||||
/* Key List for storing the object data sorted by instance number */
|
||||
static OS_Keylist Object_List;
|
||||
static OS_Keylist Object_Lists[MAX_NUM_DEVICES];
|
||||
#ifdef BAC_ROUTING
|
||||
#define Object_List (Object_Lists[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define Object_List (Object_Lists[0])
|
||||
#endif
|
||||
/* common object type */
|
||||
static const BACNET_OBJECT_TYPE Object_Type = OBJECT_MULTI_STATE_VALUE;
|
||||
/* callback for present value writes */
|
||||
@@ -1083,17 +1090,30 @@ bool Multistate_Value_Delete(uint32_t object_instance)
|
||||
void Multistate_Value_Cleanup(void)
|
||||
{
|
||||
struct object_data *pObject;
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1101,7 +1121,21 @@ void Multistate_Value_Cleanup(void)
|
||||
*/
|
||||
void Multistate_Value_Init(void)
|
||||
{
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -34,7 +34,13 @@
|
||||
#endif
|
||||
|
||||
#if defined(INTRINSIC_REPORTING)
|
||||
static NOTIFICATION_CLASS_INFO NC_Info[MAX_NOTIFICATION_CLASSES];
|
||||
static NOTIFICATION_CLASS_INFO NC_Infos[MAX_NUM_DEVICES]
|
||||
[MAX_NOTIFICATION_CLASSES];
|
||||
#ifdef BAC_ROUTING
|
||||
#define NC_Info (NC_Infos[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define NC_Info (NC_Infos[0])
|
||||
#endif
|
||||
/* buffer for sending event messages */
|
||||
static uint8_t Event_Buffer[MAX_APDU];
|
||||
|
||||
@@ -119,25 +125,38 @@ static void Notification_Class_I_Am_Router_To_Network_Handler(
|
||||
|
||||
void Notification_Class_Init(void)
|
||||
{
|
||||
uint16_t dev_id;
|
||||
uint8_t NotifyIdx = 0;
|
||||
unsigned i;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
for (NotifyIdx = 0; NotifyIdx < MAX_NOTIFICATION_CLASSES; NotifyIdx++) {
|
||||
/* init with zeros */
|
||||
memset(&NC_Info[NotifyIdx], 0x00, sizeof(NOTIFICATION_CLASS_INFO));
|
||||
/* set the basic parameters */
|
||||
NC_Info[NotifyIdx].Ack_Required = 0;
|
||||
/* The lowest priority for Normal message = 255 */
|
||||
NC_Info[NotifyIdx].Priority[TRANSITION_TO_OFFNORMAL] = 255;
|
||||
NC_Info[NotifyIdx].Priority[TRANSITION_TO_FAULT] = 255;
|
||||
NC_Info[NotifyIdx].Priority[TRANSITION_TO_NORMAL] = 255;
|
||||
/* note: default uses wildcard device destination */
|
||||
for (i = 0; i < NC_MAX_RECIPIENTS; i++) {
|
||||
BACNET_DESTINATION *destination;
|
||||
destination = &NC_Info[NotifyIdx].Recipient_List[i];
|
||||
bacnet_destination_default_init(destination);
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
for (NotifyIdx = 0; NotifyIdx < MAX_NOTIFICATION_CLASSES; NotifyIdx++) {
|
||||
/* init with zeros */
|
||||
memset(&NC_Info[NotifyIdx], 0x00, sizeof(NOTIFICATION_CLASS_INFO));
|
||||
/* set the basic parameters */
|
||||
NC_Info[NotifyIdx].Ack_Required = 0;
|
||||
/* The lowest priority for Normal message = 255 */
|
||||
NC_Info[NotifyIdx].Priority[TRANSITION_TO_OFFNORMAL] = 255;
|
||||
NC_Info[NotifyIdx].Priority[TRANSITION_TO_FAULT] = 255;
|
||||
NC_Info[NotifyIdx].Priority[TRANSITION_TO_NORMAL] = 255;
|
||||
/* note: default uses wildcard device destination */
|
||||
for (i = 0; i < NC_MAX_RECIPIENTS; i++) {
|
||||
BACNET_DESTINATION *destination;
|
||||
destination = &NC_Info[NotifyIdx].Recipient_List[i];
|
||||
bacnet_destination_default_init(destination);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
npdu_set_i_am_router_to_network_handler(
|
||||
Notification_Class_I_Am_Router_To_Network_Handler);
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "bacnet/datalink/bvlc6.h"
|
||||
#include "bacnet/datalink/datalink.h"
|
||||
#include "bacnet/basic/binding/address.h"
|
||||
/* BACnet Stack Objects */
|
||||
#include "bacnet/basic/object/device.h"
|
||||
/* me */
|
||||
#include "bacnet/basic/object/netport.h"
|
||||
@@ -129,7 +130,13 @@ struct object_data {
|
||||
#define BACNET_NETWORK_PORTS_MAX 1
|
||||
#endif
|
||||
|
||||
static struct object_data Object_List[BACNET_NETWORK_PORTS_MAX];
|
||||
static struct object_data Object_Lists[MAX_NUM_DEVICES]
|
||||
[BACNET_NETWORK_PORTS_MAX];
|
||||
#ifdef BAC_ROUTING
|
||||
#define Object_List (Object_Lists[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define Object_List (Object_Lists[0])
|
||||
#endif
|
||||
|
||||
/* BACnetARRAY of REAL, is an array of the link speeds
|
||||
supported by this network port */
|
||||
@@ -4833,13 +4840,27 @@ void Network_Port_Cleanup(void)
|
||||
{
|
||||
#if defined(BACDL_BSC) && defined(BACNET_SECURE_CONNECT_ROUTING_TABLE)
|
||||
unsigned index = 0;
|
||||
for (index = 0; index < BACNET_NETWORK_PORTS_MAX; index++) {
|
||||
BACNET_SC_PARAMS *sc = &Object_List[index].Network.BSC.Parameters;
|
||||
if (sc->Routing_Table) {
|
||||
Keylist_Delete(sc->Routing_Table);
|
||||
sc->Routing_Table = NULL;
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
for (index = 0; index < BACNET_NETWORK_PORTS_MAX; index++) {
|
||||
BACNET_SC_PARAMS *sc = &Object_List[index].Network.BSC.Parameters;
|
||||
if (sc->Routing_Table) {
|
||||
Keylist_Delete(sc->Routing_Table);
|
||||
sc->Routing_Table = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -4881,35 +4902,46 @@ void Network_Port_Context_Set(uint32_t object_instance, void *context)
|
||||
void Network_Port_Init(void)
|
||||
{
|
||||
unsigned index = 0;
|
||||
uint16_t dev_id = 0;
|
||||
#ifdef BAC_ROUTING
|
||||
const uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
#ifdef BACDL_BSC
|
||||
BACNET_SC_PARAMS *sc;
|
||||
#endif /* BACDL_BSC */
|
||||
|
||||
/* do something interesting */
|
||||
|
||||
for (index = 0; index < BACNET_NETWORK_PORTS_MAX; index++) {
|
||||
memset(&Object_List[index], 0, sizeof(Object_List[index]));
|
||||
#ifdef BACDL_BSC
|
||||
Object_List[index].Network_Type = PORT_TYPE_BSC;
|
||||
sc = &Object_List[index].Network.BSC.Parameters;
|
||||
Object_List[index].Activate_Changes =
|
||||
Network_Port_SC_Pending_Params_Apply;
|
||||
Object_List[index].Discard_Changes =
|
||||
Network_Port_SC_Pending_Params_Discard;
|
||||
#ifdef BACNET_SECURE_CONNECT_ROUTING_TABLE
|
||||
sc->Routing_Table = Keylist_Create();
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
sc->SC_Failed_Connection_Requests_Count = 0;
|
||||
for (index = 0; index < BACNET_NETWORK_PORTS_MAX; index++) {
|
||||
memset(&Object_List[index], 0, sizeof(Object_List[index]));
|
||||
#ifdef BACDL_BSC
|
||||
Object_List[index].Network_Type = PORT_TYPE_BSC;
|
||||
sc = &Object_List[index].Network.BSC.Parameters;
|
||||
Object_List[index].Activate_Changes =
|
||||
Network_Port_SC_Pending_Params_Apply;
|
||||
Object_List[index].Discard_Changes =
|
||||
Network_Port_SC_Pending_Params_Discard;
|
||||
#ifdef BACNET_SECURE_CONNECT_ROUTING_TABLE
|
||||
sc->Routing_Table = Keylist_Create();
|
||||
#endif
|
||||
sc->SC_Failed_Connection_Requests_Count = 0;
|
||||
#if BSC_CONF_HUB_FUNCTIONS_NUM != 0
|
||||
sc->SC_Hub_Function_Connection_Status_Count = 0;
|
||||
sc->SC_Hub_Function_Connection_Status_Count = 0;
|
||||
#endif
|
||||
#if BSC_CONF_HUB_CONNECTORS_NUM != 0
|
||||
sc->SC_Direct_Connect_Connection_Status_Count = 0;
|
||||
sc->SC_Direct_Connect_Connection_Status_Count = 0;
|
||||
#endif
|
||||
(void)sc;
|
||||
(void)sc;
|
||||
#endif /* BACDL_BSC */
|
||||
}
|
||||
}
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef BACDL_BSC
|
||||
|
||||
@@ -31,7 +31,12 @@ struct object_data {
|
||||
};
|
||||
|
||||
/* Key List for storing object data sorted by instance number */
|
||||
static OS_Keylist Object_List = NULL;
|
||||
static OS_Keylist Object_Lists[MAX_NUM_DEVICES];
|
||||
#ifdef BAC_ROUTING
|
||||
#define Object_List (Object_Lists[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define Object_List (Object_Lists[0])
|
||||
#endif
|
||||
|
||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||
static const int32_t Properties_Required[] = {
|
||||
@@ -167,12 +172,24 @@ bool OctetString_Value_Delete(uint32_t object_instance)
|
||||
void OctetString_Value_Init(void)
|
||||
{
|
||||
#ifdef MAX_OCTETSTRING_VALUES
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
unsigned i = 0;
|
||||
uint16_t dev_id;
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
for (i = 0; i < MAX_OCTETSTRING_VALUES; i++) {
|
||||
OctetString_Value_Create(i);
|
||||
}
|
||||
}
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#else
|
||||
unsigned i = 0;
|
||||
|
||||
for (i = 0; i < MAX_OCTETSTRING_VALUES; i++) {
|
||||
OctetString_Value_Create(i);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -22,7 +22,12 @@
|
||||
#include "bacnet/basic/object/piv.h"
|
||||
|
||||
/* Key List for storing object data sorted by instance number */
|
||||
static OS_Keylist Object_List = NULL;
|
||||
static OS_Keylist Object_Lists[MAX_NUM_DEVICES];
|
||||
#ifdef BAC_ROUTING
|
||||
#define Object_List (Object_Lists[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define Object_List (Object_Lists[0])
|
||||
#endif
|
||||
/* common object type */
|
||||
static const BACNET_OBJECT_TYPE Object_Type = OBJECT_POSITIVE_INTEGER_VALUE;
|
||||
|
||||
@@ -171,8 +176,22 @@ bool PositiveInteger_Value_Delete(uint32_t object_instance)
|
||||
void PositiveInteger_Value_Init(void)
|
||||
{
|
||||
#ifdef MAX_POSITIVEINTEGER_VALUES
|
||||
#ifdef BAC_ROUTING
|
||||
unsigned i = 0;
|
||||
uint16_t dev_id;
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
}
|
||||
for (i = 0; i < MAX_POSITIVEINTEGER_VALUES; i++) {
|
||||
PositiveInteger_Value_Create(i);
|
||||
}
|
||||
}
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#else
|
||||
unsigned i = 0;
|
||||
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
}
|
||||
@@ -180,6 +199,7 @@ void PositiveInteger_Value_Init(void)
|
||||
PositiveInteger_Value_Create(i);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,7 +30,12 @@
|
||||
#include "bacnet/basic/object/program.h"
|
||||
|
||||
/* Key List for storing the object data sorted by instance number */
|
||||
static OS_Keylist Object_List = NULL;
|
||||
static OS_Keylist Object_Lists[MAX_NUM_DEVICES];
|
||||
#ifdef BAC_ROUTING
|
||||
#define Object_List (Object_Lists[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define Object_List (Object_Lists[0])
|
||||
#endif
|
||||
/* common object type */
|
||||
static const BACNET_OBJECT_TYPE Object_Type = OBJECT_PROGRAM;
|
||||
|
||||
@@ -1426,18 +1431,30 @@ bool Program_Delete(uint32_t object_instance)
|
||||
void Program_Cleanup(void)
|
||||
{
|
||||
struct object_data *pObject;
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1445,7 +1462,21 @@ void Program_Cleanup(void)
|
||||
*/
|
||||
void Program_Init(void)
|
||||
{
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -25,7 +25,12 @@
|
||||
#define MAX_SCHEDULES 4
|
||||
#endif
|
||||
|
||||
static SCHEDULE_DESCR Schedule_Descr[MAX_SCHEDULES];
|
||||
static SCHEDULE_DESCR Schedule_Descrs[MAX_NUM_DEVICES][MAX_SCHEDULES];
|
||||
#ifdef BAC_ROUTING
|
||||
#define Schedule_Descr (Schedule_Descrs[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define Schedule_Descr (Schedule_Descrs[0])
|
||||
#endif
|
||||
|
||||
static const int32_t Schedule_Properties_Required[] = {
|
||||
/* list of required properties */
|
||||
@@ -134,6 +139,7 @@ SCHEDULE_DESCR *Schedule_Object(uint32_t object_instance)
|
||||
*/
|
||||
void Schedule_Init(void)
|
||||
{
|
||||
uint16_t dev_id;
|
||||
unsigned i, j;
|
||||
BACNET_DATE start_date = { 0 }, end_date = { 0 };
|
||||
SCHEDULE_DESCR *psched;
|
||||
@@ -141,6 +147,9 @@ void Schedule_Init(void)
|
||||
unsigned e;
|
||||
BACNET_SPECIAL_EVENT *event;
|
||||
#endif
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
/* whole year, change as necessary */
|
||||
datetime_set_date(&start_date, 0, 1, 1);
|
||||
@@ -149,38 +158,49 @@ void Schedule_Init(void)
|
||||
datetime_set_date(&end_date, 0, 12, 31);
|
||||
datetime_wildcard_year_set(&end_date);
|
||||
datetime_wildcard_weekday_set(&end_date);
|
||||
for (i = 0; i < MAX_SCHEDULES; i++, psched++) {
|
||||
psched = &Schedule_Descr[i];
|
||||
datetime_copy_date(&psched->Start_Date, &start_date);
|
||||
datetime_copy_date(&psched->End_Date, &end_date);
|
||||
for (j = 0; j < BACNET_WEEKLY_SCHEDULE_SIZE; j++) {
|
||||
psched->Weekly_Schedule[j].TV_Count = 0;
|
||||
}
|
||||
memcpy(
|
||||
&psched->Present_Value, &psched->Schedule_Default,
|
||||
sizeof(psched->Present_Value));
|
||||
psched->Schedule_Default.context_specific = false;
|
||||
psched->Schedule_Default.tag = BACNET_APPLICATION_TAG_REAL;
|
||||
psched->Schedule_Default.type.Real = 21.0f; /* 21 C, room temperature */
|
||||
psched->obj_prop_ref_cnt = 0; /* no references, add as needed */
|
||||
psched->Priority_For_Writing = 16; /* lowest priority */
|
||||
psched->Out_Of_Service = false;
|
||||
#if BACNET_EXCEPTION_SCHEDULE_SIZE
|
||||
for (e = 0; e < BACNET_EXCEPTION_SCHEDULE_SIZE; e++) {
|
||||
event = &psched->Exception_Schedule[e];
|
||||
event->periodTag = BACNET_SPECIAL_EVENT_PERIOD_CALENDAR_ENTRY;
|
||||
event->period.calendarEntry.tag = BACNET_CALENDAR_DATE_RANGE;
|
||||
datetime_copy_date(
|
||||
&event->period.calendarEntry.type.DateRange.startdate,
|
||||
&start_date);
|
||||
datetime_copy_date(
|
||||
&event->period.calendarEntry.type.DateRange.enddate, &end_date);
|
||||
event->period.calendarEntry.next = NULL;
|
||||
event->timeValues.TV_Count = 0;
|
||||
event->priority = 16;
|
||||
}
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
for (i = 0; i < MAX_SCHEDULES; i++) {
|
||||
psched = &Schedule_Descr[i];
|
||||
datetime_copy_date(&psched->Start_Date, &start_date);
|
||||
datetime_copy_date(&psched->End_Date, &end_date);
|
||||
for (j = 0; j < BACNET_WEEKLY_SCHEDULE_SIZE; j++) {
|
||||
psched->Weekly_Schedule[j].TV_Count = 0;
|
||||
}
|
||||
memcpy(
|
||||
&psched->Present_Value, &psched->Schedule_Default,
|
||||
sizeof(psched->Present_Value));
|
||||
psched->Schedule_Default.context_specific = false;
|
||||
psched->Schedule_Default.tag = BACNET_APPLICATION_TAG_REAL;
|
||||
psched->Schedule_Default.type.Real =
|
||||
21.0f; /* 21 C, room temperature */
|
||||
psched->obj_prop_ref_cnt = 0; /* no references, add as needed */
|
||||
psched->Priority_For_Writing = 16; /* lowest priority */
|
||||
psched->Out_Of_Service = false;
|
||||
#if BACNET_EXCEPTION_SCHEDULE_SIZE
|
||||
for (e = 0; e < BACNET_EXCEPTION_SCHEDULE_SIZE; e++) {
|
||||
event = &psched->Exception_Schedule[e];
|
||||
event->periodTag = BACNET_SPECIAL_EVENT_PERIOD_CALENDAR_ENTRY;
|
||||
event->period.calendarEntry.tag = BACNET_CALENDAR_DATE_RANGE;
|
||||
datetime_copy_date(
|
||||
&event->period.calendarEntry.type.DateRange.startdate,
|
||||
&start_date);
|
||||
datetime_copy_date(
|
||||
&event->period.calendarEntry.type.DateRange.enddate,
|
||||
&end_date);
|
||||
event->period.calendarEntry.next = NULL;
|
||||
event->timeValues.TV_Count = 0;
|
||||
event->priority = 16;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#include "bacnet/proplist.h"
|
||||
#include "bacnet/rp.h"
|
||||
#include "bacnet/basic/sys/keylist.h"
|
||||
/* BACnet Stack Objects */
|
||||
#include "bacnet/basic/object/device.h"
|
||||
/* me! */
|
||||
#include "structured_view.h"
|
||||
|
||||
@@ -36,7 +38,12 @@ struct object_data {
|
||||
};
|
||||
|
||||
/* Key List for storing the object data sorted by instance number */
|
||||
static OS_Keylist Object_List;
|
||||
static OS_Keylist Object_Lists[MAX_NUM_DEVICES];
|
||||
#ifdef BAC_ROUTING
|
||||
#define Object_List (Object_Lists[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define Object_List (Object_Lists[0])
|
||||
#endif
|
||||
|
||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||
static const int32_t Properties_Required[] = {
|
||||
@@ -1844,15 +1851,28 @@ bool Structured_View_Delete(uint32_t object_instance)
|
||||
void Structured_View_Cleanup(void)
|
||||
{
|
||||
struct object_data *pObject;
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
Structured_View_Object_Free(pObject);
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
Structured_View_Object_Free(pObject);
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1868,7 +1888,21 @@ size_t Structured_View_Size(void)
|
||||
*/
|
||||
void Structured_View_Init(void)
|
||||
{
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
#include "bacnet/wp.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
#include "bacnet/basic/sys/keylist.h"
|
||||
/* BACnet Stack Objects */
|
||||
#include "bacnet/basic/object/device.h"
|
||||
/* me! */
|
||||
#include "time_value.h"
|
||||
|
||||
@@ -44,7 +46,12 @@ struct object_data {
|
||||
};
|
||||
|
||||
/* Key List for storing the object data sorted by instance number */
|
||||
static OS_Keylist Object_List;
|
||||
static OS_Keylist Object_Lists[MAX_NUM_DEVICES];
|
||||
#ifdef BAC_ROUTING
|
||||
#define Object_List (Object_Lists[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define Object_List (Object_Lists[0])
|
||||
#endif
|
||||
/* callback for present value writes */
|
||||
static time_value_write_present_value_callback
|
||||
Time_Value_Write_Present_Value_Callback;
|
||||
@@ -891,17 +898,30 @@ bool Time_Value_Delete(uint32_t object_instance)
|
||||
void Time_Value_Cleanup(void)
|
||||
{
|
||||
struct object_data *pObject;
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -909,7 +929,21 @@ void Time_Value_Cleanup(void)
|
||||
*/
|
||||
void Time_Value_Init(void)
|
||||
{
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -35,7 +35,12 @@
|
||||
#endif
|
||||
|
||||
/* Key List for storing the object data sorted by instance number */
|
||||
static OS_Keylist Object_List = NULL;
|
||||
static OS_Keylist Object_Lists[MAX_NUM_DEVICES];
|
||||
#ifdef BAC_ROUTING
|
||||
#define Object_List (Object_Lists[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define Object_List (Object_Lists[0])
|
||||
#endif
|
||||
/* common object type */
|
||||
static const BACNET_OBJECT_TYPE Object_Type = OBJECT_TIMER;
|
||||
static write_property_function Write_Property_Internal_Callback;
|
||||
@@ -2386,18 +2391,30 @@ bool Timer_Delete(uint32_t object_instance)
|
||||
void Timer_Cleanup(void)
|
||||
{
|
||||
struct object_data *pObject;
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (Object_List) {
|
||||
do {
|
||||
pObject = Keylist_Data_Pop(Object_List);
|
||||
if (pObject) {
|
||||
free(pObject);
|
||||
}
|
||||
} while (pObject);
|
||||
Keylist_Delete(Object_List);
|
||||
Object_List = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2405,7 +2422,21 @@ void Timer_Cleanup(void)
|
||||
*/
|
||||
void Timer_Init(void)
|
||||
{
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
uint16_t dev_id;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
if (!Object_List) {
|
||||
Object_List = Keylist_Create();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -30,8 +30,19 @@
|
||||
#define MAX_TREND_LOGS 8
|
||||
#endif
|
||||
|
||||
static TL_DATA_REC Logs[MAX_TREND_LOGS][TL_MAX_ENTRIES];
|
||||
static TL_LOG_INFO LogInfo[MAX_TREND_LOGS];
|
||||
static TL_DATA_REC Logs_Records[MAX_NUM_DEVICES][MAX_TREND_LOGS]
|
||||
[TL_MAX_ENTRIES];
|
||||
#ifdef BAC_ROUTING
|
||||
#define Logs (Logs_Records[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define Logs (Logs_Records[0])
|
||||
#endif
|
||||
static TL_LOG_INFO LogInfos[MAX_NUM_DEVICES][MAX_TREND_LOGS];
|
||||
#ifdef BAC_ROUTING
|
||||
#define LogInfo (LogInfos[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define LogInfo (LogInfos[0])
|
||||
#endif
|
||||
|
||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||
static const int32_t Trend_Log_Properties_Required[] = {
|
||||
@@ -195,85 +206,98 @@ static bacnet_time_t Trend_Log_Epoch_Seconds_Now(void)
|
||||
void Trend_Log_Init(void)
|
||||
{
|
||||
static bool initialized = false;
|
||||
uint16_t dev_id;
|
||||
int iLog;
|
||||
int iEntry;
|
||||
BACNET_DATE_TIME bdatetime = { 0 };
|
||||
bacnet_time_t tClock;
|
||||
uint8_t month;
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
#endif
|
||||
|
||||
if (!initialized) {
|
||||
initialized = true;
|
||||
|
||||
/* initialize all the values */
|
||||
|
||||
for (iLog = 0; iLog < MAX_TREND_LOGS; iLog++) {
|
||||
/*
|
||||
* Do we need to do anything here?
|
||||
* Trend logs are usually assumed to survive over resets
|
||||
* and are frequently implemented using Battery Backed RAM
|
||||
* If they are implemented using Flash or SD cards or some
|
||||
* such mechanism there may be some RAM based setup needed
|
||||
* for log management purposes.
|
||||
* We probably need to look at inserting LOG_INTERRUPTED
|
||||
* entries into any active logs if the power down or reset
|
||||
* may have caused us to miss readings.
|
||||
*/
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
#endif
|
||||
for (iLog = 0; iLog < MAX_TREND_LOGS; iLog++) {
|
||||
/*
|
||||
* Do we need to do anything here?
|
||||
* Trend logs are usually assumed to survive over resets
|
||||
* and are frequently implemented using Battery Backed RAM
|
||||
* If they are implemented using Flash or SD cards or some
|
||||
* such mechanism there may be some RAM based setup needed
|
||||
* for log management purposes.
|
||||
* We probably need to look at inserting LOG_INTERRUPTED
|
||||
* entries into any active logs if the power down or reset
|
||||
* may have caused us to miss readings.
|
||||
*/
|
||||
|
||||
/* We will just fill the logs with some entries for testing
|
||||
* purposes.
|
||||
*/
|
||||
/* Different month for each log */
|
||||
month = iLog + 1;
|
||||
datetime_set_values(&bdatetime, 2009, month, 1, 0, 0, 0, 0);
|
||||
tClock = datetime_seconds_since_epoch(&bdatetime);
|
||||
for (iEntry = 0; iEntry < TL_MAX_ENTRIES; iEntry++) {
|
||||
Logs[iLog][iEntry].tTimeStamp = tClock;
|
||||
Logs[iLog][iEntry].ucRecType = TL_TYPE_REAL;
|
||||
Logs[iLog][iEntry].Datum.fReal =
|
||||
(float)(iEntry + (iLog * TL_MAX_ENTRIES));
|
||||
/* Put status flags with every second log */
|
||||
if ((iLog & 1) == 0) {
|
||||
Logs[iLog][iEntry].ucStatus = 128;
|
||||
} else {
|
||||
Logs[iLog][iEntry].ucStatus = 0;
|
||||
/* We will just fill the logs with some entries for testing
|
||||
* purposes.
|
||||
*/
|
||||
/* Different month for each log */
|
||||
month = iLog + 1;
|
||||
datetime_set_values(&bdatetime, 2009, month, 1, 0, 0, 0, 0);
|
||||
tClock = datetime_seconds_since_epoch(&bdatetime);
|
||||
for (iEntry = 0; iEntry < TL_MAX_ENTRIES; iEntry++) {
|
||||
Logs[iLog][iEntry].tTimeStamp = tClock;
|
||||
Logs[iLog][iEntry].ucRecType = TL_TYPE_REAL;
|
||||
Logs[iLog][iEntry].Datum.fReal =
|
||||
(float)(iEntry + (iLog * TL_MAX_ENTRIES));
|
||||
/* Put status flags with every second log */
|
||||
if ((iLog & 1) == 0) {
|
||||
Logs[iLog][iEntry].ucStatus = 128;
|
||||
} else {
|
||||
Logs[iLog][iEntry].ucStatus = 0;
|
||||
}
|
||||
/* advance 15 minutes, in seconds */
|
||||
tClock += 900;
|
||||
}
|
||||
/* advance 15 minutes, in seconds */
|
||||
tClock += 900;
|
||||
|
||||
LogInfo[iLog].tLastDataTime = tClock - 900;
|
||||
LogInfo[iLog].bAlignIntervals = true;
|
||||
LogInfo[iLog].bEnable = true;
|
||||
LogInfo[iLog].bStopWhenFull = false;
|
||||
LogInfo[iLog].bTrigger = false;
|
||||
LogInfo[iLog].LoggingType = LOGGING_TYPE_POLLED;
|
||||
LogInfo[iLog].Source.arrayIndex = 0;
|
||||
LogInfo[iLog].ucTimeFlags = 0;
|
||||
LogInfo[iLog].ulIntervalOffset = 0;
|
||||
LogInfo[iLog].iIndex = 0;
|
||||
LogInfo[iLog].ulLogInterval = 900;
|
||||
LogInfo[iLog].ulRecordCount = TL_MAX_ENTRIES;
|
||||
LogInfo[iLog].ulTotalRecordCount = 10000;
|
||||
|
||||
LogInfo[iLog].Source.deviceIdentifier.instance =
|
||||
Device_Object_Instance_Number();
|
||||
LogInfo[iLog].Source.deviceIdentifier.type = OBJECT_DEVICE;
|
||||
LogInfo[iLog].Source.objectIdentifier.instance = iLog;
|
||||
LogInfo[iLog].Source.objectIdentifier.type =
|
||||
OBJECT_ANALOG_INPUT;
|
||||
LogInfo[iLog].Source.arrayIndex = BACNET_ARRAY_ALL;
|
||||
LogInfo[iLog].Source.propertyIdentifier = PROP_PRESENT_VALUE;
|
||||
|
||||
datetime_set_values(
|
||||
&LogInfo[iLog].StartTime, 2009, 1, 1, 0, 0, 0, 0);
|
||||
LogInfo[iLog].tStartTime =
|
||||
TL_BAC_Time_To_Local(&LogInfo[iLog].StartTime);
|
||||
datetime_set_values(
|
||||
&LogInfo[iLog].StopTime, 2020, 12, 22, 23, 59, 59, 99);
|
||||
LogInfo[iLog].tStopTime =
|
||||
TL_BAC_Time_To_Local(&LogInfo[iLog].StopTime);
|
||||
}
|
||||
|
||||
LogInfo[iLog].tLastDataTime = tClock - 900;
|
||||
LogInfo[iLog].bAlignIntervals = true;
|
||||
LogInfo[iLog].bEnable = true;
|
||||
LogInfo[iLog].bStopWhenFull = false;
|
||||
LogInfo[iLog].bTrigger = false;
|
||||
LogInfo[iLog].LoggingType = LOGGING_TYPE_POLLED;
|
||||
LogInfo[iLog].Source.arrayIndex = 0;
|
||||
LogInfo[iLog].ucTimeFlags = 0;
|
||||
LogInfo[iLog].ulIntervalOffset = 0;
|
||||
LogInfo[iLog].iIndex = 0;
|
||||
LogInfo[iLog].ulLogInterval = 900;
|
||||
LogInfo[iLog].ulRecordCount = TL_MAX_ENTRIES;
|
||||
LogInfo[iLog].ulTotalRecordCount = 10000;
|
||||
|
||||
LogInfo[iLog].Source.deviceIdentifier.instance =
|
||||
Device_Object_Instance_Number();
|
||||
LogInfo[iLog].Source.deviceIdentifier.type = OBJECT_DEVICE;
|
||||
LogInfo[iLog].Source.objectIdentifier.instance = iLog;
|
||||
LogInfo[iLog].Source.objectIdentifier.type = OBJECT_ANALOG_INPUT;
|
||||
LogInfo[iLog].Source.arrayIndex = BACNET_ARRAY_ALL;
|
||||
LogInfo[iLog].Source.propertyIdentifier = PROP_PRESENT_VALUE;
|
||||
|
||||
datetime_set_values(
|
||||
&LogInfo[iLog].StartTime, 2009, 1, 1, 0, 0, 0, 0);
|
||||
LogInfo[iLog].tStartTime =
|
||||
TL_BAC_Time_To_Local(&LogInfo[iLog].StartTime);
|
||||
datetime_set_values(
|
||||
&LogInfo[iLog].StopTime, 2020, 12, 22, 23, 59, 59, 99);
|
||||
LogInfo[iLog].tStopTime =
|
||||
TL_BAC_Time_To_Local(&LogInfo[iLog].StopTime);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,14 @@ typedef struct BACnet_COV_Subscription {
|
||||
#ifndef MAX_COV_SUBCRIPTIONS
|
||||
#define MAX_COV_SUBCRIPTIONS 128
|
||||
#endif
|
||||
static BACNET_COV_SUBSCRIPTION COV_Subscriptions[MAX_COV_SUBCRIPTIONS];
|
||||
|
||||
static BACNET_COV_SUBSCRIPTION COV_Subscriptions_List[MAX_NUM_DEVICES]
|
||||
[MAX_COV_SUBCRIPTIONS];
|
||||
#ifdef BAC_ROUTING
|
||||
#define COV_Subscriptions (COV_Subscriptions_List[Routed_Device_Object_Index()])
|
||||
#else
|
||||
#define COV_Subscriptions (COV_Subscriptions_List[0])
|
||||
#endif
|
||||
#ifndef MAX_COV_ADDRESSES
|
||||
#define MAX_COV_ADDRESSES 16
|
||||
#endif
|
||||
@@ -97,6 +104,32 @@ static void cov_address_remove_unused(void)
|
||||
unsigned cov_index = 0;
|
||||
bool found = false;
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
uint16_t dev_id = 0;
|
||||
for (cov_index = 0; cov_index < MAX_COV_ADDRESSES; cov_index++) {
|
||||
if (COV_Addresses[cov_index].valid) {
|
||||
found = false;
|
||||
for (dev_id = 0; dev_id < Get_Num_Managed_Devices(); dev_id++) {
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
for (index = 0; index < MAX_COV_SUBCRIPTIONS; index++) {
|
||||
if ((COV_Subscriptions[index].flag.valid) &&
|
||||
(COV_Subscriptions[index].dest_index == cov_index)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
COV_Addresses[cov_index].valid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#else
|
||||
for (cov_index = 0; cov_index < MAX_COV_ADDRESSES; cov_index++) {
|
||||
if (COV_Addresses[cov_index].valid) {
|
||||
found = false;
|
||||
@@ -112,6 +145,7 @@ static void cov_address_remove_unused(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -320,7 +354,27 @@ int handler_cov_encode_subscriptions(uint8_t *apdu, int max_apdu)
|
||||
void handler_cov_init(void)
|
||||
{
|
||||
unsigned index = 0;
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
uint16_t dev_id = 0;
|
||||
for (dev_id = 0; dev_id < MAX_NUM_DEVICES; dev_id++) {
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
for (index = 0; index < MAX_COV_SUBCRIPTIONS; index++) {
|
||||
/* initialize with invalid COV address */
|
||||
COV_Subscriptions[index].flag.valid = false;
|
||||
COV_Subscriptions[index].dest_index = MAX_COV_ADDRESSES;
|
||||
COV_Subscriptions[index].subscriberProcessIdentifier = 0;
|
||||
COV_Subscriptions[index].monitoredObjectIdentifier.type =
|
||||
OBJECT_ANALOG_INPUT;
|
||||
COV_Subscriptions[index].monitoredObjectIdentifier.instance = 0;
|
||||
COV_Subscriptions[index].flag.issueConfirmedNotifications = false;
|
||||
COV_Subscriptions[index].invokeID = 0;
|
||||
COV_Subscriptions[index].lifetime = 0;
|
||||
COV_Subscriptions[index].flag.send_requested = false;
|
||||
}
|
||||
}
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#else
|
||||
for (index = 0; index < MAX_COV_SUBCRIPTIONS; index++) {
|
||||
/* initialize with invalid COV address */
|
||||
COV_Subscriptions[index].flag.valid = false;
|
||||
@@ -334,6 +388,7 @@ void handler_cov_init(void)
|
||||
COV_Subscriptions[index].lifetime = 0;
|
||||
COV_Subscriptions[index].flag.send_requested = false;
|
||||
}
|
||||
#endif
|
||||
for (index = 0; index < MAX_COV_ADDRESSES; index++) {
|
||||
COV_Addresses[index].valid = false;
|
||||
}
|
||||
@@ -587,7 +642,27 @@ void handler_cov_timer_seconds(uint32_t elapsed_seconds)
|
||||
{
|
||||
unsigned index = 0;
|
||||
uint32_t lifetime_seconds = 0;
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
uint16_t dev_id = 0;
|
||||
if (elapsed_seconds) {
|
||||
/* handle the subscription timeouts */
|
||||
for (dev_id = 0; dev_id < Get_Num_Managed_Devices(); dev_id++) {
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
for (index = 0; index < MAX_COV_SUBCRIPTIONS; index++) {
|
||||
if (COV_Subscriptions[index].flag.valid) {
|
||||
lifetime_seconds = COV_Subscriptions[index].lifetime;
|
||||
if (lifetime_seconds) {
|
||||
/* only expire COV with definite lifetimes */
|
||||
cov_lifetime_expiration_handler(
|
||||
index, elapsed_seconds, lifetime_seconds);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#else
|
||||
if (elapsed_seconds) {
|
||||
/* handle the subscription timeouts */
|
||||
for (index = 0; index < MAX_COV_SUBCRIPTIONS; index++) {
|
||||
@@ -601,24 +676,38 @@ void handler_cov_timer_seconds(uint32_t elapsed_seconds)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool handler_cov_fsm(void)
|
||||
{
|
||||
static int index = 0;
|
||||
static int indices[MAX_NUM_DEVICES] = { 0 };
|
||||
#ifdef BAC_ROUTING
|
||||
const int dev_id = Routed_Device_Object_Index();
|
||||
#else
|
||||
const int dev_id = 0;
|
||||
#endif
|
||||
|
||||
BACNET_OBJECT_TYPE object_type = MAX_BACNET_OBJECT_TYPE;
|
||||
uint32_t object_instance = 0;
|
||||
bool status = false;
|
||||
bool send = false;
|
||||
BACNET_PROPERTY_VALUE value_list[MAX_COV_PROPERTIES] = { 0 };
|
||||
|
||||
/* states for transmitting */
|
||||
static enum {
|
||||
typedef enum cov_fsm_state {
|
||||
COV_STATE_IDLE = 0,
|
||||
COV_STATE_MARK,
|
||||
COV_STATE_CLEAR,
|
||||
COV_STATE_FREE,
|
||||
COV_STATE_SEND
|
||||
} cov_task_state = COV_STATE_IDLE;
|
||||
} cov_fsm_state_t;
|
||||
static cov_fsm_state_t cov_task_states[MAX_NUM_DEVICES] = {
|
||||
COV_STATE_IDLE
|
||||
};
|
||||
|
||||
int index = indices[dev_id];
|
||||
cov_fsm_state_t cov_task_state = cov_task_states[dev_id];
|
||||
|
||||
switch (cov_task_state) {
|
||||
case COV_STATE_IDLE:
|
||||
@@ -735,12 +824,26 @@ bool handler_cov_fsm(void)
|
||||
cov_task_state = COV_STATE_IDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
indices[dev_id] = index;
|
||||
cov_task_states[dev_id] = cov_task_state;
|
||||
|
||||
return (cov_task_state == COV_STATE_IDLE);
|
||||
}
|
||||
|
||||
void handler_cov_task(void)
|
||||
{
|
||||
#ifdef BAC_ROUTING
|
||||
uint16_t current_dev_id = Routed_Device_Object_Index();
|
||||
uint16_t dev_id = 0;
|
||||
for (dev_id = 0; dev_id < Get_Num_Managed_Devices(); dev_id++) {
|
||||
Set_Routed_Device_Object_Index(dev_id);
|
||||
handler_cov_fsm();
|
||||
}
|
||||
Set_Routed_Device_Object_Index(current_dev_id);
|
||||
#else
|
||||
handler_cov_fsm();
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool cov_subscribe(
|
||||
|
||||
+52
-1
@@ -15,6 +15,12 @@
|
||||
#include "bacnet/bacint.h"
|
||||
#include "bacnet/npdu.h"
|
||||
#include "bacnet/apdu.h"
|
||||
/* BACnet routing support */
|
||||
#ifdef BAC_ROUTING
|
||||
#include "bacnet/basic/sys/debug.h"
|
||||
#include "bacnet/basic/object/device.h"
|
||||
#include "bacnet/datalink/datalink.h"
|
||||
#endif
|
||||
|
||||
/** Copy the npdu_data structure information from src to dest.
|
||||
* @param dest [out] The 'to' structure
|
||||
@@ -35,6 +41,42 @@ void npdu_copy_data(BACNET_NPDU_DATA *dest, const BACNET_NPDU_DATA *src)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
/** Encode NPDU source address for routing.
|
||||
* Sets the source address based on whether this is a virtual device
|
||||
* or a gateway device.
|
||||
* @param src [out] Pointer to store the source address
|
||||
* @return 0 on success, -1 if device object not found
|
||||
*/
|
||||
static int npdu_encode_pdu_routing(BACNET_ADDRESS *src)
|
||||
{
|
||||
DEVICE_OBJECT_DATA *pDev = NULL;
|
||||
bool is_routed_device = false;
|
||||
/* get the currently active routed device object */
|
||||
pDev = Get_Routed_Device_Object(-1);
|
||||
if (pDev == NULL) {
|
||||
debug_fprintf(stderr, "Device object not found\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
is_routed_device = (pDev->bacDevAddr.net != 0);
|
||||
|
||||
if (is_routed_device) {
|
||||
bacnet_address_copy(src, &pDev->bacDevAddr);
|
||||
debug_fprintf(
|
||||
stdout, "Virtual Device NPDU: SNET=%d, Instance=%u\n",
|
||||
pDev->bacDevAddr.net, pDev->bacObj.Object_Instance_Number);
|
||||
} else {
|
||||
datalink_get_my_address(src);
|
||||
debug_fprintf(
|
||||
stdout, "Gateway Device NPDU: Instance=%u\n",
|
||||
pDev->bacObj.Object_Instance_Number);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
The following ICI parameters are exchanged with the
|
||||
@@ -87,10 +129,12 @@ ABORT.indication Yes Yes Yes No
|
||||
* @param dest [in] The routing destination information if the message must
|
||||
* be routed to reach its destination. If dest->net and dest->len are 0,
|
||||
* there is no routing destination information.
|
||||
* @param src [in] The routing source information if the message was routed
|
||||
* @param src [in,out] The routing source information if the message was routed
|
||||
* from another BACnet network. If src->net and src->len are 0, there is no
|
||||
* routing source information. This src describes the original source of the
|
||||
* message when it had to be routed to reach this BACnet Device.
|
||||
* @note When BAC_ROUTING is defined, src is populated with the active routed
|
||||
* device or datalink address before encoding.
|
||||
* @param npdu_data [in] The structure which describes how the NCPI and other
|
||||
* NPDU bytes should be encoded.
|
||||
* @return On success, returns the number of bytes which were encoded into
|
||||
@@ -105,6 +149,13 @@ int npdu_encode_pdu(
|
||||
int len = 0; /* return value - number of octets loaded in this function */
|
||||
uint8_t i = 0; /* counter */
|
||||
|
||||
#ifdef BAC_ROUTING
|
||||
/* populate src with the active routed device address or datalink address */
|
||||
if (src) {
|
||||
(void)npdu_encode_pdu_routing(src);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (npdu_data) {
|
||||
/* protocol version */
|
||||
if (npdu) {
|
||||
|
||||
Reference in New Issue
Block a user