Files
gateway/components/gateway_bacnet/src/gateway_bacnet_stack_port.c
T
Tony 7424b43bdd Add diagnostic bit support to Gateway Modbus
- Introduced new enum value `kShortDiagnosticBit` to `GatewayModbusGeneratedKind`.
- Enhanced `GatewayModbusPoint` and `GatewayModbusPointBinding` structures to include diagnostic snapshot, boolean key, and device type.
- Added new diagnostic bit specifications and updated the corresponding arrays for generated discrete inputs and holding registers.
- Implemented `addGeneratedDiagnosticPoint` function to handle the creation of diagnostic points.
- Updated `rebuildMap` method to include generated diagnostic points during the map rebuilding process.

Co-authored-by: Copilot <copilot@github.com>
2026-05-04 02:26:09 +08:00

639 lines
26 KiB
C

#include "gateway_bacnet_stack_port.h"
#include <stddef.h>
#include <string.h>
#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"
#include "bacnet/basic/tsm/tsm.h"
#include "bacnet/bacdef.h"
#include "bacnet/npdu.h"
#include "bip.h"
static gateway_bacnet_stack_write_callback_t Write_Callback;
static void* Write_Callback_Context;
static uint8_t Rx_Buffer[BIP_MPDU_MAX];
static const char Multistate_Value_States[] =
"State 1\0"
"State 2\0"
"State 3\0"
"State 4\0"
"State 5\0"
"State 6\0"
"State 7\0"
"State 8\0"
"State 9\0"
"State 10\0"
"State 11\0"
"State 12\0"
"State 13\0"
"State 14\0"
"State 15\0"
"State 16\0";
static bool clear_analog_value_objects(void)
{
unsigned count = Analog_Value_Count();
while (count > 0) {
count--;
Analog_Value_Delete(Analog_Value_Index_To_Instance(count));
}
return true;
}
static bool clear_analog_output_objects(void)
{
unsigned count = Analog_Output_Count();
while (count > 0) {
count--;
Analog_Output_Delete(Analog_Output_Index_To_Instance(count));
}
return true;
}
static bool clear_binary_value_objects(void)
{
unsigned count = Binary_Value_Count();
while (count > 0) {
count--;
Binary_Value_Delete(Binary_Value_Index_To_Instance(count));
}
return true;
}
static bool clear_binary_output_objects(void)
{
unsigned count = Binary_Output_Count();
while (count > 0) {
count--;
Binary_Output_Delete(Binary_Output_Index_To_Instance(count));
}
return true;
}
static bool clear_multistate_value_objects(void)
{
unsigned count = Multistate_Value_Count();
while (count > 0) {
count--;
Multistate_Value_Delete(Multistate_Value_Index_To_Instance(count));
}
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)
{
Analog_Value_Out_Of_Service_Set(object_instance, out_of_service);
Analog_Value_Reliability_Set(object_instance, reliability);
}
static void set_analog_output_state(
uint32_t object_instance, bool out_of_service, BACNET_RELIABILITY reliability)
{
Analog_Output_Out_Of_Service_Set(object_instance, out_of_service);
Analog_Output_Reliability_Set(object_instance, reliability);
}
static void set_binary_value_state(
uint32_t object_instance, bool out_of_service, BACNET_RELIABILITY reliability)
{
Binary_Value_Out_Of_Service_Set(object_instance, out_of_service);
Binary_Value_Reliability_Set(object_instance, reliability);
}
static void set_binary_output_state(
uint32_t object_instance, bool out_of_service, BACNET_RELIABILITY reliability)
{
Binary_Output_Out_Of_Service_Set(object_instance, out_of_service);
Binary_Output_Reliability_Set(object_instance, reliability);
}
static void set_multistate_value_state(
uint32_t object_instance, bool out_of_service, BACNET_RELIABILITY reliability)
{
Multistate_Value_Out_Of_Service_Set(object_instance, out_of_service);
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)
{
if (Write_Callback) {
gateway_bacnet_write_value_t write_value = {
.kind = GW_BACNET_WRITE_VALUE_REAL,
.real_value = value,
.boolean_value = false,
.unsigned_value = 0,
};
Write_Callback(object_kind, object_instance, &write_value, Write_Callback_Context);
}
}
static void notify_write_boolean(
gateway_bacnet_object_kind_t object_kind, uint32_t object_instance, bool value)
{
if (Write_Callback) {
gateway_bacnet_write_value_t write_value = {
.kind = GW_BACNET_WRITE_VALUE_BOOLEAN,
.real_value = 0.0,
.boolean_value = value,
.unsigned_value = 0,
};
Write_Callback(object_kind, object_instance, &write_value, Write_Callback_Context);
}
}
static void notify_write_unsigned(
gateway_bacnet_object_kind_t object_kind, uint32_t object_instance, uint32_t value)
{
if (Write_Callback) {
gateway_bacnet_write_value_t write_value = {
.kind = GW_BACNET_WRITE_VALUE_UNSIGNED,
.real_value = 0.0,
.boolean_value = false,
.unsigned_value = value,
};
Write_Callback(object_kind, object_instance, &write_value, Write_Callback_Context);
}
}
static void analog_value_write(uint32_t object_instance, float old_value, float value)
{
(void)old_value;
notify_write_real(GW_BACNET_OBJECT_ANALOG_VALUE, object_instance, value);
}
static void analog_output_write(uint32_t object_instance, float old_value, float value)
{
(void)old_value;
notify_write_real(GW_BACNET_OBJECT_ANALOG_OUTPUT, object_instance, value);
}
static void binary_value_write(
uint32_t object_instance, BACNET_BINARY_PV old_value, BACNET_BINARY_PV value)
{
(void)old_value;
notify_write_boolean(GW_BACNET_OBJECT_BINARY_VALUE, object_instance, value == BINARY_ACTIVE);
}
static void binary_output_write(
uint32_t object_instance, BACNET_BINARY_PV old_value, BACNET_BINARY_PV value)
{
(void)old_value;
notify_write_boolean(GW_BACNET_OBJECT_BINARY_OUTPUT, object_instance, value == BINARY_ACTIVE);
}
static void multistate_value_write(uint32_t object_instance, uint32_t old_value, uint32_t value)
{
(void)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,
Device_Write_Property_Local, Device_Property_Lists, DeviceGetRRInfo, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, Device_Writable_Property_List },
{ OBJECT_ANALOG_VALUE, Analog_Value_Init, Analog_Value_Count,
Analog_Value_Index_To_Instance, Analog_Value_Valid_Instance, Analog_Value_Object_Name,
Analog_Value_Read_Property, Analog_Value_Write_Property, Analog_Value_Property_Lists,
NULL, NULL, Analog_Value_Encode_Value_List, Analog_Value_Change_Of_Value,
Analog_Value_Change_Of_Value_Clear, NULL, NULL, NULL, Analog_Value_Create,
Analog_Value_Delete, NULL, Analog_Value_Writable_Property_List },
{ OBJECT_ANALOG_OUTPUT, Analog_Output_Init, Analog_Output_Count,
Analog_Output_Index_To_Instance, Analog_Output_Valid_Instance, Analog_Output_Object_Name,
Analog_Output_Read_Property, Analog_Output_Write_Property, Analog_Output_Property_Lists,
NULL, NULL, Analog_Output_Encode_Value_List, Analog_Output_Change_Of_Value,
Analog_Output_Change_Of_Value_Clear, NULL, NULL, NULL, Analog_Output_Create,
Analog_Output_Delete, NULL, Analog_Output_Writable_Property_List },
{ OBJECT_BINARY_VALUE, Binary_Value_Init, Binary_Value_Count,
Binary_Value_Index_To_Instance, Binary_Value_Valid_Instance, Binary_Value_Object_Name,
Binary_Value_Read_Property, Binary_Value_Write_Property, Binary_Value_Property_Lists,
NULL, NULL, Binary_Value_Encode_Value_List, Binary_Value_Change_Of_Value,
Binary_Value_Change_Of_Value_Clear, NULL, NULL, NULL, Binary_Value_Create,
Binary_Value_Delete, NULL, Binary_Value_Writable_Property_List },
{ OBJECT_BINARY_OUTPUT, Binary_Output_Init, Binary_Output_Count,
Binary_Output_Index_To_Instance, Binary_Output_Valid_Instance, Binary_Output_Object_Name,
Binary_Output_Read_Property, Binary_Output_Write_Property, Binary_Output_Property_Lists,
NULL, NULL, Binary_Output_Encode_Value_List, Binary_Output_Change_Of_Value,
Binary_Output_Change_Of_Value_Clear, NULL, NULL, NULL, Binary_Output_Create,
Binary_Output_Delete, NULL, Binary_Output_Writable_Property_List },
{ OBJECT_MULTI_STATE_VALUE, Multistate_Value_Init, Multistate_Value_Count,
Multistate_Value_Index_To_Instance, Multistate_Value_Valid_Instance,
Multistate_Value_Object_Name, Multistate_Value_Read_Property,
Multistate_Value_Write_Property, Multistate_Value_Property_Lists, NULL, NULL,
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 },
};
bool gateway_bacnet_stack_start(
uint32_t device_instance,
const char* device_name,
uint16_t udp_port,
gateway_bacnet_stack_write_callback_t write_callback,
void* callback_context)
{
if (!device_name || device_name[0] == '\0') {
device_name = "DALI Gateway";
}
if (udp_port == 0) {
udp_port = 47808;
}
Write_Callback = write_callback;
Write_Callback_Context = callback_context;
address_init();
Device_Set_Object_Instance_Number(device_instance);
Device_Init(Object_Table);
Device_Object_Name_ANSI_Init(device_name);
Device_Set_Vendor_Name("TonyCloud", strlen("TonyCloud"));
Device_Set_Vendor_Identifier(260);
Device_Set_Model_Name("DALI Gateway", strlen("DALI Gateway"));
Device_Set_Description("DALI BACnet/IP bridge", strlen("DALI BACnet/IP bridge"));
Analog_Value_Write_Present_Value_Callback_Set(analog_value_write);
Analog_Output_Write_Present_Value_Callback_Set(analog_output_write);
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);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_HAS, handler_who_has);
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_DEVICE_COMMUNICATION_CONTROL, handler_device_communication_control);
return bip_init(udp_port);
}
void gateway_bacnet_stack_cleanup(void)
{
bip_cleanup();
Write_Callback = NULL;
Write_Callback_Context = NULL;
}
bool gateway_bacnet_stack_upsert_object(
gateway_bacnet_object_kind_t object_kind,
uint32_t object_instance,
const char* object_name,
const char* description,
bool out_of_service,
uint32_t reliability)
{
if (!object_name || object_name[0] == '\0') {
object_name = "DALI BACnet Object";
}
if (!description) {
description = "";
}
BACNET_RELIABILITY object_reliability = (BACNET_RELIABILITY)reliability;
switch (object_kind) {
case GW_BACNET_OBJECT_ANALOG_VALUE:
if (!Analog_Value_Valid_Instance(object_instance)) {
Analog_Value_Create(object_instance);
}
Analog_Value_Name_Set(object_instance, object_name);
Analog_Value_Description_Set(object_instance, description);
Analog_Value_Units_Set(object_instance, UNITS_PERCENT);
Analog_Value_Present_Value_Set(object_instance, 0.0f, BACNET_NO_PRIORITY);
set_analog_value_state(object_instance, out_of_service, object_reliability);
return true;
case GW_BACNET_OBJECT_ANALOG_OUTPUT:
if (!Analog_Output_Valid_Instance(object_instance)) {
Analog_Output_Create(object_instance);
}
Analog_Output_Name_Set(object_instance, object_name);
Analog_Output_Description_Set(object_instance, description);
Analog_Output_Units_Set(object_instance, UNITS_PERCENT);
Analog_Output_Present_Value_Set(object_instance, 0.0f, BACNET_MAX_PRIORITY);
set_analog_output_state(object_instance, out_of_service, object_reliability);
return true;
case GW_BACNET_OBJECT_BINARY_VALUE:
if (!Binary_Value_Valid_Instance(object_instance)) {
Binary_Value_Create(object_instance);
}
Binary_Value_Name_Set(object_instance, object_name);
Binary_Value_Description_Set(object_instance, description);
Binary_Value_Write_Enable(object_instance);
Binary_Value_Present_Value_Set(object_instance, BINARY_INACTIVE);
set_binary_value_state(object_instance, out_of_service, object_reliability);
return true;
case GW_BACNET_OBJECT_BINARY_OUTPUT:
if (!Binary_Output_Valid_Instance(object_instance)) {
Binary_Output_Create(object_instance);
}
Binary_Output_Name_Set(object_instance, object_name);
Binary_Output_Description_Set(object_instance, description);
Binary_Output_Present_Value_Set(object_instance, BINARY_INACTIVE, BACNET_MAX_PRIORITY);
set_binary_output_state(object_instance, out_of_service, object_reliability);
return true;
case GW_BACNET_OBJECT_MULTI_STATE_VALUE:
if (!Multistate_Value_Valid_Instance(object_instance)) {
Multistate_Value_Create(object_instance);
}
Multistate_Value_Name_Set(object_instance, object_name);
Multistate_Value_Description_Set(object_instance, description);
Multistate_Value_State_Text_List_Set(object_instance, Multistate_Value_States);
Multistate_Value_Write_Enable(object_instance);
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;
}
}
bool gateway_bacnet_stack_set_object_state(
gateway_bacnet_object_kind_t object_kind,
uint32_t object_instance,
bool out_of_service,
uint32_t reliability)
{
BACNET_RELIABILITY object_reliability = (BACNET_RELIABILITY)reliability;
switch (object_kind) {
case GW_BACNET_OBJECT_ANALOG_VALUE:
set_analog_value_state(object_instance, out_of_service, object_reliability);
return true;
case GW_BACNET_OBJECT_ANALOG_OUTPUT:
set_analog_output_state(object_instance, out_of_service, object_reliability);
return true;
case GW_BACNET_OBJECT_BINARY_VALUE:
set_binary_value_state(object_instance, out_of_service, object_reliability);
return true;
case GW_BACNET_OBJECT_BINARY_OUTPUT:
set_binary_output_state(object_instance, out_of_service, object_reliability);
return true;
case GW_BACNET_OBJECT_MULTI_STATE_VALUE:
set_multistate_value_state(object_instance, out_of_service, object_reliability);
return true;
case GW_BACNET_OBJECT_ANALOG_INPUT:
set_analog_input_state(object_instance, out_of_service, object_reliability);
return true;
case GW_BACNET_OBJECT_BINARY_INPUT:
set_binary_input_state(object_instance, out_of_service, object_reliability);
return true;
case GW_BACNET_OBJECT_MULTI_STATE_INPUT:
set_multistate_input_state(object_instance, out_of_service, object_reliability);
return true;
case GW_BACNET_OBJECT_MULTI_STATE_OUTPUT:
set_multistate_output_state(object_instance, out_of_service, object_reliability);
return true;
default:
return false;
}
}
bool gateway_bacnet_stack_set_present_value(
gateway_bacnet_object_kind_t object_kind,
uint32_t object_instance,
const gateway_bacnet_write_value_t* value)
{
if (!value) {
return false;
}
switch (object_kind) {
case GW_BACNET_OBJECT_ANALOG_VALUE:
return Analog_Value_Present_Value_Set(
object_instance, (float)value->real_value, BACNET_NO_PRIORITY);
case GW_BACNET_OBJECT_ANALOG_OUTPUT:
return Analog_Output_Present_Value_Set(
object_instance, (float)value->real_value, BACNET_MAX_PRIORITY);
case GW_BACNET_OBJECT_ANALOG_INPUT:
Analog_Input_Present_Value_Set(object_instance, (float)value->real_value);
return true;
case GW_BACNET_OBJECT_BINARY_VALUE:
return Binary_Value_Present_Value_Set(
object_instance, value->boolean_value ? BINARY_ACTIVE : BINARY_INACTIVE);
case GW_BACNET_OBJECT_BINARY_OUTPUT:
return Binary_Output_Present_Value_Set(
object_instance, value->boolean_value ? BINARY_ACTIVE : BINARY_INACTIVE,
BACNET_MAX_PRIORITY);
case GW_BACNET_OBJECT_BINARY_INPUT:
return Binary_Input_Present_Value_Set(
object_instance, value->boolean_value ? BINARY_ACTIVE : BINARY_INACTIVE);
case GW_BACNET_OBJECT_MULTI_STATE_VALUE:
return Multistate_Value_Present_Value_Set(
object_instance, value->unsigned_value == 0 ? 1 : value->unsigned_value);
case GW_BACNET_OBJECT_MULTI_STATE_OUTPUT:
return Multistate_Output_Present_Value_Set(
object_instance, value->unsigned_value == 0 ? 1 : value->unsigned_value,
BACNET_MAX_PRIORITY);
case GW_BACNET_OBJECT_MULTI_STATE_INPUT:
return Multistate_Input_Present_Value_Set(
object_instance, value->unsigned_value == 0 ? 1 : value->unsigned_value);
default:
return false;
}
}
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_binary_input_objects() &&
clear_multistate_value_objects() &&
clear_multistate_input_objects() &&
clear_multistate_output_objects();
}
void gateway_bacnet_stack_send_i_am(void)
{
Send_I_Am(&Handler_Transmit_Buffer[0]);
}
void gateway_bacnet_stack_poll(uint16_t elapsed_ms)
{
BACNET_ADDRESS src = { 0 };
uint16_t pdu_len = bip_receive(&src, Rx_Buffer, sizeof(Rx_Buffer), 0);
if (pdu_len > 0) {
npdu_handler(&src, Rx_Buffer, pdu_len);
}
if (elapsed_ms > 0) {
tsm_timer_milliseconds(elapsed_ms);
Device_Timer(elapsed_ms);
}
}