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:
Hyeongjun Kim
2026-03-31 04:16:17 +09:00
committed by GitHub
parent b8dd89b879
commit f408b6eb7f
54 changed files with 2592 additions and 586 deletions
+9
View File
@@ -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})
+9
View File
@@ -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
+4
View File
@@ -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 $@
+97
View File
@@ -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
+42
View File
@@ -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
+339
View File
@@ -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 */
+9 -1
View File
@@ -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;
+36 -13
View File
@@ -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;
}
+39 -19
View File
@@ -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;
}
+38 -15
View File
@@ -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;
}
+30 -9
View File
@@ -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;
}
+28 -8
View File
@@ -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;
}
+32 -11
View File
@@ -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;
}
+46 -12
View File
@@ -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(
+46 -12
View File
@@ -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
}
+47 -13
View File
@@ -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
}
+46 -12
View File
@@ -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(
+49 -15
View File
@@ -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
}
+46 -12
View File
@@ -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
}
/**
+46 -12
View File
@@ -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
}
+46 -12
View File
@@ -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
}
+46 -12
View File
@@ -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
}
+44 -12
View File
@@ -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
}
/**
+48 -14
View File
@@ -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
}
+46 -12
View File
@@ -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
}
+44 -12
View File
@@ -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
}
+46 -12
View File
@@ -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
}
+27 -5
View File
@@ -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
}
/**
+32 -12
View File
@@ -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;
}
+47 -13
View File
@@ -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
}
/**
+63 -3
View File
@@ -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
+7
View File
@@ -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
*/
+45 -14
View File
@@ -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
}
+46 -12
View File
@@ -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
}
+46 -12
View File
@@ -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
}
+44 -13
View File
@@ -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
}
+48 -13
View File
@@ -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
}
+46 -12
View File
@@ -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
}
+46 -12
View File
@@ -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
}
+46 -12
View File
@@ -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
}
+46 -12
View File
@@ -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 -15
View File
@@ -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);
+54 -22
View File
@@ -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
+19 -2
View File
@@ -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 -2
View File
@@ -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
}
/**
+44 -13
View File
@@ -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
}
+51 -31
View File
@@ -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
}
/**
+44 -10
View File
@@ -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
}
+46 -12
View File
@@ -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
}
+44 -13
View File
@@ -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
}
+88 -64
View File
@@ -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;
}
+109 -6
View File
@@ -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
View File
@@ -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) {