Fixed network port object to accept host name option of host-n-port writes. (#997)
This commit is contained in:
+427
-113
@@ -18,6 +18,7 @@
|
||||
#include "bacnet/bacapp.h"
|
||||
#include "bacnet/bacint.h"
|
||||
#include "bacnet/bacdcode.h"
|
||||
#include "bacnet/datetime.h"
|
||||
#include "bacnet/npdu.h"
|
||||
#include "bacnet/apdu.h"
|
||||
#include "bacnet/datalink/bvlc.h"
|
||||
@@ -33,26 +34,26 @@
|
||||
#define BBMD_ENABLED 1
|
||||
#endif
|
||||
|
||||
#define IPV4_ADDR_SIZE 4
|
||||
#define BIP_DNS_MAX 3
|
||||
struct bacnet_ipv4_port {
|
||||
uint8_t IP_Address[4];
|
||||
uint8_t IP_Address[IPV4_ADDR_SIZE];
|
||||
uint8_t IP_Subnet_Prefix;
|
||||
uint8_t IP_Gateway[4];
|
||||
uint8_t IP_DNS_Server[BIP_DNS_MAX][4];
|
||||
uint8_t IP_Gateway[IPV4_ADDR_SIZE];
|
||||
uint8_t IP_DNS_Server[BIP_DNS_MAX][IPV4_ADDR_SIZE];
|
||||
uint16_t Port;
|
||||
BACNET_IP_MODE Mode;
|
||||
bool IP_DHCP_Enable;
|
||||
uint32_t IP_DHCP_Lease_Seconds;
|
||||
uint32_t IP_DHCP_Lease_Seconds_Remaining;
|
||||
uint8_t IP_DHCP_Server[4];
|
||||
uint32_t IP_DHCP_Lease_Seconds_Start;
|
||||
uint8_t IP_DHCP_Server[IPV4_ADDR_SIZE];
|
||||
bool IP_NAT_Traversal;
|
||||
uint32_t IP_Global_Address[4];
|
||||
uint32_t IP_Global_Address[IPV4_ADDR_SIZE];
|
||||
bool BBMD_Accept_FD_Registrations;
|
||||
void *BBMD_BD_Table;
|
||||
void *BBMD_FD_Table;
|
||||
/* used for foreign device registration to remote BBMD */
|
||||
uint8_t BBMD_IP_Address[4];
|
||||
uint16_t BBMD_Port;
|
||||
BACNET_HOST_N_PORT_MINIMAL BBMD_Address;
|
||||
uint16_t BBMD_Lifetime;
|
||||
};
|
||||
|
||||
@@ -65,17 +66,18 @@ struct bacnet_ipv6_port {
|
||||
uint8_t IP_Gateway[IPV6_ADDR_SIZE];
|
||||
uint8_t IP_DNS_Server[BIP_DNS_MAX][IPV6_ADDR_SIZE];
|
||||
uint8_t IP_Multicast_Address[IPV6_ADDR_SIZE];
|
||||
bool IP_DHCP_Enable;
|
||||
uint8_t IP_DHCP_Server[IPV6_ADDR_SIZE];
|
||||
uint32_t IP_DHCP_Lease_Seconds;
|
||||
uint32_t IP_DHCP_Lease_Seconds_Start;
|
||||
uint16_t Port;
|
||||
BACNET_IP_MODE Mode;
|
||||
bool Auto_Addressing_Enable;
|
||||
char Zone_Index[ZONE_INDEX_SIZE];
|
||||
bool BBMD_Accept_FD_Registrations;
|
||||
void *BBMD_BD_Table;
|
||||
void *BBMD_FD_Table;
|
||||
/* used for foreign device registration to remote BBMD */
|
||||
uint8_t BBMD_IP_Address[16];
|
||||
uint16_t BBMD_Port;
|
||||
BACNET_HOST_N_PORT_MINIMAL BBMD_Address;
|
||||
uint16_t BBMD_Lifetime;
|
||||
};
|
||||
|
||||
@@ -184,6 +186,9 @@ static const int BIP_Port_Properties_Optional[] = {
|
||||
PROP_IP_DNS_SERVER,
|
||||
#if defined(BACDL_BIP) && (BACNET_NETWORK_PORT_IP_DHCP_ENABLED)
|
||||
PROP_IP_DHCP_ENABLE,
|
||||
PROP_IP_DHCP_LEASE_TIME,
|
||||
PROP_IP_DHCP_LEASE_TIME_REMAINING,
|
||||
PROP_IP_DHCP_SERVER,
|
||||
#endif
|
||||
#if defined(BACDL_BIP) && (BBMD_ENABLED)
|
||||
PROP_BBMD_ACCEPT_FD_REGISTRATIONS,
|
||||
@@ -214,10 +219,12 @@ static const int BIP6_Port_Properties_Optional[] = {
|
||||
PROP_IPV6_DEFAULT_GATEWAY,
|
||||
PROP_BACNET_IPV6_MULTICAST_ADDRESS,
|
||||
PROP_IPV6_DNS_SERVER,
|
||||
#if defined(BACDL_BIP6) && (BACNET_NETWORK_PORT_IP_DHCP_ENABLED)
|
||||
PROP_IPV6_AUTO_ADDRESSING_ENABLE,
|
||||
PROP_IPV6_DHCP_LEASE_TIME,
|
||||
PROP_IPV6_DHCP_LEASE_TIME_REMAINING,
|
||||
PROP_IPV6_DHCP_SERVER,
|
||||
#endif
|
||||
PROP_IPV6_ZONE_INDEX,
|
||||
#if defined(BACDL_BIP6) && (BBMD_ENABLED)
|
||||
PROP_BBMD_ACCEPT_FD_REGISTRATIONS,
|
||||
@@ -1487,6 +1494,8 @@ bool Network_Port_IP_DHCP_Enable(uint32_t object_instance)
|
||||
if (index < BACNET_NETWORK_PORTS_MAX) {
|
||||
if (Object_List[index].Network_Type == PORT_TYPE_BIP) {
|
||||
dhcp_enable = Object_List[index].Network.IPv4.IP_DHCP_Enable;
|
||||
} else if (Object_List[index].Network_Type == PORT_TYPE_BIP6) {
|
||||
dhcp_enable = Object_List[index].Network.IPv6.IP_DHCP_Enable;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1509,8 +1518,17 @@ bool Network_Port_IP_DHCP_Enable_Set(uint32_t object_instance, bool value)
|
||||
index = Network_Port_Instance_To_Index(object_instance);
|
||||
if (index < BACNET_NETWORK_PORTS_MAX) {
|
||||
if (Object_List[index].Network_Type == PORT_TYPE_BIP) {
|
||||
if (Object_List[index].Network.IPv4.IP_DHCP_Enable != value) {
|
||||
Object_List[index].Changes_Pending = true;
|
||||
}
|
||||
Object_List[index].Network.IPv4.IP_DHCP_Enable = value;
|
||||
status = true;
|
||||
} else if (Object_List[index].Network_Type == PORT_TYPE_BIP6) {
|
||||
if (Object_List[index].Network.IPv6.IP_DHCP_Enable != value) {
|
||||
Object_List[index].Changes_Pending = true;
|
||||
}
|
||||
Object_List[index].Network.IPv6.IP_DHCP_Enable = value;
|
||||
status = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1602,11 +1620,19 @@ bool Network_Port_IP_DNS_Server_Set(
|
||||
{
|
||||
unsigned index = 0; /* offset from instance lookup */
|
||||
bool status = false;
|
||||
uint8_t *dns_server = NULL;
|
||||
|
||||
index = Network_Port_Instance_To_Index(object_instance);
|
||||
if (index < BACNET_NETWORK_PORTS_MAX) {
|
||||
if (Object_List[index].Network_Type == PORT_TYPE_BIP) {
|
||||
if (dns_index < BIP_DNS_MAX) {
|
||||
dns_server = &Object_List[index]
|
||||
.Network.IPv4.IP_DNS_Server[dns_index][0];
|
||||
if ((dns_server[0] != a) || (dns_server[1] != b) ||
|
||||
(dns_server[2] != c) || (dns_server[3] != d)) {
|
||||
/* octets are different, set changes pending */
|
||||
Object_List[index].Changes_Pending = true;
|
||||
}
|
||||
Object_List[index].Network.IPv4.IP_DNS_Server[dns_index][0] = a;
|
||||
Object_List[index].Network.IPv4.IP_DNS_Server[dns_index][1] = b;
|
||||
Object_List[index].Network.IPv4.IP_DNS_Server[dns_index][2] = c;
|
||||
@@ -1954,6 +1980,72 @@ static int BBMD_Foreign_Device_Table_Encode(
|
||||
return apdu_len;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief For a given object instance-number, gets the HostNPort
|
||||
* @note depends on Network_Type being set for this object
|
||||
* @param object_instance - object-instance number of the object
|
||||
* @param bbmd_address - BACNET_HOST_N_PORT structure
|
||||
* @return true if BBMD Address was copied
|
||||
*/
|
||||
bool Network_Port_Remote_BBMD_Address(
|
||||
uint32_t object_instance, BACNET_HOST_N_PORT *bbmd_address)
|
||||
{
|
||||
bool status = false;
|
||||
unsigned index;
|
||||
|
||||
index = Network_Port_Instance_To_Index(object_instance);
|
||||
if (index < BACNET_NETWORK_PORTS_MAX) {
|
||||
if (Object_List[index].Network_Type == PORT_TYPE_BIP) {
|
||||
status = host_n_port_from_minimal(
|
||||
bbmd_address, &Object_List[index].Network.IPv4.BBMD_Address);
|
||||
} else if (Object_List[index].Network_Type == PORT_TYPE_BIP6) {
|
||||
status = host_n_port_from_minimal(
|
||||
bbmd_address, &Object_List[index].Network.IPv6.BBMD_Address);
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief For a given object instance-number, sets the FD BBMD Address:
|
||||
* either as IP address or a hostname.
|
||||
* @note depends on Network_Type being set for this object
|
||||
* @param object_instance - object-instance number of the object
|
||||
* @param bbmd_address - BACNET_HOST_N_PORT FD_BBMD_Address
|
||||
* @return true if BBMD Address was set
|
||||
*/
|
||||
bool Network_Port_Remote_BBMD_Address_Set(
|
||||
uint32_t object_instance, const BACNET_HOST_N_PORT *bbmd_address)
|
||||
{
|
||||
bool status = false;
|
||||
BACNET_HOST_N_PORT_MINIMAL bbmd_address_minimal = { 0 };
|
||||
BACNET_HOST_N_PORT_MINIMAL *dest_bbmd_address = NULL;
|
||||
unsigned index;
|
||||
|
||||
index = Network_Port_Instance_To_Index(object_instance);
|
||||
if (index < BACNET_NETWORK_PORTS_MAX) {
|
||||
if (Object_List[index].Network_Type == PORT_TYPE_BIP) {
|
||||
dest_bbmd_address = &Object_List[index].Network.IPv4.BBMD_Address;
|
||||
} else if (Object_List[index].Network_Type == PORT_TYPE_BIP6) {
|
||||
dest_bbmd_address = &Object_List[index].Network.IPv6.BBMD_Address;
|
||||
}
|
||||
if (dest_bbmd_address) {
|
||||
status =
|
||||
host_n_port_to_minimal(&bbmd_address_minimal, bbmd_address);
|
||||
if (status) {
|
||||
if (!host_n_port_minimal_same(
|
||||
dest_bbmd_address, &bbmd_address_minimal)) {
|
||||
host_n_port_to_minimal(dest_bbmd_address, bbmd_address);
|
||||
Object_List[index].Changes_Pending = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given object instance-number, loads the ip-address into
|
||||
* an octet string.
|
||||
@@ -1972,23 +2064,27 @@ bool Network_Port_Remote_BBMD_IP_Address(
|
||||
{
|
||||
unsigned index = 0; /* offset from instance lookup */
|
||||
bool status = false;
|
||||
BACNET_HOST_N_PORT_MINIMAL *address;
|
||||
|
||||
index = Network_Port_Instance_To_Index(object_instance);
|
||||
if (index < BACNET_NETWORK_PORTS_MAX) {
|
||||
if (Object_List[index].Network_Type == PORT_TYPE_BIP) {
|
||||
if (a) {
|
||||
*a = Object_List[index].Network.IPv4.BBMD_IP_Address[0];
|
||||
address = &Object_List[index].Network.IPv4.BBMD_Address;
|
||||
if (address->tag == BACNET_HOST_ADDRESS_TAG_IP_ADDRESS) {
|
||||
if (a) {
|
||||
*a = address->host.ip_address.address[0];
|
||||
}
|
||||
if (b) {
|
||||
*b = address->host.ip_address.address[1];
|
||||
}
|
||||
if (c) {
|
||||
*c = address->host.ip_address.address[2];
|
||||
}
|
||||
if (d) {
|
||||
*d = address->host.ip_address.address[3];
|
||||
}
|
||||
status = true;
|
||||
}
|
||||
if (b) {
|
||||
*b = Object_List[index].Network.IPv4.BBMD_IP_Address[1];
|
||||
}
|
||||
if (c) {
|
||||
*c = Object_List[index].Network.IPv4.BBMD_IP_Address[2];
|
||||
}
|
||||
if (d) {
|
||||
*d = Object_List[index].Network.IPv4.BBMD_IP_Address[3];
|
||||
}
|
||||
status = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2012,21 +2108,25 @@ bool Network_Port_Remote_BBMD_IP_Address_Set(
|
||||
{
|
||||
unsigned index = 0; /* offset from instance lookup */
|
||||
bool status = false;
|
||||
BACNET_HOST_N_PORT_MINIMAL *address;
|
||||
|
||||
index = Network_Port_Instance_To_Index(object_instance);
|
||||
if (index < BACNET_NETWORK_PORTS_MAX) {
|
||||
if (Object_List[index].Network_Type == PORT_TYPE_BIP) {
|
||||
if ((Object_List[index].Network.IPv4.BBMD_IP_Address[0] != a) ||
|
||||
(Object_List[index].Network.IPv4.BBMD_IP_Address[1] != b) ||
|
||||
(Object_List[index].Network.IPv4.BBMD_IP_Address[2] != c) ||
|
||||
(Object_List[index].Network.IPv4.BBMD_IP_Address[3] != d)) {
|
||||
address = &Object_List[index].Network.IPv4.BBMD_Address;
|
||||
if ((address->host.ip_address.address[0] != a) ||
|
||||
(address->host.ip_address.address[1] != b) ||
|
||||
(address->host.ip_address.address[2] != c) ||
|
||||
(address->host.ip_address.address[3] != d) ||
|
||||
(address->tag != BACNET_HOST_ADDRESS_TAG_IP_ADDRESS)) {
|
||||
Object_List[index].Changes_Pending = true;
|
||||
}
|
||||
Object_List[index].Network.IPv4.BBMD_IP_Address[0] = a;
|
||||
Object_List[index].Network.IPv4.BBMD_IP_Address[1] = b;
|
||||
Object_List[index].Network.IPv4.BBMD_IP_Address[2] = c;
|
||||
Object_List[index].Network.IPv4.BBMD_IP_Address[3] = d;
|
||||
|
||||
address->host.ip_address.address[0] = a;
|
||||
address->host.ip_address.address[1] = b;
|
||||
address->host.ip_address.address[2] = c;
|
||||
address->host.ip_address.address[3] = d;
|
||||
address->host.ip_address.length = 4;
|
||||
address->tag = BACNET_HOST_ADDRESS_TAG_IP_ADDRESS;
|
||||
status = true;
|
||||
}
|
||||
}
|
||||
@@ -2050,7 +2150,7 @@ uint16_t Network_Port_Remote_BBMD_BIP_Port(uint32_t object_instance)
|
||||
index = Network_Port_Instance_To_Index(object_instance);
|
||||
if (index < BACNET_NETWORK_PORTS_MAX) {
|
||||
if (Object_List[index].Network_Type == PORT_TYPE_BIP) {
|
||||
value = Object_List[index].Network.IPv4.BBMD_Port;
|
||||
value = Object_List[index].Network.IPv4.BBMD_Address.port;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2075,10 +2175,10 @@ bool Network_Port_Remote_BBMD_BIP_Port_Set(
|
||||
index = Network_Port_Instance_To_Index(object_instance);
|
||||
if (index < BACNET_NETWORK_PORTS_MAX) {
|
||||
if (Object_List[index].Network_Type == PORT_TYPE_BIP) {
|
||||
if (Object_List[index].Network.IPv4.BBMD_Port != value) {
|
||||
if (Object_List[index].Network.IPv4.BBMD_Address.port != value) {
|
||||
Object_List[index].Changes_Pending = true;
|
||||
}
|
||||
Object_List[index].Network.IPv4.BBMD_Port = value;
|
||||
Object_List[index].Network.IPv4.BBMD_Address.port = value;
|
||||
status = true;
|
||||
}
|
||||
}
|
||||
@@ -2139,9 +2239,9 @@ bool Network_Port_Remote_BBMD_BIP_Lifetime_Set(
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the foreign device subscription lifetime
|
||||
* @brief Get the foreign device subscription lifetime seconds
|
||||
* @param object_instance [in] BACnet network port object instance number
|
||||
* @return foreign device subscription lifetime
|
||||
* @return foreign device subscription BBMD lifetime seconds
|
||||
*/
|
||||
static uint16_t Foreign_Device_Subscription_Lifetime(uint32_t object_instance)
|
||||
{
|
||||
@@ -2200,21 +2300,7 @@ bool Network_Port_BBMD_IP6_Accept_FD_Registrations(uint32_t object_instance)
|
||||
bool Network_Port_BBMD_IP6_Accept_FD_Registrations_Set(
|
||||
uint32_t object_instance, bool flag)
|
||||
{
|
||||
bool status = false;
|
||||
unsigned index = 0;
|
||||
struct bacnet_ipv6_port *ipv6 = NULL;
|
||||
|
||||
index = Network_Port_Instance_To_Index(object_instance);
|
||||
if (index < BACNET_NETWORK_PORTS_MAX) {
|
||||
ipv6 = &Object_List[index].Network.IPv6;
|
||||
if (flag != ipv6->BBMD_Accept_FD_Registrations) {
|
||||
ipv6->BBMD_Accept_FD_Registrations = flag;
|
||||
Object_List[index].Changes_Pending = true;
|
||||
}
|
||||
status = true;
|
||||
}
|
||||
|
||||
return status;
|
||||
return Network_Port_BBMD_Accept_FD_Registrations_Set(object_instance, flag);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2329,35 +2415,20 @@ bool Network_Port_BBMD_IP6_FD_Table_Set(
|
||||
* @param object_instance - object-instance number of the object
|
||||
* @param addr - holds the ip-address and port retrieved
|
||||
*
|
||||
* @return true if ip-address and port were retrieved
|
||||
* @return number of bytes encoded, or BACNET_STATUS_ERROR if error
|
||||
*/
|
||||
static int Foreign_Device_BBMD_Address_Encode(
|
||||
uint32_t object_instance, uint8_t *apdu, size_t apdu_size)
|
||||
{
|
||||
unsigned index = 0; /* offset from instance lookup */
|
||||
BACNET_IP_ADDRESS ip4_address;
|
||||
BACNET_IP6_ADDRESS ip6_address;
|
||||
int apdu_len = 0;
|
||||
BACNET_HOST_N_PORT bbmd_address = { 0 };
|
||||
|
||||
index = Network_Port_Instance_To_Index(object_instance);
|
||||
if (index < BACNET_NETWORK_PORTS_MAX) {
|
||||
if (Object_List[index].Network_Type == PORT_TYPE_BIP) {
|
||||
bvlc_address_set(
|
||||
&ip4_address,
|
||||
Object_List[index].Network.IPv4.BBMD_IP_Address[0],
|
||||
Object_List[index].Network.IPv4.BBMD_IP_Address[1],
|
||||
Object_List[index].Network.IPv4.BBMD_IP_Address[2],
|
||||
Object_List[index].Network.IPv4.BBMD_IP_Address[3]);
|
||||
ip4_address.port = Object_List[index].Network.IPv4.BBMD_Port;
|
||||
apdu_len = bvlc_foreign_device_bbmd_host_address_encode(
|
||||
apdu, apdu_size, &ip4_address);
|
||||
} else if (Object_List[index].Network_Type == PORT_TYPE_BIP6) {
|
||||
bvlc6_address_n_port_set(
|
||||
&ip6_address, Object_List[index].Network.IPv6.BBMD_IP_Address,
|
||||
Object_List[index].Network.IPv6.BBMD_Port);
|
||||
apdu_len = bvlc6_foreign_device_bbmd_host_address_encode(
|
||||
apdu, apdu_size, &ip6_address);
|
||||
}
|
||||
Network_Port_Remote_BBMD_Address(object_instance, &bbmd_address);
|
||||
apdu_len = host_n_port_encode(NULL, &bbmd_address);
|
||||
if (apdu_len > apdu_size) {
|
||||
apdu_len = BACNET_STATUS_ERROR;
|
||||
} else {
|
||||
apdu_len = host_n_port_encode(apdu, &bbmd_address);
|
||||
}
|
||||
|
||||
return apdu_len;
|
||||
@@ -2378,14 +2449,19 @@ bool Network_Port_Remote_BBMD_IP6_Address(
|
||||
{
|
||||
unsigned index = 0; /* offset from instance lookup */
|
||||
bool status = false;
|
||||
BACNET_HOST_N_PORT_MINIMAL *address;
|
||||
size_t i;
|
||||
|
||||
index = Network_Port_Instance_To_Index(object_instance);
|
||||
if (index < BACNET_NETWORK_PORTS_MAX) {
|
||||
if (Object_List[index].Network_Type == PORT_TYPE_BIP6) {
|
||||
if (addr) {
|
||||
memcpy(
|
||||
addr, Object_List[index].Network.IPv6.BBMD_IP_Address,
|
||||
IP6_ADDRESS_MAX);
|
||||
address = &Object_List[index].Network.IPv6.BBMD_Address;
|
||||
if (address->tag == BACNET_HOST_ADDRESS_TAG_IP_ADDRESS) {
|
||||
if (addr) {
|
||||
for (i = 0; i < IP6_ADDRESS_MAX; i++) {
|
||||
addr[i] = address->host.ip_address.address[i];
|
||||
}
|
||||
}
|
||||
status = true;
|
||||
}
|
||||
}
|
||||
@@ -2408,19 +2484,22 @@ bool Network_Port_Remote_BBMD_IP6_Address_Set(
|
||||
{
|
||||
unsigned index = 0; /* offset from instance lookup */
|
||||
bool status = false;
|
||||
BACNET_HOST_N_PORT_MINIMAL bbmd_address = { 0 };
|
||||
uint16_t port;
|
||||
|
||||
index = Network_Port_Instance_To_Index(object_instance);
|
||||
if (index < BACNET_NETWORK_PORTS_MAX) {
|
||||
if (Object_List[index].Network_Type == PORT_TYPE_BIP6) {
|
||||
if (memcmp(
|
||||
Object_List[index].Network.IPv6.BBMD_IP_Address, addr,
|
||||
IP6_ADDRESS_MAX)) {
|
||||
memcpy(
|
||||
Object_List[index].Network.IPv6.BBMD_IP_Address, addr,
|
||||
IP6_ADDRESS_MAX);
|
||||
port = Object_List[index].Network.IPv6.BBMD_Address.port;
|
||||
host_n_port_minimal_ip_init(
|
||||
&bbmd_address, port, addr, IP6_ADDRESS_MAX);
|
||||
if (!host_n_port_minimal_same(
|
||||
&Object_List[index].Network.IPv6.BBMD_Address,
|
||||
&bbmd_address)) {
|
||||
Object_List[index].Changes_Pending = true;
|
||||
}
|
||||
status = true;
|
||||
status = host_n_port_minimal_copy(
|
||||
&Object_List[index].Network.IPv6.BBMD_Address, &bbmd_address);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2443,7 +2522,7 @@ uint16_t Network_Port_Remote_BBMD_BIP6_Port(uint32_t object_instance)
|
||||
index = Network_Port_Instance_To_Index(object_instance);
|
||||
if (index < BACNET_NETWORK_PORTS_MAX) {
|
||||
if (Object_List[index].Network_Type == PORT_TYPE_BIP6) {
|
||||
value = Object_List[index].Network.IPv6.BBMD_Port;
|
||||
value = Object_List[index].Network.IPv6.BBMD_Address.port;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2468,10 +2547,10 @@ bool Network_Port_Remote_BBMD_BIP6_Port_Set(
|
||||
index = Network_Port_Instance_To_Index(object_instance);
|
||||
if (index < BACNET_NETWORK_PORTS_MAX) {
|
||||
if (Object_List[index].Network_Type == PORT_TYPE_BIP6) {
|
||||
if (Object_List[index].Network.IPv6.BBMD_Port != value) {
|
||||
if (Object_List[index].Network.IPv6.BBMD_Address.port != value) {
|
||||
Object_List[index].Changes_Pending = true;
|
||||
}
|
||||
Object_List[index].Network.IPv6.BBMD_Port = value;
|
||||
Object_List[index].Network.IPv6.BBMD_Address.port = value;
|
||||
status = true;
|
||||
}
|
||||
}
|
||||
@@ -2967,6 +3046,226 @@ bool Network_Port_IPv6_DHCP_Server_Set(
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the current time from the Device object
|
||||
* @return current time in epoch seconds
|
||||
*/
|
||||
static bacnet_time_t Network_Port_Epoch_Seconds_Now(void)
|
||||
{
|
||||
BACNET_DATE_TIME bdatetime = { 0 };
|
||||
|
||||
datetime_local(&bdatetime.date, &bdatetime.time, NULL, NULL);
|
||||
return datetime_seconds_since_epoch(&bdatetime);
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given object instance-number, sets the IPv4_DHCP_Lease_Time
|
||||
* or IPv6_DHCP_Lease_Time property value in seconds.
|
||||
*
|
||||
* @note depends on Network_Type being set to
|
||||
* PORT_TYPE_BIP or PORT_TYPE_BIP6 for this object
|
||||
*
|
||||
* @param object_instance - object-instance number of the object
|
||||
* @param value - 32 bit IPv4 DHCP Lease Time in seconds
|
||||
*
|
||||
* @return IPv4_DHCP_Lease_Time
|
||||
*/
|
||||
bool Network_Port_IP_DHCP_Lease_Time_Set(
|
||||
uint32_t object_instance, const uint32_t value)
|
||||
{
|
||||
bool status = false;
|
||||
unsigned index = 0;
|
||||
|
||||
index = Network_Port_Instance_To_Index(object_instance);
|
||||
if (index < BACNET_NETWORK_PORTS_MAX) {
|
||||
switch (Object_List[index].Network_Type) {
|
||||
case PORT_TYPE_BIP:
|
||||
if (Object_List[index].Network.IPv4.IP_DHCP_Lease_Seconds !=
|
||||
value) {
|
||||
Object_List[index].Changes_Pending = true;
|
||||
}
|
||||
Object_List[index].Network.IPv4.IP_DHCP_Lease_Seconds = value;
|
||||
Object_List[index].Network.IPv4.IP_DHCP_Lease_Seconds_Start =
|
||||
Network_Port_Epoch_Seconds_Now();
|
||||
status = true;
|
||||
break;
|
||||
case PORT_TYPE_BIP6:
|
||||
if (Object_List[index].Network.IPv6.IP_DHCP_Lease_Seconds !=
|
||||
value) {
|
||||
Object_List[index].Changes_Pending = true;
|
||||
}
|
||||
Object_List[index].Network.IPv6.IP_DHCP_Lease_Seconds = value;
|
||||
Object_List[index].Network.IPv6.IP_DHCP_Lease_Seconds_Start =
|
||||
Network_Port_Epoch_Seconds_Now();
|
||||
status = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the DHCP lease time in seconds
|
||||
* @param object_instance [in] BACnet network port object instance number
|
||||
* @return DHCP lease time in seconds
|
||||
*/
|
||||
uint32_t Network_Port_IP_DHCP_Lease_Time(uint32_t object_instance)
|
||||
{
|
||||
uint16_t value = 0;
|
||||
unsigned index = 0;
|
||||
|
||||
index = Network_Port_Instance_To_Index(object_instance);
|
||||
if (index < BACNET_NETWORK_PORTS_MAX) {
|
||||
switch (Object_List[index].Network_Type) {
|
||||
case PORT_TYPE_BIP:
|
||||
value = Object_List[index].Network.IPv4.IP_DHCP_Lease_Seconds;
|
||||
break;
|
||||
case PORT_TYPE_BIP6:
|
||||
value = Object_List[index].Network.IPv6.IP_DHCP_Lease_Seconds;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the DHCP lease time in seconds
|
||||
* @param object_instance [in] BACnet network port object instance number
|
||||
* @return DHCP lease time in seconds
|
||||
*/
|
||||
uint32_t Network_Port_IP_DHCP_Lease_Time_Remaining(uint32_t object_instance)
|
||||
{
|
||||
uint32_t value = 0, elapsed_seconds = 0, seconds = 0, start_seconds = 0;
|
||||
unsigned index = 0;
|
||||
|
||||
index = Network_Port_Instance_To_Index(object_instance);
|
||||
if (index < BACNET_NETWORK_PORTS_MAX) {
|
||||
switch (Object_List[index].Network_Type) {
|
||||
case PORT_TYPE_BIP:
|
||||
seconds = Object_List[index].Network.IPv4.IP_DHCP_Lease_Seconds;
|
||||
if (seconds) {
|
||||
start_seconds =
|
||||
Object_List[index]
|
||||
.Network.IPv4.IP_DHCP_Lease_Seconds_Start;
|
||||
elapsed_seconds =
|
||||
Network_Port_Epoch_Seconds_Now() - start_seconds;
|
||||
if (elapsed_seconds < seconds) {
|
||||
value = seconds - elapsed_seconds;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PORT_TYPE_BIP6:
|
||||
seconds = Object_List[index].Network.IPv6.IP_DHCP_Lease_Seconds;
|
||||
if (seconds) {
|
||||
start_seconds =
|
||||
Object_List[index]
|
||||
.Network.IPv6.IP_DHCP_Lease_Seconds_Start;
|
||||
elapsed_seconds =
|
||||
Network_Port_Epoch_Seconds_Now() - start_seconds;
|
||||
if (elapsed_seconds < seconds) {
|
||||
value = seconds - elapsed_seconds;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the the address of the DHCP server from which the last DHCP
|
||||
* lease was obtained for the port. If the address of the DHCP server
|
||||
* cannot be determined, the value of this property shall be X'00000000'.
|
||||
* @param object_instance [in] BACnet network port object instance number
|
||||
* @param ip_address [out] pointer to the IP address
|
||||
*/
|
||||
void Network_Port_IP_DHCP_Server(
|
||||
uint32_t object_instance, BACNET_OCTET_STRING *ip_address)
|
||||
{
|
||||
unsigned index = 0;
|
||||
|
||||
index = Network_Port_Instance_To_Index(object_instance);
|
||||
if (index < BACNET_NETWORK_PORTS_MAX) {
|
||||
switch (Object_List[index].Network_Type) {
|
||||
case PORT_TYPE_BIP:
|
||||
octetstring_init(
|
||||
ip_address,
|
||||
&Object_List[index].Network.IPv4.IP_DHCP_Server[0],
|
||||
IPV4_ADDR_SIZE);
|
||||
break;
|
||||
case PORT_TYPE_BIP6:
|
||||
octetstring_init(
|
||||
ip_address,
|
||||
&Object_List[index].Network.IPv6.IP_DHCP_Server[0],
|
||||
IPV6_ADDR_SIZE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief For a given object instance-number, sets the DHCP server ip-address
|
||||
* @note depends on Network_Type being set for this object
|
||||
* @param object_instance - object-instance number of the object
|
||||
* @param ip_address - octet string of the DHCP server address
|
||||
* @return true if ip-address was set
|
||||
*/
|
||||
bool Network_Port_IP_DHCP_Server_Set(
|
||||
uint32_t object_instance, BACNET_OCTET_STRING *ip_address)
|
||||
{
|
||||
bool status = false;
|
||||
unsigned index = 0;
|
||||
BACNET_OCTET_STRING my_address = { 0 };
|
||||
|
||||
index = Network_Port_Instance_To_Index(object_instance);
|
||||
if (index < BACNET_NETWORK_PORTS_MAX) {
|
||||
switch (Object_List[index].Network_Type) {
|
||||
case PORT_TYPE_BIP:
|
||||
/* check for changes */
|
||||
octetstring_init(
|
||||
&my_address,
|
||||
&Object_List[index].Network.IPv4.IP_DHCP_Server[0],
|
||||
IPV4_ADDR_SIZE);
|
||||
if (!octetstring_value_same(&my_address, ip_address)) {
|
||||
Object_List[index].Changes_Pending = true;
|
||||
}
|
||||
octetstring_copy_value(
|
||||
&Object_List[index].Network.IPv4.IP_DHCP_Server[0],
|
||||
IPV4_ADDR_SIZE, ip_address);
|
||||
status = true;
|
||||
break;
|
||||
case PORT_TYPE_BIP6:
|
||||
octetstring_init(
|
||||
&my_address,
|
||||
&Object_List[index].Network.IPv6.IP_DHCP_Server[0],
|
||||
IPV6_ADDR_SIZE);
|
||||
if (!octetstring_value_same(&my_address, ip_address)) {
|
||||
Object_List[index].Changes_Pending = true;
|
||||
}
|
||||
octetstring_copy_value(
|
||||
&Object_List[index].Network.IPv6.IP_DHCP_Server[0],
|
||||
IPV6_ADDR_SIZE, ip_address);
|
||||
status = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given object instance-number, gets the BACnet/IP UDP Port number
|
||||
* Note: depends on Network_Type being set to PORT_TYPE_BIP for this object
|
||||
@@ -3085,7 +3384,7 @@ bool Network_Port_IPv6_Auto_Addressing_Enable(uint32_t object_instance)
|
||||
index = Network_Port_Instance_To_Index(object_instance);
|
||||
if (index < BACNET_NETWORK_PORTS_MAX) {
|
||||
ipv6 = &Object_List[index].Network.IPv6;
|
||||
flag = ipv6->Auto_Addressing_Enable;
|
||||
flag = ipv6->IP_DHCP_Enable;
|
||||
}
|
||||
|
||||
return flag;
|
||||
@@ -3110,11 +3409,10 @@ bool Network_Port_IPv6_Auto_Addressing_Enable_Set(
|
||||
index = Network_Port_Instance_To_Index(object_instance);
|
||||
if (index < BACNET_NETWORK_PORTS_MAX) {
|
||||
if (Object_List[index].Network_Type == PORT_TYPE_BIP6) {
|
||||
if (Object_List[index].Network.IPv6.Auto_Addressing_Enable !=
|
||||
value) {
|
||||
if (Object_List[index].Network.IPv6.IP_DHCP_Enable != value) {
|
||||
Object_List[index].Changes_Pending = true;
|
||||
}
|
||||
Object_List[index].Network.IPv6.Auto_Addressing_Enable = value;
|
||||
Object_List[index].Network.IPv6.IP_DHCP_Enable = value;
|
||||
status = true;
|
||||
}
|
||||
}
|
||||
@@ -3182,16 +3480,13 @@ static bool Network_Port_FD_BBMD_Address_Write(
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
|
||||
break;
|
||||
} else if (value->host.ip_address.length == 4) {
|
||||
status = Network_Port_Remote_BBMD_IP_Address_Set(
|
||||
object_instance, value->host.ip_address.value[0],
|
||||
value->host.ip_address.value[1],
|
||||
value->host.ip_address.value[2],
|
||||
value->host.ip_address.value[3]);
|
||||
if (status) {
|
||||
status = Network_Port_Remote_BBMD_BIP_Port_Set(
|
||||
object_instance, value->port);
|
||||
}
|
||||
} else if (
|
||||
((value->host_ip_address) &&
|
||||
(value->host.ip_address.length == 4)) ||
|
||||
((value->host_name) &&
|
||||
(bacnet_is_valid_hostname(&value->host.name)))) {
|
||||
status = Network_Port_Remote_BBMD_Address_Set(
|
||||
object_instance, value);
|
||||
}
|
||||
if (!status) {
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
@@ -3204,14 +3499,13 @@ static bool Network_Port_FD_BBMD_Address_Write(
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
|
||||
break;
|
||||
} else if (value->host.ip_address.length == 16) {
|
||||
status = Network_Port_Remote_BBMD_IP6_Address_Set(
|
||||
object_instance, &value->host.ip_address.value[0]);
|
||||
|
||||
if (status) {
|
||||
status = Network_Port_Remote_BBMD_BIP6_Port_Set(
|
||||
object_instance, value->port);
|
||||
}
|
||||
} else if (
|
||||
((value->host_ip_address) &&
|
||||
(value->host.ip_address.length == 16)) ||
|
||||
((value->host_name) &&
|
||||
(bacnet_is_valid_hostname(&value->host.name)))) {
|
||||
status = Network_Port_Remote_BBMD_Address_Set(
|
||||
object_instance, value);
|
||||
}
|
||||
if (!status) {
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
@@ -3489,6 +3783,21 @@ int Network_Port_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
|
||||
apdu_len = encode_application_boolean(
|
||||
&apdu[0], Network_Port_IP_DHCP_Enable(rpdata->object_instance));
|
||||
break;
|
||||
case PROP_IP_DHCP_LEASE_TIME:
|
||||
apdu_len = encode_application_unsigned(
|
||||
&apdu[0],
|
||||
Network_Port_IP_DHCP_Lease_Time(rpdata->object_instance));
|
||||
break;
|
||||
case PROP_IP_DHCP_LEASE_TIME_REMAINING:
|
||||
apdu_len = encode_application_unsigned(
|
||||
&apdu[0],
|
||||
Network_Port_IP_DHCP_Lease_Time_Remaining(
|
||||
rpdata->object_instance));
|
||||
break;
|
||||
case PROP_IP_DHCP_SERVER:
|
||||
Network_Port_IP_DHCP_Server(rpdata->object_instance, &octet_string);
|
||||
apdu_len = encode_application_octet_string(&apdu[0], &octet_string);
|
||||
break;
|
||||
case PROP_IP_DNS_SERVER:
|
||||
apdu_len = bacnet_array_encode(
|
||||
rpdata->object_instance, rpdata->array_index,
|
||||
@@ -3575,10 +3884,15 @@ int Network_Port_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
|
||||
rpdata->object_instance));
|
||||
break;
|
||||
case PROP_IPV6_DHCP_LEASE_TIME:
|
||||
apdu_len = encode_application_unsigned(&apdu[0], 0);
|
||||
apdu_len = encode_application_unsigned(
|
||||
&apdu[0],
|
||||
Network_Port_IP_DHCP_Lease_Time(rpdata->object_instance));
|
||||
break;
|
||||
case PROP_IPV6_DHCP_LEASE_TIME_REMAINING:
|
||||
apdu_len = encode_application_unsigned(&apdu[0], 0);
|
||||
apdu_len = encode_application_unsigned(
|
||||
&apdu[0],
|
||||
Network_Port_IP_DHCP_Lease_Time_Remaining(
|
||||
rpdata->object_instance));
|
||||
break;
|
||||
case PROP_IPV6_DHCP_SERVER:
|
||||
Network_Port_IPv6_DHCP_Server(
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "bacnet/bacdef.h"
|
||||
/* BACnet Stack API */
|
||||
#include "bacnet/apdu.h"
|
||||
#include "bacnet/hostnport.h"
|
||||
#include "bacnet/readrange.h"
|
||||
#include "bacnet/rp.h"
|
||||
#include "bacnet/wp.h"
|
||||
@@ -160,6 +161,19 @@ BACNET_STACK_EXPORT
|
||||
bool Network_Port_IP_DHCP_Enable(uint32_t object_instance);
|
||||
BACNET_STACK_EXPORT
|
||||
bool Network_Port_IP_DHCP_Enable_Set(uint32_t object_instance, bool value);
|
||||
BACNET_STACK_EXPORT
|
||||
void Network_Port_IP_DHCP_Server(
|
||||
uint32_t object_instance, BACNET_OCTET_STRING *ip_address);
|
||||
BACNET_STACK_EXPORT
|
||||
bool Network_Port_IP_DHCP_Server_Set(
|
||||
uint32_t object_instance, BACNET_OCTET_STRING *ip_address);
|
||||
BACNET_STACK_EXPORT
|
||||
bool Network_Port_IP_DHCP_Lease_Time_Set(
|
||||
uint32_t object_instance, const uint32_t value);
|
||||
BACNET_STACK_EXPORT
|
||||
uint32_t Network_Port_IP_DHCP_Lease_Time(uint32_t object_instance);
|
||||
BACNET_STACK_EXPORT
|
||||
uint32_t Network_Port_IP_DHCP_Lease_Time_Remaining(uint32_t object_instance);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
bool Network_Port_IP_DNS_Server(
|
||||
@@ -217,6 +231,13 @@ uint16_t Network_Port_Remote_BBMD_BIP_Port(uint32_t object_instance);
|
||||
BACNET_STACK_EXPORT
|
||||
bool Network_Port_Remote_BBMD_BIP_Port_Set(
|
||||
uint32_t object_instance, uint16_t value);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
bool Network_Port_Remote_BBMD_Address(
|
||||
uint32_t object_instance, BACNET_HOST_N_PORT *bbmd_address);
|
||||
BACNET_STACK_EXPORT
|
||||
bool Network_Port_Remote_BBMD_Address_Set(
|
||||
uint32_t object_instance, const BACNET_HOST_N_PORT *bbmd_address);
|
||||
BACNET_STACK_EXPORT
|
||||
uint16_t Network_Port_Remote_BBMD_BIP_Lifetime(uint32_t object_instance);
|
||||
BACNET_STACK_EXPORT
|
||||
|
||||
Reference in New Issue
Block a user