feat(gateway_bacnet): add support for new BACnet object types and enhance state management functions

Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
Tony
2026-05-04 01:18:44 +08:00
parent 30a96c5125
commit 8aa5a451a4
4 changed files with 196 additions and 1 deletions
+4
View File
@@ -49,11 +49,15 @@ set(BACNET_BASIC_SRCS
"${BACNET_SRC_ROOT}/bacnet/basic/binding/address.c"
"${BACNET_SRC_ROOT}/bacnet/basic/npdu/h_npdu.c"
"${BACNET_SRC_ROOT}/bacnet/basic/npdu/s_router.c"
"${BACNET_SRC_ROOT}/bacnet/basic/object/ai.c"
"${BACNET_SRC_ROOT}/bacnet/basic/object/ao.c"
"${BACNET_SRC_ROOT}/bacnet/basic/object/av.c"
"${BACNET_SRC_ROOT}/bacnet/basic/object/bi.c"
"${BACNET_SRC_ROOT}/bacnet/basic/object/bo.c"
"${BACNET_SRC_ROOT}/bacnet/basic/object/bv.c"
"${BACNET_SRC_ROOT}/bacnet/basic/object/device.c"
"${BACNET_SRC_ROOT}/bacnet/basic/object/ms-input.c"
"${BACNET_SRC_ROOT}/bacnet/basic/object/mso.c"
"${BACNET_SRC_ROOT}/bacnet/basic/object/msv.c"
"${BACNET_SRC_ROOT}/bacnet/basic/service/h_apdu.c"
"${BACNET_SRC_ROOT}/bacnet/basic/service/h_cov.c"
@@ -9,11 +9,15 @@ extern "C" {
typedef enum gateway_bacnet_object_kind {
GW_BACNET_OBJECT_UNKNOWN = 0,
GW_BACNET_OBJECT_ANALOG_INPUT,
GW_BACNET_OBJECT_ANALOG_VALUE,
GW_BACNET_OBJECT_ANALOG_OUTPUT,
GW_BACNET_OBJECT_BINARY_INPUT,
GW_BACNET_OBJECT_BINARY_VALUE,
GW_BACNET_OBJECT_BINARY_OUTPUT,
GW_BACNET_OBJECT_MULTI_STATE_INPUT,
GW_BACNET_OBJECT_MULTI_STATE_VALUE,
GW_BACNET_OBJECT_MULTI_STATE_OUTPUT,
} gateway_bacnet_object_kind_t;
typedef enum gateway_bacnet_write_value_kind {
@@ -42,16 +42,32 @@ GatewayBacnetServer* g_server = nullptr;
gateway_bacnet_object_kind_t ToBacnetKind(BridgeObjectType type) {
switch (type) {
case BridgeObjectType::analogInput:
return GW_BACNET_OBJECT_ANALOG_INPUT;
case BridgeObjectType::analogValue:
return GW_BACNET_OBJECT_ANALOG_VALUE;
case BridgeObjectType::analogOutput:
return GW_BACNET_OBJECT_ANALOG_OUTPUT;
case BridgeObjectType::binaryInput:
return GW_BACNET_OBJECT_BINARY_INPUT;
case BridgeObjectType::binaryValue:
return GW_BACNET_OBJECT_BINARY_VALUE;
case BridgeObjectType::binaryOutput:
return GW_BACNET_OBJECT_BINARY_OUTPUT;
case BridgeObjectType::multiStateInput:
return GW_BACNET_OBJECT_MULTI_STATE_INPUT;
case BridgeObjectType::multiStateValue:
return GW_BACNET_OBJECT_MULTI_STATE_VALUE;
case BridgeObjectType::multiStateOutput:
return GW_BACNET_OBJECT_MULTI_STATE_OUTPUT;
case BridgeObjectType::holdingRegister:
return GW_BACNET_OBJECT_ANALOG_VALUE;
case BridgeObjectType::inputRegister:
return GW_BACNET_OBJECT_ANALOG_INPUT;
case BridgeObjectType::coil:
return GW_BACNET_OBJECT_BINARY_OUTPUT;
case BridgeObjectType::discreteInput:
return GW_BACNET_OBJECT_BINARY_INPUT;
default:
return GW_BACNET_OBJECT_UNKNOWN;
}
@@ -59,16 +75,24 @@ gateway_bacnet_object_kind_t ToBacnetKind(BridgeObjectType type) {
BridgeObjectType FromBacnetKind(gateway_bacnet_object_kind_t kind) {
switch (kind) {
case GW_BACNET_OBJECT_ANALOG_INPUT:
return BridgeObjectType::analogInput;
case GW_BACNET_OBJECT_ANALOG_VALUE:
return BridgeObjectType::analogValue;
case GW_BACNET_OBJECT_ANALOG_OUTPUT:
return BridgeObjectType::analogOutput;
case GW_BACNET_OBJECT_BINARY_INPUT:
return BridgeObjectType::binaryInput;
case GW_BACNET_OBJECT_BINARY_VALUE:
return BridgeObjectType::binaryValue;
case GW_BACNET_OBJECT_BINARY_OUTPUT:
return BridgeObjectType::binaryOutput;
case GW_BACNET_OBJECT_MULTI_STATE_INPUT:
return BridgeObjectType::multiStateInput;
case GW_BACNET_OBJECT_MULTI_STATE_VALUE:
return BridgeObjectType::multiStateValue;
case GW_BACNET_OBJECT_MULTI_STATE_OUTPUT:
return BridgeObjectType::multiStateOutput;
default:
return BridgeObjectType::unknown;
}
@@ -5,11 +5,15 @@
#include "bacnet/apdu.h"
#include "bacnet/basic/binding/address.h"
#include "bacnet/basic/object/ai.h"
#include "bacnet/basic/object/ao.h"
#include "bacnet/basic/object/av.h"
#include "bacnet/basic/object/bi.h"
#include "bacnet/basic/object/bo.h"
#include "bacnet/basic/object/bv.h"
#include "bacnet/basic/object/device.h"
#include "bacnet/basic/object/ms-input.h"
#include "bacnet/basic/object/mso.h"
#include "bacnet/basic/object/msv.h"
#include "bacnet/basic/service/h_apdu.h"
#include "bacnet/basic/services.h"
@@ -89,6 +93,46 @@ static bool clear_multistate_value_objects(void)
return true;
}
static bool clear_analog_input_objects(void)
{
unsigned count = Analog_Input_Count();
while (count > 0) {
count--;
Analog_Input_Delete(Analog_Input_Index_To_Instance(count));
}
return true;
}
static bool clear_binary_input_objects(void)
{
unsigned count = Binary_Input_Count();
while (count > 0) {
count--;
Binary_Input_Delete(Binary_Input_Index_To_Instance(count));
}
return true;
}
static bool clear_multistate_input_objects(void)
{
unsigned count = Multistate_Input_Count();
while (count > 0) {
count--;
Multistate_Input_Delete(Multistate_Input_Index_To_Instance(count));
}
return true;
}
static bool clear_multistate_output_objects(void)
{
unsigned count = Multistate_Output_Count();
while (count > 0) {
count--;
Multistate_Output_Delete(Multistate_Output_Index_To_Instance(count));
}
return true;
}
static void set_analog_value_state(
uint32_t object_instance, bool out_of_service, BACNET_RELIABILITY reliability)
{
@@ -124,6 +168,34 @@ static void set_multistate_value_state(
Multistate_Value_Reliability_Set(object_instance, reliability);
}
static void set_analog_input_state(
uint32_t object_instance, bool out_of_service, BACNET_RELIABILITY reliability)
{
Analog_Input_Out_Of_Service_Set(object_instance, out_of_service);
Analog_Input_Reliability_Set(object_instance, reliability);
}
static void set_binary_input_state(
uint32_t object_instance, bool out_of_service, BACNET_RELIABILITY reliability)
{
Binary_Input_Out_Of_Service_Set(object_instance, out_of_service);
Binary_Input_Reliability_Set(object_instance, reliability);
}
static void set_multistate_input_state(
uint32_t object_instance, bool out_of_service, BACNET_RELIABILITY reliability)
{
Multistate_Input_Out_Of_Service_Set(object_instance, out_of_service);
Multistate_Input_Reliability_Set(object_instance, reliability);
}
static void set_multistate_output_state(
uint32_t object_instance, bool out_of_service, BACNET_RELIABILITY reliability)
{
Multistate_Output_Out_Of_Service_Set(object_instance, out_of_service);
Multistate_Output_Reliability_Set(object_instance, reliability);
}
static void notify_write_real(
gateway_bacnet_object_kind_t object_kind, uint32_t object_instance, double value)
{
@@ -198,6 +270,25 @@ static void multistate_value_write(uint32_t object_instance, uint32_t old_value,
notify_write_unsigned(GW_BACNET_OBJECT_MULTI_STATE_VALUE, object_instance, value);
}
static void binary_input_write(
uint32_t object_instance, BACNET_BINARY_PV old_value, BACNET_BINARY_PV value)
{
(void)old_value;
notify_write_boolean(GW_BACNET_OBJECT_BINARY_INPUT, object_instance, value == BINARY_ACTIVE);
}
static void multistate_input_write(uint32_t object_instance, uint32_t old_value, uint32_t value)
{
(void)old_value;
notify_write_unsigned(GW_BACNET_OBJECT_MULTI_STATE_INPUT, object_instance, value);
}
static void multistate_output_write(uint32_t object_instance, uint32_t old_value, uint32_t value)
{
(void)old_value;
notify_write_unsigned(GW_BACNET_OBJECT_MULTI_STATE_OUTPUT, object_instance, value);
}
static object_functions_t Object_Table[] = {
{ OBJECT_DEVICE, NULL, Device_Count, Device_Index_To_Instance,
Device_Valid_Object_Instance_Number, Device_Object_Name, Device_Read_Property_Local,
@@ -234,6 +325,32 @@ static object_functions_t Object_Table[] = {
Multistate_Value_Encode_Value_List, Multistate_Value_Change_Of_Value,
Multistate_Value_Change_Of_Value_Clear, NULL, NULL, NULL, Multistate_Value_Create,
Multistate_Value_Delete, NULL, Multistate_Value_Writable_Property_List },
{ OBJECT_ANALOG_INPUT, Analog_Input_Init, Analog_Input_Count,
Analog_Input_Index_To_Instance, Analog_Input_Valid_Instance, Analog_Input_Object_Name,
Analog_Input_Read_Property, Analog_Input_Write_Property, Analog_Input_Property_Lists,
NULL, NULL, Analog_Input_Encode_Value_List, Analog_Input_Change_Of_Value,
Analog_Input_Change_Of_Value_Clear, NULL, NULL, NULL, Analog_Input_Create,
Analog_Input_Delete, NULL, Analog_Input_Writable_Property_List },
{ OBJECT_BINARY_INPUT, Binary_Input_Init, Binary_Input_Count,
Binary_Input_Index_To_Instance, Binary_Input_Valid_Instance, Binary_Input_Object_Name,
Binary_Input_Read_Property, Binary_Input_Write_Property, Binary_Input_Property_Lists,
NULL, NULL, Binary_Input_Encode_Value_List, Binary_Input_Change_Of_Value,
Binary_Input_Change_Of_Value_Clear, NULL, NULL, NULL, Binary_Input_Create,
Binary_Input_Delete, NULL, Binary_Input_Writable_Property_List },
{ OBJECT_MULTI_STATE_INPUT, Multistate_Input_Init, Multistate_Input_Count,
Multistate_Input_Index_To_Instance, Multistate_Input_Valid_Instance,
Multistate_Input_Object_Name, Multistate_Input_Read_Property,
Multistate_Input_Write_Property, Multistate_Input_Property_Lists, NULL, NULL,
Multistate_Input_Encode_Value_List, Multistate_Input_Change_Of_Value,
Multistate_Input_Change_Of_Value_Clear, NULL, NULL, NULL, Multistate_Input_Create,
Multistate_Input_Delete, NULL, Multistate_Input_Writable_Property_List },
{ OBJECT_MULTI_STATE_OUTPUT, Multistate_Output_Init, Multistate_Output_Count,
Multistate_Output_Index_To_Instance, Multistate_Output_Valid_Instance,
Multistate_Output_Object_Name, Multistate_Output_Read_Property,
Multistate_Output_Write_Property, Multistate_Output_Property_Lists, NULL, NULL,
Multistate_Output_Encode_Value_List, Multistate_Output_Change_Of_Value,
Multistate_Output_Change_Of_Value_Clear, NULL, NULL, NULL, Multistate_Output_Create,
Multistate_Output_Delete, NULL, Multistate_Output_Writable_Property_List },
{ MAX_BACNET_OBJECT_TYPE, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
};
@@ -269,6 +386,9 @@ bool gateway_bacnet_stack_start(
Binary_Value_Write_Present_Value_Callback_Set(binary_value_write);
Binary_Output_Write_Present_Value_Callback_Set(binary_output_write);
Multistate_Value_Write_Present_Value_Callback_Set(multistate_value_write);
Binary_Input_Write_Present_Value_Callback_Set(binary_input_write);
Multistate_Input_Write_Present_Value_Callback_Set(multistate_input_write);
Multistate_Output_Write_Present_Value_Callback_Set(multistate_output_write);
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
@@ -358,6 +478,45 @@ bool gateway_bacnet_stack_upsert_object(
Multistate_Value_Present_Value_Set(object_instance, 1);
set_multistate_value_state(object_instance, out_of_service, object_reliability);
return true;
case GW_BACNET_OBJECT_ANALOG_INPUT:
if (!Analog_Input_Valid_Instance(object_instance)) {
Analog_Input_Create(object_instance);
}
Analog_Input_Name_Set(object_instance, object_name);
Analog_Input_Description_Set(object_instance, description);
Analog_Input_Units_Set(object_instance, UNITS_PERCENT);
Analog_Input_Present_Value_Set(object_instance, 0.0f);
set_analog_input_state(object_instance, out_of_service, object_reliability);
return true;
case GW_BACNET_OBJECT_BINARY_INPUT:
if (!Binary_Input_Valid_Instance(object_instance)) {
Binary_Input_Create(object_instance);
}
Binary_Input_Name_Set(object_instance, object_name);
Binary_Input_Description_Set(object_instance, description);
Binary_Input_Present_Value_Set(object_instance, BINARY_INACTIVE);
set_binary_input_state(object_instance, out_of_service, object_reliability);
return true;
case GW_BACNET_OBJECT_MULTI_STATE_INPUT:
if (!Multistate_Input_Valid_Instance(object_instance)) {
Multistate_Input_Create(object_instance);
}
Multistate_Input_Name_Set(object_instance, object_name);
Multistate_Input_Description_Set(object_instance, description);
Multistate_Input_State_Text_List_Set(object_instance, Multistate_Value_States);
Multistate_Input_Present_Value_Set(object_instance, 1);
set_multistate_input_state(object_instance, out_of_service, object_reliability);
return true;
case GW_BACNET_OBJECT_MULTI_STATE_OUTPUT:
if (!Multistate_Output_Valid_Instance(object_instance)) {
Multistate_Output_Create(object_instance);
}
Multistate_Output_Name_Set(object_instance, object_name);
Multistate_Output_Description_Set(object_instance, description);
Multistate_Output_State_Text_List_Set(object_instance, Multistate_Value_States);
Multistate_Output_Present_Value_Set(object_instance, 1, BACNET_MAX_PRIORITY);
set_multistate_output_state(object_instance, out_of_service, object_reliability);
return true;
default:
return false;
}
@@ -367,9 +526,13 @@ bool gateway_bacnet_stack_clear_objects(void)
{
return clear_analog_value_objects() &&
clear_analog_output_objects() &&
clear_analog_input_objects() &&
clear_binary_value_objects() &&
clear_binary_output_objects() &&
clear_multistate_value_objects();
clear_binary_input_objects() &&
clear_multistate_value_objects() &&
clear_multistate_input_objects() &&
clear_multistate_output_objects();
}
void gateway_bacnet_stack_send_i_am(void)