Fixed network port object to accept host name option of host-n-port writes. (#997)
This commit is contained in:
@@ -498,6 +498,35 @@ bool characterstring_ansi_copy(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Copy a BACnetCharacterString into a buffer with null padding
|
||||||
|
* @param dest Pointer to the destination buffer.
|
||||||
|
* @param dest_max_len Size of the destination buffer.
|
||||||
|
* @param src Pointer to the source BACnetCharacterString.
|
||||||
|
* @return Length of the copied BACnetCharacterString, or 0 if the string
|
||||||
|
* exceeds the destination buffer size.
|
||||||
|
*/
|
||||||
|
size_t characterstring_copy_value(
|
||||||
|
char *dest, size_t dest_max_len, const BACNET_CHARACTER_STRING *src)
|
||||||
|
{
|
||||||
|
size_t i = 0, length = 0;
|
||||||
|
|
||||||
|
if (dest && src) {
|
||||||
|
if (src->length < dest_max_len) {
|
||||||
|
length = src->length;
|
||||||
|
for (i = 0; i < dest_max_len; i++) {
|
||||||
|
if (i < src->length) {
|
||||||
|
dest[i] = src->value[i];
|
||||||
|
} else {
|
||||||
|
dest[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the character encoding and string
|
* Returns true if the character encoding and string
|
||||||
* contents are the same.
|
* contents are the same.
|
||||||
|
|||||||
@@ -89,6 +89,9 @@ BACNET_STACK_EXPORT
|
|||||||
bool characterstring_copy(
|
bool characterstring_copy(
|
||||||
BACNET_CHARACTER_STRING *dest, const BACNET_CHARACTER_STRING *src);
|
BACNET_CHARACTER_STRING *dest, const BACNET_CHARACTER_STRING *src);
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
|
size_t characterstring_copy_value(
|
||||||
|
char *dest, size_t dest_max_len, const BACNET_CHARACTER_STRING *src);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
bool characterstring_ansi_copy(
|
bool characterstring_ansi_copy(
|
||||||
char *dest, size_t dest_max_len, const BACNET_CHARACTER_STRING *src);
|
char *dest, size_t dest_max_len, const BACNET_CHARACTER_STRING *src);
|
||||||
/* returns true if the strings are the same length, encoding, value */
|
/* returns true if the strings are the same length, encoding, value */
|
||||||
|
|||||||
+427
-113
@@ -18,6 +18,7 @@
|
|||||||
#include "bacnet/bacapp.h"
|
#include "bacnet/bacapp.h"
|
||||||
#include "bacnet/bacint.h"
|
#include "bacnet/bacint.h"
|
||||||
#include "bacnet/bacdcode.h"
|
#include "bacnet/bacdcode.h"
|
||||||
|
#include "bacnet/datetime.h"
|
||||||
#include "bacnet/npdu.h"
|
#include "bacnet/npdu.h"
|
||||||
#include "bacnet/apdu.h"
|
#include "bacnet/apdu.h"
|
||||||
#include "bacnet/datalink/bvlc.h"
|
#include "bacnet/datalink/bvlc.h"
|
||||||
@@ -33,26 +34,26 @@
|
|||||||
#define BBMD_ENABLED 1
|
#define BBMD_ENABLED 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define IPV4_ADDR_SIZE 4
|
||||||
#define BIP_DNS_MAX 3
|
#define BIP_DNS_MAX 3
|
||||||
struct bacnet_ipv4_port {
|
struct bacnet_ipv4_port {
|
||||||
uint8_t IP_Address[4];
|
uint8_t IP_Address[IPV4_ADDR_SIZE];
|
||||||
uint8_t IP_Subnet_Prefix;
|
uint8_t IP_Subnet_Prefix;
|
||||||
uint8_t IP_Gateway[4];
|
uint8_t IP_Gateway[IPV4_ADDR_SIZE];
|
||||||
uint8_t IP_DNS_Server[BIP_DNS_MAX][4];
|
uint8_t IP_DNS_Server[BIP_DNS_MAX][IPV4_ADDR_SIZE];
|
||||||
uint16_t Port;
|
uint16_t Port;
|
||||||
BACNET_IP_MODE Mode;
|
BACNET_IP_MODE Mode;
|
||||||
bool IP_DHCP_Enable;
|
bool IP_DHCP_Enable;
|
||||||
uint32_t IP_DHCP_Lease_Seconds;
|
uint32_t IP_DHCP_Lease_Seconds;
|
||||||
uint32_t IP_DHCP_Lease_Seconds_Remaining;
|
uint32_t IP_DHCP_Lease_Seconds_Start;
|
||||||
uint8_t IP_DHCP_Server[4];
|
uint8_t IP_DHCP_Server[IPV4_ADDR_SIZE];
|
||||||
bool IP_NAT_Traversal;
|
bool IP_NAT_Traversal;
|
||||||
uint32_t IP_Global_Address[4];
|
uint32_t IP_Global_Address[IPV4_ADDR_SIZE];
|
||||||
bool BBMD_Accept_FD_Registrations;
|
bool BBMD_Accept_FD_Registrations;
|
||||||
void *BBMD_BD_Table;
|
void *BBMD_BD_Table;
|
||||||
void *BBMD_FD_Table;
|
void *BBMD_FD_Table;
|
||||||
/* used for foreign device registration to remote BBMD */
|
/* used for foreign device registration to remote BBMD */
|
||||||
uint8_t BBMD_IP_Address[4];
|
BACNET_HOST_N_PORT_MINIMAL BBMD_Address;
|
||||||
uint16_t BBMD_Port;
|
|
||||||
uint16_t BBMD_Lifetime;
|
uint16_t BBMD_Lifetime;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -65,17 +66,18 @@ struct bacnet_ipv6_port {
|
|||||||
uint8_t IP_Gateway[IPV6_ADDR_SIZE];
|
uint8_t IP_Gateway[IPV6_ADDR_SIZE];
|
||||||
uint8_t IP_DNS_Server[BIP_DNS_MAX][IPV6_ADDR_SIZE];
|
uint8_t IP_DNS_Server[BIP_DNS_MAX][IPV6_ADDR_SIZE];
|
||||||
uint8_t IP_Multicast_Address[IPV6_ADDR_SIZE];
|
uint8_t IP_Multicast_Address[IPV6_ADDR_SIZE];
|
||||||
|
bool IP_DHCP_Enable;
|
||||||
uint8_t IP_DHCP_Server[IPV6_ADDR_SIZE];
|
uint8_t IP_DHCP_Server[IPV6_ADDR_SIZE];
|
||||||
|
uint32_t IP_DHCP_Lease_Seconds;
|
||||||
|
uint32_t IP_DHCP_Lease_Seconds_Start;
|
||||||
uint16_t Port;
|
uint16_t Port;
|
||||||
BACNET_IP_MODE Mode;
|
BACNET_IP_MODE Mode;
|
||||||
bool Auto_Addressing_Enable;
|
|
||||||
char Zone_Index[ZONE_INDEX_SIZE];
|
char Zone_Index[ZONE_INDEX_SIZE];
|
||||||
bool BBMD_Accept_FD_Registrations;
|
bool BBMD_Accept_FD_Registrations;
|
||||||
void *BBMD_BD_Table;
|
void *BBMD_BD_Table;
|
||||||
void *BBMD_FD_Table;
|
void *BBMD_FD_Table;
|
||||||
/* used for foreign device registration to remote BBMD */
|
/* used for foreign device registration to remote BBMD */
|
||||||
uint8_t BBMD_IP_Address[16];
|
BACNET_HOST_N_PORT_MINIMAL BBMD_Address;
|
||||||
uint16_t BBMD_Port;
|
|
||||||
uint16_t BBMD_Lifetime;
|
uint16_t BBMD_Lifetime;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -184,6 +186,9 @@ static const int BIP_Port_Properties_Optional[] = {
|
|||||||
PROP_IP_DNS_SERVER,
|
PROP_IP_DNS_SERVER,
|
||||||
#if defined(BACDL_BIP) && (BACNET_NETWORK_PORT_IP_DHCP_ENABLED)
|
#if defined(BACDL_BIP) && (BACNET_NETWORK_PORT_IP_DHCP_ENABLED)
|
||||||
PROP_IP_DHCP_ENABLE,
|
PROP_IP_DHCP_ENABLE,
|
||||||
|
PROP_IP_DHCP_LEASE_TIME,
|
||||||
|
PROP_IP_DHCP_LEASE_TIME_REMAINING,
|
||||||
|
PROP_IP_DHCP_SERVER,
|
||||||
#endif
|
#endif
|
||||||
#if defined(BACDL_BIP) && (BBMD_ENABLED)
|
#if defined(BACDL_BIP) && (BBMD_ENABLED)
|
||||||
PROP_BBMD_ACCEPT_FD_REGISTRATIONS,
|
PROP_BBMD_ACCEPT_FD_REGISTRATIONS,
|
||||||
@@ -214,10 +219,12 @@ static const int BIP6_Port_Properties_Optional[] = {
|
|||||||
PROP_IPV6_DEFAULT_GATEWAY,
|
PROP_IPV6_DEFAULT_GATEWAY,
|
||||||
PROP_BACNET_IPV6_MULTICAST_ADDRESS,
|
PROP_BACNET_IPV6_MULTICAST_ADDRESS,
|
||||||
PROP_IPV6_DNS_SERVER,
|
PROP_IPV6_DNS_SERVER,
|
||||||
|
#if defined(BACDL_BIP6) && (BACNET_NETWORK_PORT_IP_DHCP_ENABLED)
|
||||||
PROP_IPV6_AUTO_ADDRESSING_ENABLE,
|
PROP_IPV6_AUTO_ADDRESSING_ENABLE,
|
||||||
PROP_IPV6_DHCP_LEASE_TIME,
|
PROP_IPV6_DHCP_LEASE_TIME,
|
||||||
PROP_IPV6_DHCP_LEASE_TIME_REMAINING,
|
PROP_IPV6_DHCP_LEASE_TIME_REMAINING,
|
||||||
PROP_IPV6_DHCP_SERVER,
|
PROP_IPV6_DHCP_SERVER,
|
||||||
|
#endif
|
||||||
PROP_IPV6_ZONE_INDEX,
|
PROP_IPV6_ZONE_INDEX,
|
||||||
#if defined(BACDL_BIP6) && (BBMD_ENABLED)
|
#if defined(BACDL_BIP6) && (BBMD_ENABLED)
|
||||||
PROP_BBMD_ACCEPT_FD_REGISTRATIONS,
|
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 (index < BACNET_NETWORK_PORTS_MAX) {
|
||||||
if (Object_List[index].Network_Type == PORT_TYPE_BIP) {
|
if (Object_List[index].Network_Type == PORT_TYPE_BIP) {
|
||||||
dhcp_enable = Object_List[index].Network.IPv4.IP_DHCP_Enable;
|
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);
|
index = Network_Port_Instance_To_Index(object_instance);
|
||||||
if (index < BACNET_NETWORK_PORTS_MAX) {
|
if (index < BACNET_NETWORK_PORTS_MAX) {
|
||||||
if (Object_List[index].Network_Type == PORT_TYPE_BIP) {
|
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;
|
Object_List[index].Network.IPv4.IP_DHCP_Enable = value;
|
||||||
status = true;
|
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 */
|
unsigned index = 0; /* offset from instance lookup */
|
||||||
bool status = false;
|
bool status = false;
|
||||||
|
uint8_t *dns_server = NULL;
|
||||||
|
|
||||||
index = Network_Port_Instance_To_Index(object_instance);
|
index = Network_Port_Instance_To_Index(object_instance);
|
||||||
if (index < BACNET_NETWORK_PORTS_MAX) {
|
if (index < BACNET_NETWORK_PORTS_MAX) {
|
||||||
if (Object_List[index].Network_Type == PORT_TYPE_BIP) {
|
if (Object_List[index].Network_Type == PORT_TYPE_BIP) {
|
||||||
if (dns_index < BIP_DNS_MAX) {
|
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][0] = a;
|
||||||
Object_List[index].Network.IPv4.IP_DNS_Server[dns_index][1] = b;
|
Object_List[index].Network.IPv4.IP_DNS_Server[dns_index][1] = b;
|
||||||
Object_List[index].Network.IPv4.IP_DNS_Server[dns_index][2] = c;
|
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;
|
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
|
* For a given object instance-number, loads the ip-address into
|
||||||
* an octet string.
|
* an octet string.
|
||||||
@@ -1972,23 +2064,27 @@ bool Network_Port_Remote_BBMD_IP_Address(
|
|||||||
{
|
{
|
||||||
unsigned index = 0; /* offset from instance lookup */
|
unsigned index = 0; /* offset from instance lookup */
|
||||||
bool status = false;
|
bool status = false;
|
||||||
|
BACNET_HOST_N_PORT_MINIMAL *address;
|
||||||
|
|
||||||
index = Network_Port_Instance_To_Index(object_instance);
|
index = Network_Port_Instance_To_Index(object_instance);
|
||||||
if (index < BACNET_NETWORK_PORTS_MAX) {
|
if (index < BACNET_NETWORK_PORTS_MAX) {
|
||||||
if (Object_List[index].Network_Type == PORT_TYPE_BIP) {
|
if (Object_List[index].Network_Type == PORT_TYPE_BIP) {
|
||||||
if (a) {
|
address = &Object_List[index].Network.IPv4.BBMD_Address;
|
||||||
*a = Object_List[index].Network.IPv4.BBMD_IP_Address[0];
|
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 */
|
unsigned index = 0; /* offset from instance lookup */
|
||||||
bool status = false;
|
bool status = false;
|
||||||
|
BACNET_HOST_N_PORT_MINIMAL *address;
|
||||||
|
|
||||||
index = Network_Port_Instance_To_Index(object_instance);
|
index = Network_Port_Instance_To_Index(object_instance);
|
||||||
if (index < BACNET_NETWORK_PORTS_MAX) {
|
if (index < BACNET_NETWORK_PORTS_MAX) {
|
||||||
if (Object_List[index].Network_Type == PORT_TYPE_BIP) {
|
if (Object_List[index].Network_Type == PORT_TYPE_BIP) {
|
||||||
if ((Object_List[index].Network.IPv4.BBMD_IP_Address[0] != a) ||
|
address = &Object_List[index].Network.IPv4.BBMD_Address;
|
||||||
(Object_List[index].Network.IPv4.BBMD_IP_Address[1] != b) ||
|
if ((address->host.ip_address.address[0] != a) ||
|
||||||
(Object_List[index].Network.IPv4.BBMD_IP_Address[2] != c) ||
|
(address->host.ip_address.address[1] != b) ||
|
||||||
(Object_List[index].Network.IPv4.BBMD_IP_Address[3] != d)) {
|
(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].Changes_Pending = true;
|
||||||
}
|
}
|
||||||
Object_List[index].Network.IPv4.BBMD_IP_Address[0] = a;
|
address->host.ip_address.address[0] = a;
|
||||||
Object_List[index].Network.IPv4.BBMD_IP_Address[1] = b;
|
address->host.ip_address.address[1] = b;
|
||||||
Object_List[index].Network.IPv4.BBMD_IP_Address[2] = c;
|
address->host.ip_address.address[2] = c;
|
||||||
Object_List[index].Network.IPv4.BBMD_IP_Address[3] = d;
|
address->host.ip_address.address[3] = d;
|
||||||
|
address->host.ip_address.length = 4;
|
||||||
|
address->tag = BACNET_HOST_ADDRESS_TAG_IP_ADDRESS;
|
||||||
status = true;
|
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);
|
index = Network_Port_Instance_To_Index(object_instance);
|
||||||
if (index < BACNET_NETWORK_PORTS_MAX) {
|
if (index < BACNET_NETWORK_PORTS_MAX) {
|
||||||
if (Object_List[index].Network_Type == PORT_TYPE_BIP) {
|
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);
|
index = Network_Port_Instance_To_Index(object_instance);
|
||||||
if (index < BACNET_NETWORK_PORTS_MAX) {
|
if (index < BACNET_NETWORK_PORTS_MAX) {
|
||||||
if (Object_List[index].Network_Type == PORT_TYPE_BIP) {
|
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].Changes_Pending = true;
|
||||||
}
|
}
|
||||||
Object_List[index].Network.IPv4.BBMD_Port = value;
|
Object_List[index].Network.IPv4.BBMD_Address.port = value;
|
||||||
status = true;
|
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
|
* @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)
|
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(
|
bool Network_Port_BBMD_IP6_Accept_FD_Registrations_Set(
|
||||||
uint32_t object_instance, bool flag)
|
uint32_t object_instance, bool flag)
|
||||||
{
|
{
|
||||||
bool status = false;
|
return Network_Port_BBMD_Accept_FD_Registrations_Set(object_instance, flag);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2329,35 +2415,20 @@ bool Network_Port_BBMD_IP6_FD_Table_Set(
|
|||||||
* @param object_instance - object-instance number of the object
|
* @param object_instance - object-instance number of the object
|
||||||
* @param addr - holds the ip-address and port retrieved
|
* @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(
|
static int Foreign_Device_BBMD_Address_Encode(
|
||||||
uint32_t object_instance, uint8_t *apdu, size_t apdu_size)
|
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;
|
int apdu_len = 0;
|
||||||
|
BACNET_HOST_N_PORT bbmd_address = { 0 };
|
||||||
|
|
||||||
index = Network_Port_Instance_To_Index(object_instance);
|
Network_Port_Remote_BBMD_Address(object_instance, &bbmd_address);
|
||||||
if (index < BACNET_NETWORK_PORTS_MAX) {
|
apdu_len = host_n_port_encode(NULL, &bbmd_address);
|
||||||
if (Object_List[index].Network_Type == PORT_TYPE_BIP) {
|
if (apdu_len > apdu_size) {
|
||||||
bvlc_address_set(
|
apdu_len = BACNET_STATUS_ERROR;
|
||||||
&ip4_address,
|
} else {
|
||||||
Object_List[index].Network.IPv4.BBMD_IP_Address[0],
|
apdu_len = host_n_port_encode(apdu, &bbmd_address);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return apdu_len;
|
return apdu_len;
|
||||||
@@ -2378,14 +2449,19 @@ bool Network_Port_Remote_BBMD_IP6_Address(
|
|||||||
{
|
{
|
||||||
unsigned index = 0; /* offset from instance lookup */
|
unsigned index = 0; /* offset from instance lookup */
|
||||||
bool status = false;
|
bool status = false;
|
||||||
|
BACNET_HOST_N_PORT_MINIMAL *address;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
index = Network_Port_Instance_To_Index(object_instance);
|
index = Network_Port_Instance_To_Index(object_instance);
|
||||||
if (index < BACNET_NETWORK_PORTS_MAX) {
|
if (index < BACNET_NETWORK_PORTS_MAX) {
|
||||||
if (Object_List[index].Network_Type == PORT_TYPE_BIP6) {
|
if (Object_List[index].Network_Type == PORT_TYPE_BIP6) {
|
||||||
if (addr) {
|
address = &Object_List[index].Network.IPv6.BBMD_Address;
|
||||||
memcpy(
|
if (address->tag == BACNET_HOST_ADDRESS_TAG_IP_ADDRESS) {
|
||||||
addr, Object_List[index].Network.IPv6.BBMD_IP_Address,
|
if (addr) {
|
||||||
IP6_ADDRESS_MAX);
|
for (i = 0; i < IP6_ADDRESS_MAX; i++) {
|
||||||
|
addr[i] = address->host.ip_address.address[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
status = true;
|
status = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2408,19 +2484,22 @@ bool Network_Port_Remote_BBMD_IP6_Address_Set(
|
|||||||
{
|
{
|
||||||
unsigned index = 0; /* offset from instance lookup */
|
unsigned index = 0; /* offset from instance lookup */
|
||||||
bool status = false;
|
bool status = false;
|
||||||
|
BACNET_HOST_N_PORT_MINIMAL bbmd_address = { 0 };
|
||||||
|
uint16_t port;
|
||||||
|
|
||||||
index = Network_Port_Instance_To_Index(object_instance);
|
index = Network_Port_Instance_To_Index(object_instance);
|
||||||
if (index < BACNET_NETWORK_PORTS_MAX) {
|
if (index < BACNET_NETWORK_PORTS_MAX) {
|
||||||
if (Object_List[index].Network_Type == PORT_TYPE_BIP6) {
|
if (Object_List[index].Network_Type == PORT_TYPE_BIP6) {
|
||||||
if (memcmp(
|
port = Object_List[index].Network.IPv6.BBMD_Address.port;
|
||||||
Object_List[index].Network.IPv6.BBMD_IP_Address, addr,
|
host_n_port_minimal_ip_init(
|
||||||
IP6_ADDRESS_MAX)) {
|
&bbmd_address, port, addr, IP6_ADDRESS_MAX);
|
||||||
memcpy(
|
if (!host_n_port_minimal_same(
|
||||||
Object_List[index].Network.IPv6.BBMD_IP_Address, addr,
|
&Object_List[index].Network.IPv6.BBMD_Address,
|
||||||
IP6_ADDRESS_MAX);
|
&bbmd_address)) {
|
||||||
Object_List[index].Changes_Pending = true;
|
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);
|
index = Network_Port_Instance_To_Index(object_instance);
|
||||||
if (index < BACNET_NETWORK_PORTS_MAX) {
|
if (index < BACNET_NETWORK_PORTS_MAX) {
|
||||||
if (Object_List[index].Network_Type == PORT_TYPE_BIP6) {
|
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);
|
index = Network_Port_Instance_To_Index(object_instance);
|
||||||
if (index < BACNET_NETWORK_PORTS_MAX) {
|
if (index < BACNET_NETWORK_PORTS_MAX) {
|
||||||
if (Object_List[index].Network_Type == PORT_TYPE_BIP6) {
|
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].Changes_Pending = true;
|
||||||
}
|
}
|
||||||
Object_List[index].Network.IPv6.BBMD_Port = value;
|
Object_List[index].Network.IPv6.BBMD_Address.port = value;
|
||||||
status = true;
|
status = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2967,6 +3046,226 @@ bool Network_Port_IPv6_DHCP_Server_Set(
|
|||||||
return status;
|
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
|
* 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
|
* 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);
|
index = Network_Port_Instance_To_Index(object_instance);
|
||||||
if (index < BACNET_NETWORK_PORTS_MAX) {
|
if (index < BACNET_NETWORK_PORTS_MAX) {
|
||||||
ipv6 = &Object_List[index].Network.IPv6;
|
ipv6 = &Object_List[index].Network.IPv6;
|
||||||
flag = ipv6->Auto_Addressing_Enable;
|
flag = ipv6->IP_DHCP_Enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
return flag;
|
return flag;
|
||||||
@@ -3110,11 +3409,10 @@ bool Network_Port_IPv6_Auto_Addressing_Enable_Set(
|
|||||||
index = Network_Port_Instance_To_Index(object_instance);
|
index = Network_Port_Instance_To_Index(object_instance);
|
||||||
if (index < BACNET_NETWORK_PORTS_MAX) {
|
if (index < BACNET_NETWORK_PORTS_MAX) {
|
||||||
if (Object_List[index].Network_Type == PORT_TYPE_BIP6) {
|
if (Object_List[index].Network_Type == PORT_TYPE_BIP6) {
|
||||||
if (Object_List[index].Network.IPv6.Auto_Addressing_Enable !=
|
if (Object_List[index].Network.IPv6.IP_DHCP_Enable != value) {
|
||||||
value) {
|
|
||||||
Object_List[index].Changes_Pending = true;
|
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;
|
status = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3182,16 +3480,13 @@ static bool Network_Port_FD_BBMD_Address_Write(
|
|||||||
*error_class = ERROR_CLASS_PROPERTY;
|
*error_class = ERROR_CLASS_PROPERTY;
|
||||||
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
|
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
|
||||||
break;
|
break;
|
||||||
} else if (value->host.ip_address.length == 4) {
|
} else if (
|
||||||
status = Network_Port_Remote_BBMD_IP_Address_Set(
|
((value->host_ip_address) &&
|
||||||
object_instance, value->host.ip_address.value[0],
|
(value->host.ip_address.length == 4)) ||
|
||||||
value->host.ip_address.value[1],
|
((value->host_name) &&
|
||||||
value->host.ip_address.value[2],
|
(bacnet_is_valid_hostname(&value->host.name)))) {
|
||||||
value->host.ip_address.value[3]);
|
status = Network_Port_Remote_BBMD_Address_Set(
|
||||||
if (status) {
|
object_instance, value);
|
||||||
status = Network_Port_Remote_BBMD_BIP_Port_Set(
|
|
||||||
object_instance, value->port);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!status) {
|
if (!status) {
|
||||||
*error_class = ERROR_CLASS_PROPERTY;
|
*error_class = ERROR_CLASS_PROPERTY;
|
||||||
@@ -3204,14 +3499,13 @@ static bool Network_Port_FD_BBMD_Address_Write(
|
|||||||
*error_class = ERROR_CLASS_PROPERTY;
|
*error_class = ERROR_CLASS_PROPERTY;
|
||||||
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
|
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
|
||||||
break;
|
break;
|
||||||
} else if (value->host.ip_address.length == 16) {
|
} else if (
|
||||||
status = Network_Port_Remote_BBMD_IP6_Address_Set(
|
((value->host_ip_address) &&
|
||||||
object_instance, &value->host.ip_address.value[0]);
|
(value->host.ip_address.length == 16)) ||
|
||||||
|
((value->host_name) &&
|
||||||
if (status) {
|
(bacnet_is_valid_hostname(&value->host.name)))) {
|
||||||
status = Network_Port_Remote_BBMD_BIP6_Port_Set(
|
status = Network_Port_Remote_BBMD_Address_Set(
|
||||||
object_instance, value->port);
|
object_instance, value);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!status) {
|
if (!status) {
|
||||||
*error_class = ERROR_CLASS_PROPERTY;
|
*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_len = encode_application_boolean(
|
||||||
&apdu[0], Network_Port_IP_DHCP_Enable(rpdata->object_instance));
|
&apdu[0], Network_Port_IP_DHCP_Enable(rpdata->object_instance));
|
||||||
break;
|
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:
|
case PROP_IP_DNS_SERVER:
|
||||||
apdu_len = bacnet_array_encode(
|
apdu_len = bacnet_array_encode(
|
||||||
rpdata->object_instance, rpdata->array_index,
|
rpdata->object_instance, rpdata->array_index,
|
||||||
@@ -3575,10 +3884,15 @@ int Network_Port_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
|
|||||||
rpdata->object_instance));
|
rpdata->object_instance));
|
||||||
break;
|
break;
|
||||||
case PROP_IPV6_DHCP_LEASE_TIME:
|
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;
|
break;
|
||||||
case PROP_IPV6_DHCP_LEASE_TIME_REMAINING:
|
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;
|
break;
|
||||||
case PROP_IPV6_DHCP_SERVER:
|
case PROP_IPV6_DHCP_SERVER:
|
||||||
Network_Port_IPv6_DHCP_Server(
|
Network_Port_IPv6_DHCP_Server(
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include "bacnet/bacdef.h"
|
#include "bacnet/bacdef.h"
|
||||||
/* BACnet Stack API */
|
/* BACnet Stack API */
|
||||||
#include "bacnet/apdu.h"
|
#include "bacnet/apdu.h"
|
||||||
|
#include "bacnet/hostnport.h"
|
||||||
#include "bacnet/readrange.h"
|
#include "bacnet/readrange.h"
|
||||||
#include "bacnet/rp.h"
|
#include "bacnet/rp.h"
|
||||||
#include "bacnet/wp.h"
|
#include "bacnet/wp.h"
|
||||||
@@ -160,6 +161,19 @@ BACNET_STACK_EXPORT
|
|||||||
bool Network_Port_IP_DHCP_Enable(uint32_t object_instance);
|
bool Network_Port_IP_DHCP_Enable(uint32_t object_instance);
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
bool Network_Port_IP_DHCP_Enable_Set(uint32_t object_instance, bool value);
|
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
|
BACNET_STACK_EXPORT
|
||||||
bool Network_Port_IP_DNS_Server(
|
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
|
BACNET_STACK_EXPORT
|
||||||
bool Network_Port_Remote_BBMD_BIP_Port_Set(
|
bool Network_Port_Remote_BBMD_BIP_Port_Set(
|
||||||
uint32_t object_instance, uint16_t value);
|
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
|
BACNET_STACK_EXPORT
|
||||||
uint16_t Network_Port_Remote_BBMD_BIP_Lifetime(uint32_t object_instance);
|
uint16_t Network_Port_Remote_BBMD_BIP_Lifetime(uint32_t object_instance);
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
|
|||||||
@@ -374,6 +374,210 @@ bool host_n_port_copy(BACNET_HOST_N_PORT *dst, const BACNET_HOST_N_PORT *src)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize a BACnetHostNPort_Minimal structure for IP address
|
||||||
|
* @param host - BACnetHostNPort_Minimal structure
|
||||||
|
* @param port - port number
|
||||||
|
* @param address - BACnetHostAddress
|
||||||
|
*/
|
||||||
|
void host_n_port_minimal_ip_init(
|
||||||
|
BACNET_HOST_N_PORT_MINIMAL *host,
|
||||||
|
uint16_t port,
|
||||||
|
const uint8_t *address,
|
||||||
|
size_t address_len)
|
||||||
|
{
|
||||||
|
unsigned i, imax;
|
||||||
|
|
||||||
|
if (host) {
|
||||||
|
host->tag = BACNET_HOST_ADDRESS_TAG_IP_ADDRESS;
|
||||||
|
host->host.ip_address.length = address_len;
|
||||||
|
imax = min(address_len, sizeof(host->host.ip_address.address));
|
||||||
|
if (address) {
|
||||||
|
for (i = 0; i < imax; i++) {
|
||||||
|
host->host.ip_address.address[i] = address[i];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (i = 0; i < imax; i++) {
|
||||||
|
host->host.ip_address.address[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
host->port = port;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief copy the BACnetHostNPort_Minimal complex data
|
||||||
|
* @param dest - destination structure
|
||||||
|
* @param src - source structure
|
||||||
|
* @return true if successfully copied
|
||||||
|
*/
|
||||||
|
bool host_n_port_minimal_copy(
|
||||||
|
BACNET_HOST_N_PORT_MINIMAL *dest, const BACNET_HOST_N_PORT_MINIMAL *src)
|
||||||
|
{
|
||||||
|
bool status = false;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (dest && src) {
|
||||||
|
dest->tag = src->tag;
|
||||||
|
dest->port = src->port;
|
||||||
|
if (src->tag == BACNET_HOST_ADDRESS_TAG_IP_ADDRESS) {
|
||||||
|
status = true;
|
||||||
|
dest->host.ip_address.length = src->host.ip_address.length;
|
||||||
|
for (i = 0; i < src->host.ip_address.length; i++) {
|
||||||
|
if (i < sizeof(dest->host.ip_address.address)) {
|
||||||
|
dest->host.ip_address.address[i] =
|
||||||
|
src->host.ip_address.address[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (src->tag == BACNET_HOST_ADDRESS_TAG_NAME) {
|
||||||
|
status = true;
|
||||||
|
dest->host.name.length = src->host.name.length;
|
||||||
|
for (i = 0; i < src->host.name.length; i++) {
|
||||||
|
if (i < sizeof(dest->host.name.fqdn)) {
|
||||||
|
dest->host.name.fqdn[i] = src->host.name.fqdn[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (src->tag == BACNET_HOST_ADDRESS_TAG_NONE) {
|
||||||
|
status = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Copy the BACnetHostNPort complex data from src to dst
|
||||||
|
* @param dst - destination structure
|
||||||
|
* @param src - source structure
|
||||||
|
* @return true if successfully copied
|
||||||
|
*/
|
||||||
|
bool host_n_port_from_minimal(
|
||||||
|
BACNET_HOST_N_PORT *dst, const BACNET_HOST_N_PORT_MINIMAL *src)
|
||||||
|
{
|
||||||
|
bool status = false;
|
||||||
|
|
||||||
|
if (dst && src) {
|
||||||
|
switch (src->tag) {
|
||||||
|
case BACNET_HOST_ADDRESS_TAG_NONE:
|
||||||
|
dst->host_ip_address = false;
|
||||||
|
dst->host_name = false;
|
||||||
|
status = true;
|
||||||
|
break;
|
||||||
|
case BACNET_HOST_ADDRESS_TAG_IP_ADDRESS:
|
||||||
|
dst->host_ip_address = true;
|
||||||
|
dst->host_name = false;
|
||||||
|
octetstring_init(
|
||||||
|
&dst->host.ip_address, src->host.ip_address.address,
|
||||||
|
src->host.ip_address.length);
|
||||||
|
status = true;
|
||||||
|
break;
|
||||||
|
case BACNET_HOST_ADDRESS_TAG_NAME:
|
||||||
|
dst->host_ip_address = false;
|
||||||
|
dst->host_name = true;
|
||||||
|
characterstring_init(
|
||||||
|
&dst->host.name, CHARACTER_ANSI_X34, src->host.name.fqdn,
|
||||||
|
src->host.name.length);
|
||||||
|
status = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false; /* invalid tag number */
|
||||||
|
}
|
||||||
|
if (status) {
|
||||||
|
dst->port = src->port;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Copy the BACnetHostNPort complex data from src to dst
|
||||||
|
* @param dst - destination structure
|
||||||
|
* @param src - source structure
|
||||||
|
* @return true if successfully copied
|
||||||
|
*/
|
||||||
|
bool host_n_port_to_minimal(
|
||||||
|
BACNET_HOST_N_PORT_MINIMAL *dst, const BACNET_HOST_N_PORT *src)
|
||||||
|
{
|
||||||
|
bool status = false;
|
||||||
|
|
||||||
|
if (dst && src) {
|
||||||
|
if (src->host_ip_address) {
|
||||||
|
dst->tag = BACNET_HOST_ADDRESS_TAG_IP_ADDRESS;
|
||||||
|
dst->host.ip_address.length = octetstring_copy_value(
|
||||||
|
dst->host.ip_address.address,
|
||||||
|
sizeof(dst->host.ip_address.address), &src->host.ip_address);
|
||||||
|
if (dst->host.ip_address.length > 0) {
|
||||||
|
status = true;
|
||||||
|
}
|
||||||
|
} else if (src->host_name) {
|
||||||
|
dst->tag = BACNET_HOST_ADDRESS_TAG_NAME;
|
||||||
|
dst->host.name.length = characterstring_copy_value(
|
||||||
|
dst->host.name.fqdn, sizeof(dst->host.name.fqdn),
|
||||||
|
&src->host.name);
|
||||||
|
if (dst->host.name.length > 0) {
|
||||||
|
status = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dst->tag = BACNET_HOST_ADDRESS_TAG_NONE;
|
||||||
|
status = true;
|
||||||
|
}
|
||||||
|
dst->port = src->port;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool host_n_port_minimal_same(
|
||||||
|
const BACNET_HOST_N_PORT_MINIMAL *dst,
|
||||||
|
const BACNET_HOST_N_PORT_MINIMAL *src)
|
||||||
|
{
|
||||||
|
bool status = false;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (dst && src) {
|
||||||
|
if (dst->tag == src->tag) {
|
||||||
|
if (dst->tag == BACNET_HOST_ADDRESS_TAG_IP_ADDRESS) {
|
||||||
|
if (dst->host.ip_address.length ==
|
||||||
|
src->host.ip_address.length) {
|
||||||
|
status = true;
|
||||||
|
for (i = 0; i < dst->host.ip_address.length; i++) {
|
||||||
|
if (i < sizeof(dst->host.ip_address.address)) {
|
||||||
|
if (dst->host.ip_address.address[i] !=
|
||||||
|
src->host.ip_address.address[i]) {
|
||||||
|
status = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (dst->tag == BACNET_HOST_ADDRESS_TAG_NAME) {
|
||||||
|
if (dst->host.name.length == src->host.name.length) {
|
||||||
|
status = true;
|
||||||
|
for (i = 0; i < dst->host.name.length; i++) {
|
||||||
|
if (i < sizeof(dst->host.name.fqdn)) {
|
||||||
|
if (dst->host.name.fqdn[i] !=
|
||||||
|
src->host.name.fqdn[i]) {
|
||||||
|
status = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (dst->tag == BACNET_HOST_ADDRESS_TAG_NONE) {
|
||||||
|
status = true;
|
||||||
|
}
|
||||||
|
if (status) {
|
||||||
|
if (dst->port != src->port) {
|
||||||
|
status = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Compare the BACnetHostNPort complex data of src and dst
|
* @brief Compare the BACnetHostNPort complex data of src and dst
|
||||||
* @param host1 - host 1 structure
|
* @param host1 - host 1 structure
|
||||||
@@ -1159,3 +1363,102 @@ int bacnet_fdt_entry_to_ascii(
|
|||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks conformance of a hostname with:
|
||||||
|
* RFC 1123: Requirements for Internet Hosts – application and support
|
||||||
|
* RFC 2181: Clarifications to the DNS specification
|
||||||
|
*
|
||||||
|
* Host software MUST handle host names of up to 63 characters and
|
||||||
|
* SHOULD handle host names of up to 255 characters.
|
||||||
|
*
|
||||||
|
* Whenever a user inputs the identity of an Internet host, it SHOULD
|
||||||
|
* be possible to enter either (1) a host domain name or (2) an IP
|
||||||
|
* address in dotted-decimal ("#.#.#.#") form. The host SHOULD check
|
||||||
|
* the string syntactically for a dotted-decimal number before
|
||||||
|
* looking it up in the Domain Name System.
|
||||||
|
*
|
||||||
|
* The DNS itself places only one restriction on the particular labels
|
||||||
|
* that can be used to identify resource records. That one restriction
|
||||||
|
* relates to the length of the label and the full name. The length of
|
||||||
|
* any one label is limited to between 1 and 63 octets. A full domain
|
||||||
|
* name is limited to 255 octets (including the separators). The zero
|
||||||
|
* length full name is defined as representing the root of the DNS tree,
|
||||||
|
* and is typically written and displayed as ".". Those restrictions
|
||||||
|
* aside, any binary string whatever can be used as the label of any
|
||||||
|
* resource record. Similarly, any binary string can serve as the value
|
||||||
|
* of any record that includes a domain name as some or all of its value
|
||||||
|
* (SOA, NS, MX, PTR, CNAME, and any others that may be added).
|
||||||
|
*
|
||||||
|
* @param hostname - hostname as BACNET_CHARACTER_STRING
|
||||||
|
* @return true if the host name conorms to RFC 1123, false otherwise
|
||||||
|
*/
|
||||||
|
bool bacnet_is_valid_hostname(const BACNET_CHARACTER_STRING *const hostname)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
const char *val;
|
||||||
|
int dot_count = 0;
|
||||||
|
int i = 0;
|
||||||
|
char c;
|
||||||
|
char fqdn_copy[255 + 1] = { 0 };
|
||||||
|
char *label = NULL;
|
||||||
|
|
||||||
|
len = characterstring_length(hostname);
|
||||||
|
/* Check length */
|
||||||
|
if ((len == 0) || (len > sizeof(fqdn_copy) - 1)) {
|
||||||
|
/* Invalid length */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/* Check if it looks like an IP address (basic check) */
|
||||||
|
val = characterstring_value(hostname);
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
if (val[i] == '.') {
|
||||||
|
dot_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Check if it's a numeric pattern (like an incomplete IP) */
|
||||||
|
if (dot_count > 0 && strspn(val, "0123456789.") == len) {
|
||||||
|
/* Invalid: looks like an incomplete IP */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/* Check each character */
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
c = val[i];
|
||||||
|
if (!isalnum(c) && c != '-' && c != '.') {
|
||||||
|
/* Invalid character */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/* Check for starting and ending hyphens */
|
||||||
|
if (i == 0 && c == '-') {
|
||||||
|
/* Cannot start with a hyphen */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (i == len - 1 && c == '-') {
|
||||||
|
/* Cannot end with a hyphen */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/* Check for consecutive periods or hyphens */
|
||||||
|
if (i > 0 &&
|
||||||
|
((val[i] == '-' && val[i - 1] == '-') ||
|
||||||
|
(val[i] == '.' && val[i - 1] == '.'))) {
|
||||||
|
/* Invalid consecutive characters */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Make a copy to manipulate when checking each label */
|
||||||
|
strncpy(fqdn_copy, val, sizeof(fqdn_copy) - 1);
|
||||||
|
/* Split FQDN by '.' */
|
||||||
|
label = strtok(fqdn_copy, ".");
|
||||||
|
while (label != NULL) {
|
||||||
|
/* check for each label length not exceeding 63 characters */
|
||||||
|
if (strlen(label) > 63) {
|
||||||
|
/* Invalid label found */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/* Move to the next label */
|
||||||
|
label = strtok(NULL, ".");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Valid hostname */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
/* BACnet Stack API */
|
/* BACnet Stack API */
|
||||||
#include "bacnet/bacstr.h"
|
#include "bacnet/bacstr.h"
|
||||||
#include "bacnet/datalink/bvlc.h"
|
#include "bacnet/datalink/bvlc.h"
|
||||||
|
#include "bacnet/datalink/bvlc6.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BACnetHostNPort ::= SEQUENCE {
|
* BACnetHostNPort ::= SEQUENCE {
|
||||||
@@ -38,6 +39,25 @@ typedef struct BACnetHostNPort {
|
|||||||
uint16_t port;
|
uint16_t port;
|
||||||
} BACNET_HOST_N_PORT;
|
} BACNET_HOST_N_PORT;
|
||||||
|
|
||||||
|
#define BACNET_HOST_ADDRESS_TAG_NONE 0
|
||||||
|
#define BACNET_HOST_ADDRESS_TAG_IP_ADDRESS 1
|
||||||
|
#define BACNET_HOST_ADDRESS_TAG_NAME 2
|
||||||
|
/* BACnetHostNPort with smaller RAM footprint using C datatypes */
|
||||||
|
typedef struct BACnetHostNPort_Minimal {
|
||||||
|
uint8_t tag;
|
||||||
|
union BACnetHostAddress_Minimal {
|
||||||
|
struct BACnetHostOctetString {
|
||||||
|
uint8_t address[IP6_ADDRESS_MAX];
|
||||||
|
uint8_t length;
|
||||||
|
} ip_address;
|
||||||
|
struct BACnetHostCharacterString {
|
||||||
|
char fqdn[256];
|
||||||
|
uint8_t length;
|
||||||
|
} name;
|
||||||
|
} host;
|
||||||
|
uint16_t port;
|
||||||
|
} BACNET_HOST_N_PORT_MINIMAL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BACnetBDTEntry ::= SEQUENCE {
|
* BACnetBDTEntry ::= SEQUENCE {
|
||||||
* bbmd-address [0] BACnetHostNPort,
|
* bbmd-address [0] BACnetHostNPort,
|
||||||
@@ -99,6 +119,26 @@ int host_n_port_context_decode(
|
|||||||
BACNET_HOST_N_PORT *address);
|
BACNET_HOST_N_PORT *address);
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
bool host_n_port_copy(BACNET_HOST_N_PORT *dst, const BACNET_HOST_N_PORT *src);
|
bool host_n_port_copy(BACNET_HOST_N_PORT *dst, const BACNET_HOST_N_PORT *src);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
bool host_n_port_from_minimal(
|
||||||
|
BACNET_HOST_N_PORT *dst, const BACNET_HOST_N_PORT_MINIMAL *src);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
bool host_n_port_to_minimal(
|
||||||
|
BACNET_HOST_N_PORT_MINIMAL *dst, const BACNET_HOST_N_PORT *src);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
bool host_n_port_minimal_copy(
|
||||||
|
BACNET_HOST_N_PORT_MINIMAL *dst, const BACNET_HOST_N_PORT_MINIMAL *src);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
bool host_n_port_minimal_same(
|
||||||
|
const BACNET_HOST_N_PORT_MINIMAL *dst,
|
||||||
|
const BACNET_HOST_N_PORT_MINIMAL *src);
|
||||||
|
void host_n_port_minimal_ip_init(
|
||||||
|
BACNET_HOST_N_PORT_MINIMAL *host,
|
||||||
|
uint16_t port,
|
||||||
|
const uint8_t *address,
|
||||||
|
size_t address_len);
|
||||||
|
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
bool host_n_port_same(
|
bool host_n_port_same(
|
||||||
const BACNET_HOST_N_PORT *dst, const BACNET_HOST_N_PORT *src);
|
const BACNET_HOST_N_PORT *dst, const BACNET_HOST_N_PORT *src);
|
||||||
@@ -162,6 +202,8 @@ bool bacnet_fdt_entry_from_ascii(BACNET_FDT_ENTRY *value, const char *argv);
|
|||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
int bacnet_fdt_entry_to_ascii(
|
int bacnet_fdt_entry_to_ascii(
|
||||||
char *str, size_t str_size, const BACNET_FDT_ENTRY *value);
|
char *str, size_t str_size, const BACNET_FDT_ENTRY *value);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
bool bacnet_is_valid_hostname(const BACNET_CHARACTER_STRING *const hostname);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ add_compile_definitions(
|
|||||||
BIG_ENDIAN=0
|
BIG_ENDIAN=0
|
||||||
CONFIG_ZTEST=1
|
CONFIG_ZTEST=1
|
||||||
BACDL_ALL=1
|
BACDL_ALL=1
|
||||||
|
BACNET_NETWORK_PORT_IP_DHCP_ENABLED=1
|
||||||
BACNET_SECURE_CONNECT_ROUTING_TABLE=1
|
BACNET_SECURE_CONNECT_ROUTING_TABLE=1
|
||||||
BSC_CONF_HUB_FUNCTIONS_NUM=1
|
BSC_CONF_HUB_FUNCTIONS_NUM=1
|
||||||
BSC_CONF_HUB_CONNECTORS_NUM=1
|
BSC_CONF_HUB_CONNECTORS_NUM=1
|
||||||
|
|||||||
@@ -37,32 +37,51 @@ static void test_network_port(void)
|
|||||||
};
|
};
|
||||||
uint8_t test_address[16] = { 0 };
|
uint8_t test_address[16] = { 0 };
|
||||||
uint8_t mac_len;
|
uint8_t mac_len;
|
||||||
|
uint8_t max_master, max_info_frames;
|
||||||
uint8_t ip_prefix;
|
uint8_t ip_prefix;
|
||||||
uint32_t object_instance = 0;
|
uint32_t object_instance = 1234, test_object_instance = 0;
|
||||||
|
unsigned object_index = 0, test_object_index = 0;
|
||||||
|
BACNET_HOST_N_PORT host_n_port, test_host_n_port = { 0 };
|
||||||
|
BACNET_OCTET_STRING ip_address;
|
||||||
|
BACNET_IP_BROADCAST_DISTRIBUTION_TABLE_ENTRY bdt[2] = {
|
||||||
|
{ .valid = true,
|
||||||
|
.dest_address = { .address = { 1, 2, 3, 4 }, .port = 47808 },
|
||||||
|
.broadcast_mask = { .address = { 255, 255, 255, 255 } } },
|
||||||
|
{ .valid = true,
|
||||||
|
.dest_address = { .address = { 5, 6, 7, 8 }, .port = 47808 },
|
||||||
|
.broadcast_mask = { .address = { 255, 255, 255, 0 } } }
|
||||||
|
};
|
||||||
|
BACNET_IP_BROADCAST_DISTRIBUTION_TABLE_ENTRY *test_bdt;
|
||||||
|
BACNET_IP_FOREIGN_DEVICE_TABLE_ENTRY fdt[2] = {
|
||||||
|
{ .valid = true,
|
||||||
|
.dest_address = { .address = { 1, 2, 3, 4 }, .port = 47808 },
|
||||||
|
.ttl_seconds = 30,
|
||||||
|
.ttl_seconds_remaining = 30 },
|
||||||
|
{ .valid = true,
|
||||||
|
.dest_address = { .address = { 5, 6, 7, 8 }, .port = 47808 },
|
||||||
|
.ttl_seconds = 60,
|
||||||
|
.ttl_seconds_remaining = 60 }
|
||||||
|
};
|
||||||
|
BACNET_IP_FOREIGN_DEVICE_TABLE_ENTRY *test_fdt;
|
||||||
uint8_t port_type[] = { PORT_TYPE_ETHERNET, PORT_TYPE_ARCNET,
|
uint8_t port_type[] = { PORT_TYPE_ETHERNET, PORT_TYPE_ARCNET,
|
||||||
PORT_TYPE_MSTP, PORT_TYPE_PTP,
|
PORT_TYPE_MSTP, PORT_TYPE_PTP,
|
||||||
PORT_TYPE_LONTALK, PORT_TYPE_BIP,
|
PORT_TYPE_LONTALK, PORT_TYPE_BIP,
|
||||||
PORT_TYPE_ZIGBEE, PORT_TYPE_VIRTUAL,
|
PORT_TYPE_ZIGBEE, PORT_TYPE_VIRTUAL,
|
||||||
PORT_TYPE_NON_BACNET, PORT_TYPE_BIP6,
|
PORT_TYPE_NON_BACNET, PORT_TYPE_BIP6,
|
||||||
PORT_TYPE_BSC, PORT_TYPE_MAX };
|
PORT_TYPE_BSC, PORT_TYPE_MAX };
|
||||||
const int known_fail_property_list[] = {
|
const int known_fail_property_list[] = { -1 };
|
||||||
PROP_IP_DNS_SERVER,
|
|
||||||
PROP_BBMD_BROADCAST_DISTRIBUTION_TABLE,
|
|
||||||
PROP_BBMD_FOREIGN_DEVICE_TABLE,
|
|
||||||
PROP_FD_BBMD_ADDRESS,
|
|
||||||
PROP_IPV6_DNS_SERVER,
|
|
||||||
PROP_ISSUER_CERTIFICATE_FILES,
|
|
||||||
PROP_SC_HUB_FUNCTION_CONNECTION_STATUS,
|
|
||||||
PROP_SC_DIRECT_CONNECT_CONNECTION_STATUS,
|
|
||||||
PROP_SC_FAILED_CONNECTION_REQUESTS,
|
|
||||||
-1
|
|
||||||
};
|
|
||||||
|
|
||||||
while (port_type[port] != PORT_TYPE_MAX) {
|
while (port_type[port] != PORT_TYPE_MAX) {
|
||||||
Network_Port_Init();
|
Network_Port_Init();
|
||||||
object_instance = 1234;
|
status = Network_Port_Object_Instance_Number_Set(
|
||||||
status = Network_Port_Object_Instance_Number_Set(0, object_instance);
|
object_index, object_instance);
|
||||||
zassert_true(status, NULL);
|
zassert_true(status, NULL);
|
||||||
|
test_object_index = Network_Port_Instance_To_Index(object_instance);
|
||||||
|
zassert_equal(object_index, test_object_index, NULL);
|
||||||
|
test_object_instance = Network_Port_Index_To_Instance(object_index);
|
||||||
|
zassert_equal(object_instance, test_object_instance, NULL);
|
||||||
|
test_object_instance = Network_Port_Index_To_Instance(UINT_MAX);
|
||||||
|
zassert_equal(test_object_instance, BACNET_MAX_INSTANCE, NULL);
|
||||||
status = Network_Port_Type_Set(object_instance, port_type[port]);
|
status = Network_Port_Type_Set(object_instance, port_type[port]);
|
||||||
zassert_true(status, NULL);
|
zassert_true(status, NULL);
|
||||||
count = Network_Port_Count();
|
count = Network_Port_Count();
|
||||||
@@ -118,8 +137,18 @@ static void test_network_port(void)
|
|||||||
zassert_equal(address[0], 127, NULL);
|
zassert_equal(address[0], 127, NULL);
|
||||||
status = Network_Port_MSTP_Max_Info_Frames_Set(object_instance, 1);
|
status = Network_Port_MSTP_Max_Info_Frames_Set(object_instance, 1);
|
||||||
zassert_true(status, NULL);
|
zassert_true(status, NULL);
|
||||||
zassert_equal(
|
max_info_frames =
|
||||||
Network_Port_MSTP_Max_Info_Frames(object_instance), 1, NULL);
|
Network_Port_MSTP_Max_Info_Frames(object_instance);
|
||||||
|
zassert_equal(max_info_frames, 1, NULL);
|
||||||
|
Network_Port_MSTP_Max_Master_Set(object_instance, 127);
|
||||||
|
max_master = Network_Port_MSTP_Max_Master(object_instance);
|
||||||
|
zassert_equal(max_master, 127, NULL);
|
||||||
|
Network_Port_Changes_Pending_Set(object_instance, false);
|
||||||
|
status = Network_Port_MSTP_Max_Master_Set(object_instance, 63);
|
||||||
|
zassert_true(status, NULL);
|
||||||
|
max_master = Network_Port_MSTP_Max_Master(object_instance);
|
||||||
|
zassert_equal(max_master, 63, NULL);
|
||||||
|
zassert_true(Network_Port_Changes_Pending(object_instance), NULL);
|
||||||
}
|
}
|
||||||
if (port_type[port] == PORT_TYPE_BIP) {
|
if (port_type[port] == PORT_TYPE_BIP) {
|
||||||
status = Network_Port_IP_Address_Set(object_instance, 1, 2, 3, 4);
|
status = Network_Port_IP_Address_Set(object_instance, 1, 2, 3, 4);
|
||||||
@@ -134,6 +163,16 @@ static void test_network_port(void)
|
|||||||
zassert_true(status, NULL);
|
zassert_true(status, NULL);
|
||||||
status = Network_Port_IP_DHCP_Enable(object_instance);
|
status = Network_Port_IP_DHCP_Enable(object_instance);
|
||||||
zassert_true(status, NULL);
|
zassert_true(status, NULL);
|
||||||
|
Network_Port_IP_DHCP_Lease_Time_Set(object_instance, 60);
|
||||||
|
zassert_equal(
|
||||||
|
Network_Port_IP_DHCP_Lease_Time(object_instance), 60, NULL);
|
||||||
|
zassert_equal(
|
||||||
|
Network_Port_IP_DHCP_Lease_Time_Remaining(object_instance), 60,
|
||||||
|
NULL);
|
||||||
|
octetstring_init_ascii_hex(&ip_address, "0x0A0B0C0D");
|
||||||
|
status =
|
||||||
|
Network_Port_IP_DHCP_Server_Set(object_instance, &ip_address);
|
||||||
|
zassert_true(status, NULL);
|
||||||
status = Network_Port_IP_DNS_Server_Set(
|
status = Network_Port_IP_DNS_Server_Set(
|
||||||
object_instance, 0, 9, 10, 11, 12);
|
object_instance, 0, 9, 10, 11, 12);
|
||||||
zassert_true(status, NULL);
|
zassert_true(status, NULL);
|
||||||
@@ -151,21 +190,70 @@ static void test_network_port(void)
|
|||||||
status = Network_Port_BBMD_BD_Table_Set(object_instance, NULL);
|
status = Network_Port_BBMD_BD_Table_Set(object_instance, NULL);
|
||||||
zassert_true(status, NULL);
|
zassert_true(status, NULL);
|
||||||
zassert_is_null(Network_Port_BBMD_BD_Table(object_instance), NULL);
|
zassert_is_null(Network_Port_BBMD_BD_Table(object_instance), NULL);
|
||||||
|
bvlc_broadcast_distribution_table_link_array(bdt, ARRAY_SIZE(bdt));
|
||||||
|
status = Network_Port_BBMD_BD_Table_Set(object_instance, bdt);
|
||||||
|
zassert_true(status, NULL);
|
||||||
|
test_bdt = Network_Port_BBMD_BD_Table(object_instance);
|
||||||
|
zassert_not_null(test_bdt, NULL);
|
||||||
|
zassert_equal(
|
||||||
|
test_bdt->dest_address.address[0],
|
||||||
|
bdt[0].dest_address.address[0], NULL);
|
||||||
status = Network_Port_BBMD_FD_Table_Set(object_instance, NULL);
|
status = Network_Port_BBMD_FD_Table_Set(object_instance, NULL);
|
||||||
zassert_true(status, NULL);
|
zassert_true(status, NULL);
|
||||||
zassert_is_null(Network_Port_BBMD_FD_Table(object_instance), NULL);
|
zassert_is_null(Network_Port_BBMD_FD_Table(object_instance), NULL);
|
||||||
|
bvlc_foreign_device_table_link_array(fdt, ARRAY_SIZE(fdt));
|
||||||
|
status = Network_Port_BBMD_FD_Table_Set(object_instance, &fdt[0]);
|
||||||
|
zassert_true(status, NULL);
|
||||||
|
test_fdt = Network_Port_BBMD_FD_Table(object_instance);
|
||||||
|
zassert_not_null(test_fdt, NULL);
|
||||||
|
zassert_equal(
|
||||||
|
test_fdt->dest_address.address[0],
|
||||||
|
fdt[0].dest_address.address[0], NULL);
|
||||||
status = Network_Port_Remote_BBMD_IP_Address(
|
status = Network_Port_Remote_BBMD_IP_Address(
|
||||||
object_instance, NULL, NULL, NULL, NULL);
|
object_instance, NULL, NULL, NULL, NULL);
|
||||||
zassert_true(status, NULL);
|
zassert_false(status, NULL);
|
||||||
status = Network_Port_Remote_BBMD_IP_Address_Set(
|
status = Network_Port_Remote_BBMD_IP_Address_Set(
|
||||||
object_instance, 1, 2, 3, 4);
|
object_instance, 1, 2, 3, 4);
|
||||||
zassert_true(status, NULL);
|
zassert_true(status, NULL);
|
||||||
|
status = Network_Port_Remote_BBMD_IP_Address(
|
||||||
|
object_instance, &test_address[0], &test_address[1],
|
||||||
|
&test_address[2], &test_address[3]);
|
||||||
|
zassert_true(status, NULL);
|
||||||
|
status = Network_Port_Remote_BBMD_IP_Address(
|
||||||
|
object_instance, NULL, NULL, NULL, NULL);
|
||||||
|
zassert_true(status, NULL);
|
||||||
|
zassert_equal(test_address[0], 1, NULL);
|
||||||
|
zassert_equal(test_address[1], 2, NULL);
|
||||||
|
zassert_equal(test_address[2], 3, NULL);
|
||||||
|
zassert_equal(test_address[3], 4, NULL);
|
||||||
|
Network_Port_Changes_Pending_Set(object_instance, false);
|
||||||
|
status = Network_Port_Remote_BBMD_IP_Address_Set(
|
||||||
|
object_instance, 5, 6, 7, 8);
|
||||||
|
zassert_true(status, NULL);
|
||||||
|
zassert_true(Network_Port_Changes_Pending(object_instance), NULL);
|
||||||
status =
|
status =
|
||||||
Network_Port_Remote_BBMD_BIP_Port_Set(object_instance, 47808);
|
Network_Port_Remote_BBMD_BIP_Port_Set(object_instance, 47808);
|
||||||
zassert_true(status, NULL);
|
zassert_true(status, NULL);
|
||||||
zassert_equal(
|
zassert_equal(
|
||||||
Network_Port_Remote_BBMD_BIP_Port(object_instance), 47808,
|
Network_Port_Remote_BBMD_BIP_Port(object_instance), 47808,
|
||||||
NULL);
|
NULL);
|
||||||
|
Network_Port_Remote_BBMD_Address(object_instance, &host_n_port);
|
||||||
|
zassert_false(host_n_port.host_name, NULL);
|
||||||
|
zassert_true(host_n_port.host_ip_address, NULL);
|
||||||
|
zassert_equal(host_n_port.port, 47808, NULL);
|
||||||
|
test_host_n_port.host_ip_address = false;
|
||||||
|
test_host_n_port.host_name = true;
|
||||||
|
characterstring_init_ansi(
|
||||||
|
&test_host_n_port.host.name, "bbmd.example.com");
|
||||||
|
test_host_n_port.port = 47808;
|
||||||
|
Network_Port_Remote_BBMD_Address_Set(
|
||||||
|
object_instance, &test_host_n_port);
|
||||||
|
Network_Port_Remote_BBMD_Address(object_instance, &host_n_port);
|
||||||
|
zassert_false(host_n_port.host_ip_address, NULL);
|
||||||
|
zassert_true(host_n_port.host_name, NULL);
|
||||||
|
zassert_equal(host_n_port.port, 47808, NULL);
|
||||||
|
characterstring_ansi_same(
|
||||||
|
&test_host_n_port.host.name, "bbmd.example.com");
|
||||||
status =
|
status =
|
||||||
Network_Port_Remote_BBMD_BIP_Lifetime_Set(object_instance, 60);
|
Network_Port_Remote_BBMD_BIP_Lifetime_Set(object_instance, 60);
|
||||||
zassert_true(status, NULL);
|
zassert_true(status, NULL);
|
||||||
@@ -192,16 +280,33 @@ static void test_network_port(void)
|
|||||||
Network_Port_BBMD_IP6_FD_Table(object_instance), NULL);
|
Network_Port_BBMD_IP6_FD_Table(object_instance), NULL);
|
||||||
status =
|
status =
|
||||||
Network_Port_Remote_BBMD_IP6_Address(object_instance, address);
|
Network_Port_Remote_BBMD_IP6_Address(object_instance, address);
|
||||||
zassert_true(status, NULL);
|
zassert_false(status, NULL);
|
||||||
status = Network_Port_Remote_BBMD_IP6_Address_Set(
|
status = Network_Port_Remote_BBMD_IP6_Address_Set(
|
||||||
object_instance, address);
|
object_instance, address);
|
||||||
zassert_true(status, NULL);
|
zassert_true(status, NULL);
|
||||||
status =
|
status =
|
||||||
Network_Port_Remote_BBMD_BIP6_Port_Set(object_instance, 47808);
|
Network_Port_Remote_BBMD_BIP6_Port_Set(object_instance, 47808);
|
||||||
zassert_true(status, NULL);
|
zassert_true(status, NULL);
|
||||||
|
status =
|
||||||
|
Network_Port_Remote_BBMD_IP6_Address(object_instance, address);
|
||||||
|
zassert_true(status, NULL);
|
||||||
zassert_equal(
|
zassert_equal(
|
||||||
Network_Port_Remote_BBMD_BIP6_Port(object_instance), 47808,
|
Network_Port_Remote_BBMD_BIP6_Port(object_instance), 47808,
|
||||||
NULL);
|
NULL);
|
||||||
|
Network_Port_Remote_BBMD_Address(object_instance, &host_n_port);
|
||||||
|
zassert_true(host_n_port.host_ip_address, NULL);
|
||||||
|
zassert_equal(host_n_port.port, 47808, NULL);
|
||||||
|
test_host_n_port.host_ip_address = false;
|
||||||
|
test_host_n_port.host_name = true;
|
||||||
|
characterstring_init_ansi(
|
||||||
|
&test_host_n_port.host.name, "bbmd.example.com");
|
||||||
|
test_host_n_port.port = 47808;
|
||||||
|
Network_Port_Remote_BBMD_Address_Set(
|
||||||
|
object_instance, &test_host_n_port);
|
||||||
|
Network_Port_Remote_BBMD_Address(object_instance, &host_n_port);
|
||||||
|
zassert_false(host_n_port.host_ip_address, NULL);
|
||||||
|
zassert_true(host_n_port.host_name, NULL);
|
||||||
|
zassert_equal(host_n_port.port, 47808, NULL);
|
||||||
status =
|
status =
|
||||||
Network_Port_Remote_BBMD_BIP6_Lifetime_Set(object_instance, 60);
|
Network_Port_Remote_BBMD_BIP6_Lifetime_Set(object_instance, 60);
|
||||||
zassert_true(status, NULL);
|
zassert_true(status, NULL);
|
||||||
@@ -226,8 +331,21 @@ static void test_network_port(void)
|
|||||||
status = Network_Port_IPv6_Multicast_Address_Set(
|
status = Network_Port_IPv6_Multicast_Address_Set(
|
||||||
object_instance, address);
|
object_instance, address);
|
||||||
zassert_true(status, NULL);
|
zassert_true(status, NULL);
|
||||||
|
status = Network_Port_IP_DHCP_Enable_Set(object_instance, true);
|
||||||
|
zassert_true(status, NULL);
|
||||||
|
status = Network_Port_IP_DHCP_Enable(object_instance);
|
||||||
|
zassert_true(status, NULL);
|
||||||
|
Network_Port_IP_DHCP_Lease_Time_Set(object_instance, 60);
|
||||||
|
zassert_equal(
|
||||||
|
Network_Port_IP_DHCP_Lease_Time(object_instance), 60, NULL);
|
||||||
|
zassert_equal(
|
||||||
|
Network_Port_IP_DHCP_Lease_Time_Remaining(object_instance), 60,
|
||||||
|
NULL);
|
||||||
status =
|
status =
|
||||||
Network_Port_IPv6_DHCP_Server_Set(object_instance, address);
|
Network_Port_IPv6_DHCP_Server_Set(object_instance, address);
|
||||||
|
octetstring_init(&ip_address, address, sizeof(address));
|
||||||
|
status =
|
||||||
|
Network_Port_IP_DHCP_Server_Set(object_instance, &ip_address);
|
||||||
zassert_true(status, NULL);
|
zassert_true(status, NULL);
|
||||||
status = Network_Port_BIP6_Port_Set(object_instance, 47808);
|
status = Network_Port_BIP6_Port_Set(object_instance, 47808);
|
||||||
zassert_true(status, NULL);
|
zassert_true(status, NULL);
|
||||||
@@ -257,7 +375,10 @@ static void test_network_port(void)
|
|||||||
Network_Port_Object_Name_ASCII);
|
Network_Port_Object_Name_ASCII);
|
||||||
port++;
|
port++;
|
||||||
Network_Port_Changes_Activate();
|
Network_Port_Changes_Activate();
|
||||||
|
zassert_false(Network_Port_Changes_Pending(object_instance), NULL);
|
||||||
|
Network_Port_Changes_Pending_Set(object_instance, true);
|
||||||
Network_Port_Changes_Discard();
|
Network_Port_Changes_Discard();
|
||||||
|
zassert_false(Network_Port_Changes_Pending(object_instance), NULL);
|
||||||
Network_Port_Cleanup();
|
Network_Port_Cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,43 @@
|
|||||||
#include <bacnet/bacdest.h>
|
#include <bacnet/bacdest.h>
|
||||||
#include <bacnet/hostnport.h>
|
#include <bacnet/hostnport.h>
|
||||||
|
|
||||||
|
#if defined(CONFIG_ZTEST_NEW_API)
|
||||||
|
ZTEST(create_object_tests, test_HostNPortMinimal_Init)
|
||||||
|
#else
|
||||||
|
static void test_HostNPortMinimal_Init(void)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
BACNET_HOST_N_PORT_MINIMAL test_data_1 = { 0 }, test_data_2 = { 0 };
|
||||||
|
BACNET_HOST_N_PORT host_n_port = { 0 };
|
||||||
|
uint8_t address[IP6_ADDRESS_MAX] = { 1, 2, 3, 4, 5, 6, 7, 8,
|
||||||
|
9, 10, 11, 12, 13, 14, 15, 16 };
|
||||||
|
uint16_t port = 0xBAC0;
|
||||||
|
|
||||||
|
/* test the init */
|
||||||
|
host_n_port_minimal_ip_init(&test_data_1, port, address, sizeof(address));
|
||||||
|
zassert_equal(test_data_1.tag, BACNET_HOST_ADDRESS_TAG_IP_ADDRESS, NULL);
|
||||||
|
zassert_equal(test_data_1.port, port, NULL);
|
||||||
|
zassert_equal(test_data_1.host.ip_address.length, sizeof(address), NULL);
|
||||||
|
zassert_mem_equal(
|
||||||
|
test_data_1.host.ip_address.address, address, sizeof(address), NULL);
|
||||||
|
host_n_port_from_minimal(&host_n_port, &test_data_1);
|
||||||
|
host_n_port_to_minimal(&test_data_2, &host_n_port);
|
||||||
|
zassert_true(
|
||||||
|
host_n_port_minimal_same(&test_data_1, &test_data_2),
|
||||||
|
"test_data_1 != test_data_2");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_HostNPortMinimal_Copy(BACNET_HOST_N_PORT *data)
|
||||||
|
{
|
||||||
|
BACNET_HOST_N_PORT_MINIMAL test_data_1 = { 0 }, test_data_2 = { 0 };
|
||||||
|
|
||||||
|
host_n_port_to_minimal(&test_data_1, data);
|
||||||
|
host_n_port_minimal_copy(&test_data_2, &test_data_1);
|
||||||
|
zassert_true(
|
||||||
|
host_n_port_minimal_same(&test_data_1, &test_data_2),
|
||||||
|
"test_data_1 != test_data_2");
|
||||||
|
}
|
||||||
|
|
||||||
static void test_HostNPortCodec(BACNET_HOST_N_PORT *data)
|
static void test_HostNPortCodec(BACNET_HOST_N_PORT *data)
|
||||||
{
|
{
|
||||||
uint8_t apdu[MAX_APDU] = { 0 };
|
uint8_t apdu[MAX_APDU] = { 0 };
|
||||||
@@ -72,12 +109,82 @@ static void test_HostNPort(void)
|
|||||||
data.host_name = false;
|
data.host_name = false;
|
||||||
data.port = 0xBAC0;
|
data.port = 0xBAC0;
|
||||||
test_HostNPortCodec(&data);
|
test_HostNPortCodec(&data);
|
||||||
|
test_HostNPortMinimal_Copy(&data);
|
||||||
/* Host Name */
|
/* Host Name */
|
||||||
characterstring_init_ansi(&data.host.name, "bacnet.org");
|
characterstring_init_ansi(&data.host.name, "bacnet.org");
|
||||||
data.host_ip_address = false;
|
data.host_ip_address = false;
|
||||||
data.host_name = true;
|
data.host_name = true;
|
||||||
data.port = 0xBAC0;
|
data.port = 0xBAC0;
|
||||||
test_HostNPortCodec(&data);
|
test_HostNPortCodec(&data);
|
||||||
|
test_HostNPortMinimal_Copy(&data);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_ZTEST_NEW_API)
|
||||||
|
ZTEST(create_object_tests, test_is_valid_hostname)
|
||||||
|
#else
|
||||||
|
static void test_is_valid_hostname(void)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
bool status = false;
|
||||||
|
BACNET_CHARACTER_STRING hostname;
|
||||||
|
|
||||||
|
status = characterstring_init_ansi(&hostname, "valid.host.name");
|
||||||
|
zassert_true(status, NULL);
|
||||||
|
status = bacnet_is_valid_hostname(&hostname);
|
||||||
|
zassert_true(status, NULL);
|
||||||
|
|
||||||
|
status = characterstring_init_ansi(&hostname, "invalid..host.name");
|
||||||
|
zassert_true(status, NULL);
|
||||||
|
status = bacnet_is_valid_hostname(&hostname);
|
||||||
|
zassert_false(status, NULL);
|
||||||
|
|
||||||
|
status = characterstring_init_ansi(&hostname, "-invalid.host.name");
|
||||||
|
zassert_true(status, NULL);
|
||||||
|
status = bacnet_is_valid_hostname(&hostname);
|
||||||
|
zassert_false(status, NULL);
|
||||||
|
|
||||||
|
status = characterstring_init_ansi(&hostname, "valid.host-name");
|
||||||
|
zassert_true(status, NULL);
|
||||||
|
status = bacnet_is_valid_hostname(&hostname);
|
||||||
|
zassert_true(status, NULL);
|
||||||
|
|
||||||
|
status = characterstring_init_ansi(&hostname, "invalid.host--name");
|
||||||
|
zassert_true(status, NULL);
|
||||||
|
status = bacnet_is_valid_hostname(&hostname);
|
||||||
|
zassert_false(status, NULL);
|
||||||
|
|
||||||
|
status = characterstring_init_ansi(&hostname, "invalid.host name");
|
||||||
|
zassert_true(status, NULL);
|
||||||
|
status = bacnet_is_valid_hostname(&hostname);
|
||||||
|
zassert_false(status, NULL);
|
||||||
|
|
||||||
|
status = characterstring_init_ansi(&hostname, "valid.host.123.name");
|
||||||
|
zassert_true(status, NULL);
|
||||||
|
status = bacnet_is_valid_hostname(&hostname);
|
||||||
|
zassert_true(status, NULL);
|
||||||
|
|
||||||
|
{
|
||||||
|
char too_long_label[65] = { 0 };
|
||||||
|
memset(too_long_label, 'l', sizeof(too_long_label) - 1);
|
||||||
|
status = characterstring_init_ansi(&hostname, too_long_label);
|
||||||
|
zassert_true(status, NULL);
|
||||||
|
status = bacnet_is_valid_hostname(&hostname);
|
||||||
|
zassert_false(status, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
char max_length_label[64] = { 0 };
|
||||||
|
memset(max_length_label, 'l', sizeof(max_length_label) - 1);
|
||||||
|
status = characterstring_init_ansi(&hostname, max_length_label);
|
||||||
|
zassert_true(status, NULL);
|
||||||
|
status = bacnet_is_valid_hostname(&hostname);
|
||||||
|
zassert_true(status, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
status = characterstring_init_ansi(&hostname, "non-alpanumer!c.host name");
|
||||||
|
zassert_true(status, NULL);
|
||||||
|
status = bacnet_is_valid_hostname(&hostname);
|
||||||
|
zassert_false(status, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_ZTEST_NEW_API)
|
#if defined(CONFIG_ZTEST_NEW_API)
|
||||||
@@ -85,7 +192,10 @@ ZTEST_SUITE(host_n_port_tests, NULL, NULL, NULL, NULL, NULL);
|
|||||||
#else
|
#else
|
||||||
void test_main(void)
|
void test_main(void)
|
||||||
{
|
{
|
||||||
ztest_test_suite(host_n_port_tests, ztest_unit_test(test_HostNPort));
|
ztest_test_suite(
|
||||||
|
host_n_port_tests, ztest_unit_test(test_HostNPort),
|
||||||
|
ztest_unit_test(test_HostNPortMinimal_Init),
|
||||||
|
ztest_unit_test(test_is_valid_hostname));
|
||||||
|
|
||||||
ztest_run_test_suite(host_n_port_tests);
|
ztest_run_test_suite(host_n_port_tests);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user