Run clang-format and enable CI check for it (#755)
* pre-commit: Update and enable clang-format check There is newer version from clang-format so use that. We do not yet want 18 as that is little bit too new. * Format some thing by hand which clang-format "breaks" Clang-format will format some things little bit off in some cases. Format some things by hand so we get cleaner end result. * Run clang-format with ``` pre-commit run --all-files clang-format ``` We have already in previously checked places where clang-format does not make good format and ignored those (hopefully most of the things). --------- Co-authored-by: Kari Argillander <kari.argillander@fidelix.com>
This commit is contained in:
@@ -34,7 +34,8 @@ bool apdu_service_supported(BACNET_SERVICES_SUPPORTED service_supported)
|
||||
return status;
|
||||
}
|
||||
|
||||
uint16_t apdu_decode_confirmed_service_request(uint8_t *apdu, /* APDU data */
|
||||
uint16_t apdu_decode_confirmed_service_request(
|
||||
uint8_t *apdu, /* APDU data */
|
||||
|
||||
uint16_t apdu_len,
|
||||
BACNET_CONFIRMED_SERVICE_DATA *service_data,
|
||||
@@ -63,7 +64,8 @@ uint16_t apdu_decode_confirmed_service_request(uint8_t *apdu, /* APDU data */
|
||||
return len;
|
||||
}
|
||||
|
||||
void apdu_handler(BACNET_ADDRESS *src,
|
||||
void apdu_handler(
|
||||
BACNET_ADDRESS *src,
|
||||
uint8_t *apdu, /* APDU data */
|
||||
|
||||
uint16_t apdu_len)
|
||||
@@ -87,18 +89,21 @@ void apdu_handler(BACNET_ADDRESS *src,
|
||||
break;
|
||||
}
|
||||
if (service_choice == SERVICE_CONFIRMED_READ_PROPERTY) {
|
||||
handler_read_property(service_request, service_request_len,
|
||||
src, &service_data);
|
||||
handler_read_property(
|
||||
service_request, service_request_len, src,
|
||||
&service_data);
|
||||
}
|
||||
#ifdef WRITE_PROPERTY
|
||||
else if (service_choice == SERVICE_CONFIRMED_WRITE_PROPERTY) {
|
||||
handler_write_property(service_request, service_request_len,
|
||||
src, &service_data);
|
||||
handler_write_property(
|
||||
service_request, service_request_len, src,
|
||||
&service_data);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
handler_unrecognized_service(service_request,
|
||||
service_request_len, src, &service_data);
|
||||
handler_unrecognized_service(
|
||||
service_request, service_request_len, src,
|
||||
&service_data);
|
||||
}
|
||||
break;
|
||||
case PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST:
|
||||
|
||||
@@ -29,8 +29,9 @@ float AV_Present_Value[MAX_ANALOG_VALUES];
|
||||
/* given instance exists */
|
||||
bool Analog_Value_Valid_Instance(uint32_t object_instance)
|
||||
{
|
||||
if (object_instance < MAX_ANALOG_VALUES)
|
||||
if (object_instance < MAX_ANALOG_VALUES) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -69,7 +70,8 @@ char *Analog_Value_Name(uint32_t object_instance)
|
||||
}
|
||||
|
||||
/* return apdu len, or -1 on error */
|
||||
int Analog_Value_Encode_Property_APDU(uint8_t *apdu,
|
||||
int Analog_Value_Encode_Property_APDU(
|
||||
uint8_t *apdu,
|
||||
uint32_t object_instance,
|
||||
BACNET_PROPERTY_ID property,
|
||||
uint32_t array_index,
|
||||
@@ -136,7 +138,8 @@ int Analog_Value_Encode_Property_APDU(uint8_t *apdu,
|
||||
}
|
||||
|
||||
/* returns true if successful */
|
||||
bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data,
|
||||
bool Analog_Value_Write_Property(
|
||||
BACNET_WRITE_PROPERTY_DATA *wp_data,
|
||||
BACNET_ERROR_CLASS *error_class,
|
||||
BACNET_ERROR_CODE *error_code)
|
||||
{
|
||||
|
||||
+27
-27
@@ -1,10 +1,10 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
*
|
||||
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
#ifndef AV_H
|
||||
#define AV_H
|
||||
|
||||
@@ -21,31 +21,31 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
void Analog_Value_Property_Lists(const int **pRequired,
|
||||
const int **pOptional,
|
||||
const int **pProprietary);
|
||||
bool Analog_Value_Valid_Instance(uint32_t object_instance);
|
||||
unsigned Analog_Value_Count(void);
|
||||
uint32_t Analog_Value_Index_To_Instance(unsigned index);
|
||||
char *Analog_Value_Name(uint32_t object_instance);
|
||||
void Analog_Value_Property_Lists(
|
||||
const int **pRequired, const int **pOptional, const int **pProprietary);
|
||||
bool Analog_Value_Valid_Instance(uint32_t object_instance);
|
||||
unsigned Analog_Value_Count(void);
|
||||
uint32_t Analog_Value_Index_To_Instance(unsigned index);
|
||||
char *Analog_Value_Name(uint32_t object_instance);
|
||||
|
||||
int Analog_Value_Encode_Property_APDU(uint8_t * apdu,
|
||||
uint32_t object_instance,
|
||||
BACNET_PROPERTY_ID property,
|
||||
uint32_t array_index,
|
||||
BACNET_ERROR_CLASS * error_class,
|
||||
BACNET_ERROR_CODE * error_code);
|
||||
int Analog_Value_Encode_Property_APDU(
|
||||
uint8_t *apdu,
|
||||
uint32_t object_instance,
|
||||
BACNET_PROPERTY_ID property,
|
||||
uint32_t array_index,
|
||||
BACNET_ERROR_CLASS *error_class,
|
||||
BACNET_ERROR_CODE *error_code);
|
||||
|
||||
bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
||||
BACNET_ERROR_CLASS * error_class,
|
||||
BACNET_ERROR_CODE * error_code);
|
||||
bool Analog_Value_Write_Property(
|
||||
BACNET_WRITE_PROPERTY_DATA *wp_data,
|
||||
BACNET_ERROR_CLASS *error_class,
|
||||
BACNET_ERROR_CODE *error_code);
|
||||
|
||||
bool Analog_Value_Present_Value_Set(uint32_t object_instance,
|
||||
float value,
|
||||
uint8_t priority);
|
||||
float Analog_Value_Present_Value(uint32_t object_instance);
|
||||
bool Analog_Value_Present_Value_Set(
|
||||
uint32_t object_instance, float value, uint8_t priority);
|
||||
float Analog_Value_Present_Value(uint32_t object_instance);
|
||||
|
||||
void Analog_Value_Init(void);
|
||||
void Analog_Value_Init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include "bacnet/datalink/bip.h"
|
||||
#include "socketWrapper.h"
|
||||
#include "w5100Wrapper.h"
|
||||
//#include "bacport.h"
|
||||
// #include "bacport.h"
|
||||
|
||||
/** @file linux/bip-init.c Initializes BACnet/IP interface (Linux). */
|
||||
|
||||
@@ -61,7 +61,8 @@ void bip_set_interface(const char *ifname)
|
||||
bip_set_addr(local_address);
|
||||
if (BIP_Debug) {
|
||||
fprintf(stderr, "Interface: %s\n", ifname);
|
||||
fprintf(stderr, "IP Address: %d.%d.%d.%d\n", local_address[0],
|
||||
fprintf(
|
||||
stderr, "IP Address: %d.%d.%d.%d\n", local_address[0],
|
||||
local_address[1], local_address[2], local_address[3]);
|
||||
}
|
||||
|
||||
@@ -74,9 +75,9 @@ void bip_set_interface(const char *ifname)
|
||||
|
||||
bip_set_broadcast_addr(broadcast_address);
|
||||
if (BIP_Debug) {
|
||||
fprintf(stderr, "IP Broadcast Address: %d.%d.%d.%d\n",
|
||||
broadcast_address[0], broadcast_address[1], broadcast_address[2],
|
||||
broadcast_address[3]);
|
||||
fprintf(
|
||||
stderr, "IP Broadcast Address: %d.%d.%d.%d\n", broadcast_address[0],
|
||||
broadcast_address[1], broadcast_address[2], broadcast_address[3]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,10 +103,11 @@ bool bip_init(char *ifname)
|
||||
uint8_t sock_fd = 0;
|
||||
bool isOpen = false;
|
||||
|
||||
if (ifname)
|
||||
if (ifname) {
|
||||
bip_set_interface(ifname);
|
||||
else
|
||||
} else {
|
||||
bip_set_interface("eth0");
|
||||
}
|
||||
|
||||
/* assumes that the driver has already been initialized */
|
||||
for (sock_fd = 0; sock_fd < MAX_SOCK_NUM; sock_fd++) {
|
||||
|
||||
+27
-15
@@ -37,7 +37,7 @@ static uint8_t BIP_Broadcast_Address[4] = { 0, 0, 0, 0 };
|
||||
uint32_t convertBIP_Address2uint32(const suint8_t *bip_address)
|
||||
{
|
||||
return (uint32_t)((bip_address[0] * 2 ^ 24) + (bip_address[1] * 2 ^ 16) +
|
||||
(bip_address[2] * 2 ^ 8) + bip_address[3]);
|
||||
(bip_address[2] * 2 ^ 8) + bip_address[3]);
|
||||
}
|
||||
|
||||
/** Convert from uint32_t IPv4 address to uint8_t[4] address
|
||||
@@ -76,8 +76,9 @@ bool bip_valid(void)
|
||||
|
||||
void bip_set_addr(const uint8_t *net_address)
|
||||
{ /* in network byte order */
|
||||
for (uint8_t i = 0; i < 4; i++)
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
BIP_Address[i] = net_address[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* returns network byte order */
|
||||
@@ -88,8 +89,9 @@ uint8_t *bip_get_addr(void)
|
||||
|
||||
void bip_set_broadcast_addr(const uint8_t *net_address)
|
||||
{ /* in network byte order */
|
||||
for (uint8_t i = 0; i < 4; i++)
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
BIP_Broadcast_Address[i] = net_address[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* returns network byte order */
|
||||
@@ -109,7 +111,8 @@ uint16_t bip_get_port(void)
|
||||
return ntohs(BIP_Port);
|
||||
}
|
||||
|
||||
static int bip_decode_bip_address(const BACNET_ADDRESS *bac_addr,
|
||||
static int bip_decode_bip_address(
|
||||
const BACNET_ADDRESS *bac_addr,
|
||||
uint8_t *address, /* in network format */
|
||||
uint16_t *port)
|
||||
{ /* in network format */
|
||||
@@ -133,7 +136,8 @@ static int bip_decode_bip_address(const BACNET_ADDRESS *bac_addr,
|
||||
* @param pdu_len [in] Number of bytes in the pdu buffer.
|
||||
* @return Number of bytes sent on success, negative number on failure.
|
||||
*/
|
||||
int bip_send_pdu(BACNET_ADDRESS *dest, /* destination address */
|
||||
int bip_send_pdu(
|
||||
BACNET_ADDRESS *dest, /* destination address */
|
||||
|
||||
BACNET_NPDU_DATA *npdu_data, /* network information */
|
||||
|
||||
@@ -159,19 +163,22 @@ int bip_send_pdu(BACNET_ADDRESS *dest, /* destination address */
|
||||
if ((dest->net == BACNET_BROADCAST_NETWORK) ||
|
||||
((dest->net > 0) && (dest->len == 0)) || (dest->mac_len == 0)) {
|
||||
/* broadcast */
|
||||
for (uint8_t i = 0; i < 4; i++)
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
address[i] = BIP_Broadcast_Address[i];
|
||||
}
|
||||
port = BIP_Port;
|
||||
mtu[1] = BVLC_ORIGINAL_BROADCAST_NPDU;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Send Broadcast NPDU to %d.%d.%d.%d:%d\n", address[0],
|
||||
fprintf(
|
||||
stderr, "Send Broadcast NPDU to %d.%d.%d.%d:%d\n", address[0],
|
||||
address[1], address[2], address[3], port);
|
||||
#endif
|
||||
} else if (dest->mac_len == 6) {
|
||||
bip_decode_bip_address(dest, address, &port);
|
||||
mtu[1] = BVLC_ORIGINAL_UNICAST_NPDU;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Send Unicast NPDU to %d.%d.%d.%d:%d\n", address[0],
|
||||
fprintf(
|
||||
stderr, "Send Unicast NPDU to %d.%d.%d.%d:%d\n", address[0],
|
||||
address[1], address[2], address[3], port);
|
||||
#endif
|
||||
} else {
|
||||
@@ -207,7 +214,8 @@ int bip_send_pdu(BACNET_ADDRESS *dest, /* destination address */
|
||||
* @param timeout [in] The number of milliseconds to wait for a packet.
|
||||
* @return The number of octets (remaining) in the PDU, or zero on failure.
|
||||
*/
|
||||
uint16_t bip_receive(BACNET_ADDRESS *src, /* source address */
|
||||
uint16_t bip_receive(
|
||||
BACNET_ADDRESS *src, /* source address */
|
||||
|
||||
uint8_t *pdu, /* PDU data */
|
||||
|
||||
@@ -224,8 +232,9 @@ uint16_t bip_receive(BACNET_ADDRESS *src, /* source address */
|
||||
int function = 0;
|
||||
|
||||
/* Make sure the socket is open */
|
||||
if (BIP_Socket < 0)
|
||||
if (BIP_Socket < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (getRXReceivedSize_func(CW5100Class_new(), BIP_Socket)) {
|
||||
memcpy(&src_addr, &src->mac[0], 4);
|
||||
@@ -240,12 +249,14 @@ uint16_t bip_receive(BACNET_ADDRESS *src, /* source address */
|
||||
}
|
||||
|
||||
/* no problem, just no bytes */
|
||||
if (received_bytes == 0)
|
||||
if (received_bytes == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* the signature of a BACnet/IP packet */
|
||||
if (pdu[0] != BVLL_TYPE_BACNET_IP)
|
||||
if (pdu[0] != BVLL_TYPE_BACNET_IP) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Erase up to 16 bytes after the received bytes as safety margin to
|
||||
* ensure that the decoding functions will run into a 'safe field'
|
||||
@@ -272,7 +283,7 @@ uint16_t bip_receive(BACNET_ADDRESS *src, /* source address */
|
||||
(function == BVLC_ORIGINAL_BROADCAST_NPDU)) {
|
||||
/* ignore messages from me */
|
||||
if ((convertBIP_Address2uint32(src_addr) ==
|
||||
convertBIP_Address2uint32(BIP_Address)) &&
|
||||
convertBIP_Address2uint32(BIP_Address)) &&
|
||||
(src_port == BIP_Port)) {
|
||||
pdu_len = 0;
|
||||
#if 0
|
||||
@@ -284,7 +295,8 @@ uint16_t bip_receive(BACNET_ADDRESS *src, /* source address */
|
||||
memcpy(&src->mac[0], &src_addr, 4);
|
||||
memcpy(&src->mac[4], &src_port, 2);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "BIP receive from %d.%d.%d.%d\n", src->mac[0],
|
||||
fprintf(
|
||||
stderr, "BIP receive from %d.%d.%d.%d\n", src->mac[0],
|
||||
src->mac[1], src->mac[2], src->mac[3]);
|
||||
#endif
|
||||
/* FIXME: check destination address */
|
||||
@@ -321,7 +333,7 @@ uint16_t bip_receive(BACNET_ADDRESS *src, /* source address */
|
||||
memcpy(&src_addr, &pdu[4], 4);
|
||||
memcpy(&src_port, &pdu[8], 2);
|
||||
if ((convertBIP_Address2uint32(src_addr) ==
|
||||
convertBIP_Address2uint32(BIP_Address)) &&
|
||||
convertBIP_Address2uint32(BIP_Address)) &&
|
||||
(src_port == BIP_Port)) {
|
||||
/* ignore messages from me */
|
||||
pdu_len = 0;
|
||||
|
||||
+56
-55
@@ -1,10 +1,10 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2012 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
*
|
||||
* Copyright (C) 2012 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
#ifndef BIP_H
|
||||
#define BIP_H
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
/* specific defines for BACnet/IP over Ethernet */
|
||||
#define BIP_HEADER_MAX (1 + 1 + 2)
|
||||
#define BIP_MPDU_MAX (BIP_HEADER_MAX+MAX_PDU)
|
||||
#define BIP_MPDU_MAX (BIP_HEADER_MAX + MAX_PDU)
|
||||
|
||||
#define BVLL_TYPE_BACNET_IP (0x81)
|
||||
|
||||
@@ -24,69 +24,70 @@
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* note: define init, set_interface, and cleanup in your port */
|
||||
/* on Linux, ifname is eth0, ath0, arc0, and others.
|
||||
on Windows, ifname is the dotted ip address of the interface */
|
||||
bool bip_init(char *ifname);
|
||||
void bip_set_interface(const char *ifname);
|
||||
void bip_cleanup(void);
|
||||
/* note: define init, set_interface, and cleanup in your port */
|
||||
/* on Linux, ifname is eth0, ath0, arc0, and others.
|
||||
on Windows, ifname is the dotted ip address of the interface */
|
||||
bool bip_init(char *ifname);
|
||||
void bip_set_interface(const char *ifname);
|
||||
void bip_cleanup(void);
|
||||
|
||||
/* Convert uint8_t IPv4 to uint32 */
|
||||
uint32_t convertBIP_Address2uint32(const uint8_t * bip_address);
|
||||
void convertUint32Address_2_uint8Address(uint32_t ip,
|
||||
uint8_t * address);
|
||||
/* common BACnet/IP functions */
|
||||
void bip_set_socket(uint8_t sock_fd);
|
||||
uint8_t bip_socket(void);
|
||||
bool bip_valid(void);
|
||||
void bip_get_broadcast_address(BACNET_ADDRESS * dest); /* destination address */
|
||||
void bip_get_my_address(BACNET_ADDRESS * my_address);
|
||||
/* Convert uint8_t IPv4 to uint32 */
|
||||
uint32_t convertBIP_Address2uint32(const uint8_t *bip_address);
|
||||
void convertUint32Address_2_uint8Address(uint32_t ip, uint8_t *address);
|
||||
/* common BACnet/IP functions */
|
||||
void bip_set_socket(uint8_t sock_fd);
|
||||
uint8_t bip_socket(void);
|
||||
bool bip_valid(void);
|
||||
void bip_get_broadcast_address(BACNET_ADDRESS *dest); /* destination address */
|
||||
void bip_get_my_address(BACNET_ADDRESS *my_address);
|
||||
|
||||
/* function to send a packet out the BACnet/IP socket */
|
||||
/* returns zero on success, non-zero on failure */
|
||||
int bip_send_pdu(BACNET_ADDRESS * dest, /* destination address */
|
||||
/* function to send a packet out the BACnet/IP socket */
|
||||
/* returns zero on success, non-zero on failure */
|
||||
int bip_send_pdu(
|
||||
BACNET_ADDRESS *dest, /* destination address */
|
||||
|
||||
BACNET_NPDU_DATA * npdu_data, /* network information */
|
||||
BACNET_NPDU_DATA *npdu_data, /* network information */
|
||||
|
||||
uint8_t * pdu, /* any data to be sent - may be null */
|
||||
uint8_t *pdu, /* any data to be sent - may be null */
|
||||
|
||||
unsigned pdu_len); /* number of bytes of data */
|
||||
unsigned pdu_len); /* number of bytes of data */
|
||||
|
||||
/* receives a BACnet/IP packet */
|
||||
/* returns the number of octets in the PDU, or zero on failure */
|
||||
uint16_t bip_receive(BACNET_ADDRESS * src, /* source address */
|
||||
/* receives a BACnet/IP packet */
|
||||
/* returns the number of octets in the PDU, or zero on failure */
|
||||
uint16_t bip_receive(
|
||||
BACNET_ADDRESS *src, /* source address */
|
||||
|
||||
uint8_t * pdu, /* PDU data */
|
||||
uint8_t *pdu, /* PDU data */
|
||||
|
||||
uint16_t max_pdu, /* amount of space available in the PDU */
|
||||
uint16_t max_pdu, /* amount of space available in the PDU */
|
||||
|
||||
unsigned timeout); /* milliseconds to wait for a packet */
|
||||
unsigned timeout); /* milliseconds to wait for a packet */
|
||||
|
||||
/* use host byte order for setting */
|
||||
void bip_set_port(uint16_t port);
|
||||
/* returns host byte order */
|
||||
uint16_t bip_get_port(void);
|
||||
/* use host byte order for setting */
|
||||
void bip_set_port(uint16_t port);
|
||||
/* returns host byte order */
|
||||
uint16_t bip_get_port(void);
|
||||
|
||||
/* use network byte order for setting */
|
||||
void bip_set_addr(const uint8_t * net_address);
|
||||
/* returns network byte order */
|
||||
uint8_t *bip_get_addr(void);
|
||||
/* use network byte order for setting */
|
||||
void bip_set_addr(const uint8_t *net_address);
|
||||
/* returns network byte order */
|
||||
uint8_t *bip_get_addr(void);
|
||||
|
||||
/* use network byte order for setting */
|
||||
void bip_set_broadcast_addr(const uint8_t * net_address);
|
||||
/* returns network byte order */
|
||||
uint8_t *bip_get_broadcast_addr(void);
|
||||
/* use network byte order for setting */
|
||||
void bip_set_broadcast_addr(const uint8_t *net_address);
|
||||
/* returns network byte order */
|
||||
uint8_t *bip_get_broadcast_addr(void);
|
||||
|
||||
/* gets an IP address by name, where name can be a
|
||||
string that is an IP address in dotted form, or
|
||||
a name that is a domain name
|
||||
returns 0 if not found, or
|
||||
an IP address in network byte order */
|
||||
long bip_getaddrbyname(const char *host_name);
|
||||
/* gets an IP address by name, where name can be a
|
||||
string that is an IP address in dotted form, or
|
||||
a name that is a domain name
|
||||
returns 0 if not found, or
|
||||
an IP address in network byte order */
|
||||
long bip_getaddrbyname(const char *host_name);
|
||||
|
||||
void bip_debug_enable(void);
|
||||
void bip_debug_enable(void);
|
||||
|
||||
void bip_debug_disable(void);
|
||||
void bip_debug_disable(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -27,8 +27,9 @@ static BACNET_BINARY_PV Present_Value[MAX_BINARY_VALUES];
|
||||
/* we simply have 0-n object instances. */
|
||||
bool Binary_Value_Valid_Instance(uint32_t object_instance)
|
||||
{
|
||||
if (object_instance < MAX_BINARY_VALUES)
|
||||
if (object_instance < MAX_BINARY_VALUES) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -50,8 +51,9 @@ unsigned Binary_Value_Instance_To_Index(uint32_t object_instance)
|
||||
{
|
||||
unsigned index = MAX_BINARY_VALUES;
|
||||
|
||||
if (object_instance < MAX_BINARY_VALUES)
|
||||
if (object_instance < MAX_BINARY_VALUES) {
|
||||
index = object_instance;
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
@@ -81,7 +83,8 @@ char *Binary_Value_Name(uint32_t object_instance)
|
||||
}
|
||||
|
||||
/* return apdu len, or -1 on error */
|
||||
int Binary_Value_Encode_Property_APDU(uint8_t *apdu,
|
||||
int Binary_Value_Encode_Property_APDU(
|
||||
uint8_t *apdu,
|
||||
uint32_t object_instance,
|
||||
BACNET_PROPERTY_ID property,
|
||||
uint32_t array_index,
|
||||
@@ -153,7 +156,8 @@ int Binary_Value_Encode_Property_APDU(uint8_t *apdu,
|
||||
}
|
||||
|
||||
/* returns true if successful */
|
||||
bool Binary_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data,
|
||||
bool Binary_Value_Write_Property(
|
||||
BACNET_WRITE_PROPERTY_DATA *wp_data,
|
||||
BACNET_ERROR_CLASS *error_class,
|
||||
BACNET_ERROR_CODE *error_code)
|
||||
{
|
||||
|
||||
+24
-24
@@ -1,10 +1,10 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
*
|
||||
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
#ifndef BV_H
|
||||
#define BV_H
|
||||
|
||||
@@ -18,31 +18,31 @@
|
||||
#define MAX_BINARY_VALUES 10
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
void Binary_Value_Property_Lists(const int **pRequired,
|
||||
const int **pOptional,
|
||||
const int **pProprietary);
|
||||
bool Binary_Value_Valid_Instance(uint32_t object_instance);
|
||||
unsigned Binary_Value_Count(void);
|
||||
uint32_t Binary_Value_Index_To_Instance(unsigned index);
|
||||
char *Binary_Value_Name(uint32_t object_instance);
|
||||
void Binary_Value_Property_Lists(
|
||||
const int **pRequired, const int **pOptional, const int **pProprietary);
|
||||
bool Binary_Value_Valid_Instance(uint32_t object_instance);
|
||||
unsigned Binary_Value_Count(void);
|
||||
uint32_t Binary_Value_Index_To_Instance(unsigned index);
|
||||
char *Binary_Value_Name(uint32_t object_instance);
|
||||
|
||||
void Binary_Value_Init(void);
|
||||
void Binary_Value_Init(void);
|
||||
|
||||
int Binary_Value_Encode_Property_APDU(uint8_t * apdu,
|
||||
uint32_t object_instance,
|
||||
BACNET_PROPERTY_ID property,
|
||||
uint32_t array_index,
|
||||
BACNET_ERROR_CLASS * error_class,
|
||||
BACNET_ERROR_CODE * error_code);
|
||||
int Binary_Value_Encode_Property_APDU(
|
||||
uint8_t *apdu,
|
||||
uint32_t object_instance,
|
||||
BACNET_PROPERTY_ID property,
|
||||
uint32_t array_index,
|
||||
BACNET_ERROR_CLASS *error_class,
|
||||
BACNET_ERROR_CODE *error_code);
|
||||
|
||||
bool Binary_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
||||
BACNET_ERROR_CLASS * error_class,
|
||||
BACNET_ERROR_CODE * error_code);
|
||||
bool Binary_Value_Write_Property(
|
||||
BACNET_WRITE_PROPERTY_DATA *wp_data,
|
||||
BACNET_ERROR_CLASS *error_class,
|
||||
BACNET_ERROR_CODE *error_code);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -54,7 +54,8 @@ static int bvlc_encode_bvlc_result(uint8_t *pdu, BACNET_BVLC_RESULT result_code)
|
||||
* @return Upon successful completion, returns the number of bytes sent.
|
||||
* Otherwise, -1 shall be returned and errno set to indicate the error.
|
||||
*/
|
||||
static int bvlc_send_mpdu(const uint8_t *dest_addr, /* the destination address */
|
||||
static int bvlc_send_mpdu(
|
||||
const uint8_t *dest_addr, /* the destination address */
|
||||
const uint16_t *dest_port, /* the destination port */
|
||||
uint8_t *mtu, /* the data */
|
||||
uint16_t mtu_len)
|
||||
@@ -72,7 +73,8 @@ static int bvlc_send_mpdu(const uint8_t *dest_addr, /* the destination address *
|
||||
* @param dest_addr - destination address
|
||||
* @param dest_port - destination port
|
||||
*/
|
||||
static void bvlc_send_result(const uint8_t *dest_addr,
|
||||
static void bvlc_send_result(
|
||||
const uint8_t *dest_addr,
|
||||
const uint16_t *dest_port, /* the destination address */
|
||||
BACNET_BVLC_RESULT result_code)
|
||||
{
|
||||
|
||||
@@ -16,10 +16,8 @@
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
uint16_t bvlc_for_non_bbmd(uint8_t * addr,
|
||||
uint16_t * port,
|
||||
uint8_t * npdu,
|
||||
uint16_t received_bytes);
|
||||
uint16_t bvlc_for_non_bbmd(
|
||||
uint8_t *addr, uint16_t *port, uint8_t *npdu, uint16_t received_bytes);
|
||||
|
||||
BACNET_BVLC_FUNCTION bvlc_get_function_code(void);
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2012 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
*
|
||||
* Copyright (C) 2012 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
#ifndef DATALINK_H
|
||||
#define DATALINK_H
|
||||
|
||||
@@ -46,17 +46,17 @@
|
||||
#include "bvlc-arduino.h"
|
||||
|
||||
#define datalink_init bip_init
|
||||
//#if defined(BBMD_ENABLED) && BBMD_ENABLED
|
||||
//#define datalink_send_pdu bvlc_send_pdu
|
||||
//#define datalink_receive bvlc_receive
|
||||
//#else
|
||||
// #if defined(BBMD_ENABLED) && BBMD_ENABLED
|
||||
// #define datalink_send_pdu bvlc_send_pdu
|
||||
// #define datalink_receive bvlc_receive
|
||||
// #else
|
||||
#define datalink_send_pdu bip_send_pdu
|
||||
#define datalink_receive bip_receive
|
||||
//#endif
|
||||
// #endif
|
||||
#define datalink_cleanup bip_cleanup
|
||||
#define datalink_get_broadcast_address bip_get_broadcast_address
|
||||
#ifdef BAC_ROUTING
|
||||
extern void routed_get_my_address(BACNET_ADDRESS * my_address);
|
||||
extern void routed_get_my_address(BACNET_ADDRESS *my_address);
|
||||
#define datalink_get_my_address routed_get_my_address
|
||||
#else
|
||||
#define datalink_get_my_address bip_get_my_address
|
||||
@@ -66,25 +66,24 @@ extern void routed_get_my_address(BACNET_ADDRESS * my_address);
|
||||
#include "bacnet/npdu.h"
|
||||
|
||||
#define MAX_HEADER (8)
|
||||
#define MAX_MPDU (MAX_HEADER+MAX_PDU)
|
||||
#define MAX_MPDU (MAX_HEADER + MAX_PDU)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
int datalink_send_pdu(BACNET_ADDRESS * dest,
|
||||
BACNET_NPDU_DATA * npdu_data,
|
||||
uint8_t * pdu,
|
||||
unsigned pdu_len);
|
||||
extern uint16_t datalink_receive(BACNET_ADDRESS * src,
|
||||
uint8_t * pdu,
|
||||
uint16_t max_pdu,
|
||||
unsigned timeout);
|
||||
extern void datalink_cleanup(void);
|
||||
extern void datalink_get_broadcast_address(BACNET_ADDRESS * dest);
|
||||
extern void datalink_get_my_address(BACNET_ADDRESS * my_address);
|
||||
extern void datalink_set_interface(char *ifname);
|
||||
extern void datalink_set(char *datalink_string);
|
||||
int datalink_send_pdu(
|
||||
BACNET_ADDRESS *dest,
|
||||
BACNET_NPDU_DATA *npdu_data,
|
||||
uint8_t *pdu,
|
||||
unsigned pdu_len);
|
||||
extern uint16_t datalink_receive(
|
||||
BACNET_ADDRESS *src, uint8_t *pdu, uint16_t max_pdu, unsigned timeout);
|
||||
extern void datalink_cleanup(void);
|
||||
extern void datalink_get_broadcast_address(BACNET_ADDRESS *dest);
|
||||
extern void datalink_get_my_address(BACNET_ADDRESS *my_address);
|
||||
extern void datalink_set_interface(char *ifname);
|
||||
extern void datalink_set(char *datalink_string);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
@@ -111,7 +110,8 @@ extern "C" {
|
||||
* chosen at runtime from among these choices.
|
||||
* - Clause 10 POINT-TO-POINT (PTP) and Clause 11 EIA/CEA-709.1 ("LonTalk") LAN
|
||||
* are not currently supported by this project.
|
||||
*//** @defgroup DLTemplates DataLink Template Functions
|
||||
*/
|
||||
/** @defgroup DLTemplates DataLink Template Functions
|
||||
* @ingroup DataLink
|
||||
* Most of the functions in this group are function templates which are assigned
|
||||
* to a specific DataLink network layer implementation either at compile time or
|
||||
|
||||
+16
-10
@@ -60,8 +60,9 @@ bool Device_Set_Object_Instance_Number(uint32_t object_id)
|
||||
(char *)&Object_Instance_Number,
|
||||
sizeof(Object_Instance_Number),
|
||||
EEPROM_BACNET_ID_ADDR); */
|
||||
} else
|
||||
} else {
|
||||
status = false;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -69,7 +70,8 @@ bool Device_Set_Object_Instance_Number(uint32_t object_id)
|
||||
bool Device_Valid_Object_Instance_Number(uint32_t object_id)
|
||||
{
|
||||
/* BACnet allows for a wildcard instance number */
|
||||
return ((Object_Instance_Number == object_id) ||
|
||||
return (
|
||||
(Object_Instance_Number == object_id) ||
|
||||
(object_id == BACNET_MAX_INSTANCE));
|
||||
}
|
||||
|
||||
@@ -136,7 +138,8 @@ bool Device_Object_List_Identifier(
|
||||
}
|
||||
|
||||
/* return the length of the apdu encoded or -1 for error */
|
||||
int Device_Encode_Property_APDU(uint8_t *apdu,
|
||||
int Device_Encode_Property_APDU(
|
||||
uint8_t *apdu,
|
||||
uint32_t object_instance,
|
||||
BACNET_PROPERTY_ID property,
|
||||
uint32_t array_index,
|
||||
@@ -207,7 +210,8 @@ int Device_Encode_Property_APDU(uint8_t *apdu,
|
||||
bitstring_init(&bit_string);
|
||||
for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++) {
|
||||
/* automatic lookup based on handlers set */
|
||||
bitstring_set_bit(&bit_string, (uint8_t)i,
|
||||
bitstring_set_bit(
|
||||
&bit_string, (uint8_t)i,
|
||||
apdu_service_supported((BACNET_SERVICES_SUPPORTED)i));
|
||||
}
|
||||
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
|
||||
@@ -230,8 +234,9 @@ int Device_Encode_Property_APDU(uint8_t *apdu,
|
||||
case PROP_OBJECT_LIST:
|
||||
count = Device_Object_List_Count();
|
||||
/* Array element zero is the number of objects in the list */
|
||||
if (array_index == 0)
|
||||
if (array_index == 0) {
|
||||
apdu_len = encode_application_unsigned(&apdu[0], count);
|
||||
}
|
||||
/* if no index was specified, then try to encode the entire list */
|
||||
/* into one packet. Note that more than likely you will have */
|
||||
/* to return an error if the number of encoded objects exceeds */
|
||||
@@ -254,10 +259,10 @@ int Device_Encode_Property_APDU(uint8_t *apdu,
|
||||
}
|
||||
} else {
|
||||
if (Device_Object_List_Identifier(
|
||||
array_index, &object_type, &instance))
|
||||
array_index, &object_type, &instance)) {
|
||||
apdu_len = encode_application_object_id(
|
||||
&apdu[0], object_type, instance);
|
||||
else {
|
||||
} else {
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
|
||||
apdu_len = BACNET_STATUS_ERROR;
|
||||
@@ -321,7 +326,8 @@ int Device_Encode_Property_APDU(uint8_t *apdu,
|
||||
return apdu_len;
|
||||
}
|
||||
|
||||
bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data,
|
||||
bool Device_Write_Property(
|
||||
BACNET_WRITE_PROPERTY_DATA *wp_data,
|
||||
BACNET_ERROR_CLASS *error_class,
|
||||
BACNET_ERROR_CODE *error_code)
|
||||
{
|
||||
@@ -399,8 +405,8 @@ bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data,
|
||||
encoding =
|
||||
characterstring_encoding(&value.type.Character_String);
|
||||
if (encoding == CHARACTER_ANSI_X34) {
|
||||
if (characterstring_ansi_copy(&Object_Name[0],
|
||||
sizeof(Object_Name),
|
||||
if (characterstring_ansi_copy(
|
||||
&Object_Name[0], sizeof(Object_Name),
|
||||
&value.type.Character_String)) {
|
||||
status = true;
|
||||
} else {
|
||||
|
||||
+62
-66
@@ -15,98 +15,94 @@
|
||||
#include "bacnet/wp.h"
|
||||
#include "bacnet/readrange.h"
|
||||
|
||||
typedef unsigned (*object_count_function) (void);
|
||||
typedef uint32_t(*object_index_to_instance_function)
|
||||
(unsigned index);
|
||||
typedef char *(*object_name_function)
|
||||
(uint32_t object_instance);
|
||||
typedef unsigned (*object_count_function)(void);
|
||||
typedef uint32_t (*object_index_to_instance_function)(unsigned index);
|
||||
typedef char *(*object_name_function)(uint32_t object_instance);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
void Device_Object_Function_Set(BACNET_OBJECT_TYPE object_type,
|
||||
object_count_function count_function,
|
||||
object_index_to_instance_function index_function,
|
||||
object_name_function name_function);
|
||||
void Device_Object_Function_Set(
|
||||
BACNET_OBJECT_TYPE object_type,
|
||||
object_count_function count_function,
|
||||
object_index_to_instance_function index_function,
|
||||
object_name_function name_function);
|
||||
|
||||
void Device_Init(void);
|
||||
void Device_Init(void);
|
||||
|
||||
void Device_Property_Lists(const int **pRequired,
|
||||
const int **pOptional,
|
||||
const int **pProprietary);
|
||||
void Device_Property_Lists(
|
||||
const int **pRequired, const int **pOptional, const int **pProprietary);
|
||||
|
||||
uint32_t Device_Object_Instance_Number(void);
|
||||
bool Device_Set_Object_Instance_Number(uint32_t object_id);
|
||||
bool Device_Valid_Object_Instance_Number(uint32_t object_id);
|
||||
unsigned Device_Object_List_Count(void);
|
||||
bool Device_Object_List_Identifier(uint32_t array_index,
|
||||
BACNET_OBJECT_TYPE *object_type,
|
||||
uint32_t * instance);
|
||||
uint32_t Device_Object_Instance_Number(void);
|
||||
bool Device_Set_Object_Instance_Number(uint32_t object_id);
|
||||
bool Device_Valid_Object_Instance_Number(uint32_t object_id);
|
||||
unsigned Device_Object_List_Count(void);
|
||||
bool Device_Object_List_Identifier(
|
||||
uint32_t array_index, BACNET_OBJECT_TYPE *object_type, uint32_t *instance);
|
||||
|
||||
BACNET_DEVICE_STATUS Device_System_Status(void);
|
||||
void Device_Set_System_Status(BACNET_DEVICE_STATUS status);
|
||||
BACNET_DEVICE_STATUS Device_System_Status(void);
|
||||
void Device_Set_System_Status(BACNET_DEVICE_STATUS status);
|
||||
|
||||
const char *Device_Vendor_Name(void);
|
||||
const char *Device_Vendor_Name(void);
|
||||
|
||||
uint16_t Device_Vendor_Identifier(void);
|
||||
uint16_t Device_Vendor_Identifier(void);
|
||||
|
||||
const char *Device_Model_Name(void);
|
||||
bool Device_Set_Model_Name(const char *name,
|
||||
size_t length);
|
||||
const char *Device_Model_Name(void);
|
||||
bool Device_Set_Model_Name(const char *name, size_t length);
|
||||
|
||||
const char *Device_Firmware_Revision(void);
|
||||
const char *Device_Firmware_Revision(void);
|
||||
|
||||
const char *Device_Application_Software_Version(void);
|
||||
bool Device_Set_Application_Software_Version(const char *name,
|
||||
size_t length);
|
||||
const char *Device_Application_Software_Version(void);
|
||||
bool Device_Set_Application_Software_Version(const char *name, size_t length);
|
||||
|
||||
bool Device_Set_Object_Name(const char *name,
|
||||
size_t length);
|
||||
const char *Device_Object_Name(void);
|
||||
bool Device_Set_Object_Name(const char *name, size_t length);
|
||||
const char *Device_Object_Name(void);
|
||||
|
||||
const char *Device_Description(void);
|
||||
bool Device_Set_Description(const char *name,
|
||||
size_t length);
|
||||
const char *Device_Description(void);
|
||||
bool Device_Set_Description(const char *name, size_t length);
|
||||
|
||||
const char *Device_Location(void);
|
||||
bool Device_Set_Location(const char *name,
|
||||
size_t length);
|
||||
const char *Device_Location(void);
|
||||
bool Device_Set_Location(const char *name, size_t length);
|
||||
|
||||
/* some stack-centric constant values - no set methods */
|
||||
uint8_t Device_Protocol_Version(void);
|
||||
uint8_t Device_Protocol_Revision(void);
|
||||
BACNET_SEGMENTATION Device_Segmentation_Supported(void);
|
||||
/* some stack-centric constant values - no set methods */
|
||||
uint8_t Device_Protocol_Version(void);
|
||||
uint8_t Device_Protocol_Revision(void);
|
||||
BACNET_SEGMENTATION Device_Segmentation_Supported(void);
|
||||
|
||||
uint8_t Device_Database_Revision(void);
|
||||
void Device_Set_Database_Revision(uint8_t revision);
|
||||
uint8_t Device_Database_Revision(void);
|
||||
void Device_Set_Database_Revision(uint8_t revision);
|
||||
|
||||
bool Device_Valid_Object_Name(const char *object_name,
|
||||
BACNET_OBJECT_TYPE *object_type,
|
||||
uint32_t * object_instance);
|
||||
char *Device_Valid_Object_Id(BACNET_OBJECT_TYPE object_type,
|
||||
uint32_t object_instance);
|
||||
bool Device_Valid_Object_Name(
|
||||
const char *object_name,
|
||||
BACNET_OBJECT_TYPE *object_type,
|
||||
uint32_t *object_instance);
|
||||
char *Device_Valid_Object_Id(
|
||||
BACNET_OBJECT_TYPE object_type, uint32_t object_instance);
|
||||
|
||||
int Device_Encode_Property_APDU(uint8_t * apdu,
|
||||
uint32_t object_instance,
|
||||
BACNET_PROPERTY_ID property,
|
||||
uint32_t array_index,
|
||||
BACNET_ERROR_CLASS * error_class,
|
||||
BACNET_ERROR_CODE * error_code);
|
||||
int Device_Encode_Property_APDU(
|
||||
uint8_t *apdu,
|
||||
uint32_t object_instance,
|
||||
BACNET_PROPERTY_ID property,
|
||||
uint32_t array_index,
|
||||
BACNET_ERROR_CLASS *error_class,
|
||||
BACNET_ERROR_CODE *error_code);
|
||||
|
||||
bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
||||
BACNET_ERROR_CLASS * error_class,
|
||||
BACNET_ERROR_CODE * error_code);
|
||||
bool Device_Write_Property(
|
||||
BACNET_WRITE_PROPERTY_DATA *wp_data,
|
||||
BACNET_ERROR_CLASS *error_class,
|
||||
BACNET_ERROR_CODE *error_code);
|
||||
|
||||
bool DeviceGetRRInfo(uint32_t Object, /* Which particular object - obviously not important for device object */
|
||||
bool DeviceGetRRInfo(
|
||||
uint32_t Object, /* Which particular object - obviously not important for
|
||||
device object */
|
||||
|
||||
BACNET_PROPERTY_ID Property, /* Which property */
|
||||
BACNET_PROPERTY_ID Property, /* Which property */
|
||||
|
||||
RR_PROP_INFO * pInfo, /* Where to put the information */
|
||||
|
||||
BACNET_ERROR_CLASS * error_class,
|
||||
BACNET_ERROR_CODE * error_code);
|
||||
RR_PROP_INFO *pInfo, /* Where to put the information */
|
||||
|
||||
BACNET_ERROR_CLASS *error_class,
|
||||
BACNET_ERROR_CODE *error_code);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
+30
-24
@@ -26,7 +26,8 @@
|
||||
|
||||
/* Encodes the property APDU and returns the length,
|
||||
or sets the error, and returns -1 */
|
||||
int Encode_Property_APDU(uint8_t *apdu,
|
||||
int Encode_Property_APDU(
|
||||
uint8_t *apdu,
|
||||
BACNET_READ_PROPERTY_DATA *rp_data,
|
||||
BACNET_ERROR_CLASS *error_class,
|
||||
BACNET_ERROR_CODE *error_code)
|
||||
@@ -37,23 +38,26 @@ int Encode_Property_APDU(uint8_t *apdu,
|
||||
switch (rp_data->object_type) {
|
||||
case OBJECT_DEVICE:
|
||||
if (Device_Valid_Object_Instance_Number(rp_data->object_instance)) {
|
||||
apdu_len = Device_Encode_Property_APDU(&apdu[0],
|
||||
rp_data->object_instance, rp_data->object_property,
|
||||
rp_data->array_index, error_class, error_code);
|
||||
apdu_len = Device_Encode_Property_APDU(
|
||||
&apdu[0], rp_data->object_instance,
|
||||
rp_data->object_property, rp_data->array_index, error_class,
|
||||
error_code);
|
||||
}
|
||||
break;
|
||||
case OBJECT_ANALOG_VALUE:
|
||||
if (Analog_Value_Valid_Instance(rp_data->object_instance)) {
|
||||
apdu_len = Analog_Value_Encode_Property_APDU(&apdu[0],
|
||||
rp_data->object_instance, rp_data->object_property,
|
||||
rp_data->array_index, error_class, error_code);
|
||||
apdu_len = Analog_Value_Encode_Property_APDU(
|
||||
&apdu[0], rp_data->object_instance,
|
||||
rp_data->object_property, rp_data->array_index, error_class,
|
||||
error_code);
|
||||
}
|
||||
break;
|
||||
case OBJECT_BINARY_VALUE:
|
||||
if (Binary_Value_Valid_Instance(rp_data->object_instance)) {
|
||||
apdu_len = Binary_Value_Encode_Property_APDU(&apdu[0],
|
||||
rp_data->object_instance, rp_data->object_property,
|
||||
rp_data->array_index, error_class, error_code);
|
||||
apdu_len = Binary_Value_Encode_Property_APDU(
|
||||
&apdu[0], rp_data->object_instance,
|
||||
rp_data->object_property, rp_data->array_index, error_class,
|
||||
error_code);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -65,7 +69,8 @@ int Encode_Property_APDU(uint8_t *apdu,
|
||||
return apdu_len;
|
||||
}
|
||||
|
||||
void handler_read_property(uint8_t *service_request,
|
||||
void handler_read_property(
|
||||
uint8_t *service_request,
|
||||
uint16_t service_len,
|
||||
BACNET_ADDRESS *src,
|
||||
BACNET_CONFIRMED_SERVICE_DATA *service_data)
|
||||
@@ -87,25 +92,26 @@ void handler_read_property(uint8_t *service_request,
|
||||
&Handler_Transmit_Buffer[0], src, &my_address, &npdu_data);
|
||||
if (service_data->segmented_message) {
|
||||
/* we don't support segmentation - send an abort */
|
||||
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
|
||||
true);
|
||||
len = abort_encode_apdu(
|
||||
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
|
||||
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
|
||||
goto RP_ABORT;
|
||||
}
|
||||
len = rp_decode_service_request(service_request, service_len, &data);
|
||||
if (len < 0) {
|
||||
/* bad decoding - send an abort */
|
||||
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id, ABORT_REASON_OTHER, true);
|
||||
len = abort_encode_apdu(
|
||||
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
|
||||
ABORT_REASON_OTHER, true);
|
||||
goto RP_ABORT;
|
||||
}
|
||||
/* most cases will be error */
|
||||
ack_len = rp_ack_encode_apdu_init(
|
||||
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, &data);
|
||||
/* FIXME: add buffer len as passed into function or use smart buffer */
|
||||
property_len =
|
||||
Encode_Property_APDU(&Handler_Transmit_Buffer[pdu_len + ack_len], &data,
|
||||
&error_class, &error_code);
|
||||
property_len = Encode_Property_APDU(
|
||||
&Handler_Transmit_Buffer[pdu_len + ack_len], &data, &error_class,
|
||||
&error_code);
|
||||
if (property_len >= 0) {
|
||||
len = rp_ack_encode_apdu_object_property_end(
|
||||
&Handler_Transmit_Buffer[pdu_len + property_len + ack_len]);
|
||||
@@ -115,14 +121,14 @@ void handler_read_property(uint8_t *service_request,
|
||||
/* BACnet APDU too small to fit data, so proper response is
|
||||
* Abort */
|
||||
case BACNET_STATUS_ABORT:
|
||||
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id,
|
||||
len = abort_encode_apdu(
|
||||
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
|
||||
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
|
||||
break;
|
||||
default:
|
||||
len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id, SERVICE_CONFIRMED_READ_PROPERTY,
|
||||
error_class, error_code);
|
||||
len = bacerror_encode_apdu(
|
||||
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
|
||||
SERVICE_CONFIRMED_READ_PROPERTY, error_class, error_code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,9 +41,9 @@ void sendIamUnicast(uint8_t *buffer, BACNET_ADDRESS *src)
|
||||
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
|
||||
npdu_len = npdu_encode_pdu(&buffer[0], &dest, &my_address, &npdu_data);
|
||||
/* encode the APDU portion of the packet */
|
||||
apdu_len =
|
||||
iam_encode_apdu(&buffer[npdu_len], Device_Object_Instance_Number(),
|
||||
MAX_APDU, SEGMENTATION_NONE, Device_Vendor_Identifier());
|
||||
apdu_len = iam_encode_apdu(
|
||||
&buffer[npdu_len], Device_Object_Instance_Number(), MAX_APDU,
|
||||
SEGMENTATION_NONE, Device_Vendor_Identifier());
|
||||
/* send data */
|
||||
pdu_len = npdu_len + apdu_len;
|
||||
int bytes = datalink_send_pdu(&dest, &npdu_data, &buffer[0], pdu_len);
|
||||
|
||||
+32
-27
@@ -27,7 +27,8 @@
|
||||
/* too big to reside on stack frame for PIC */
|
||||
static BACNET_WRITE_PROPERTY_DATA wp_data;
|
||||
|
||||
void handler_write_property(uint8_t *service_request,
|
||||
void handler_write_property(
|
||||
uint8_t *service_request,
|
||||
uint16_t service_len,
|
||||
BACNET_ADDRESS *src,
|
||||
BACNET_CONFIRMED_SERVICE_DATA *service_data)
|
||||
@@ -48,60 +49,64 @@ void handler_write_property(uint8_t *service_request,
|
||||
&Handler_Transmit_Buffer[0], src, &my_address, &npdu_data);
|
||||
/* bad decoding or something we didn't understand - send an abort */
|
||||
if (len <= 0) {
|
||||
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id, ABORT_REASON_OTHER, true);
|
||||
len = abort_encode_apdu(
|
||||
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
|
||||
ABORT_REASON_OTHER, true);
|
||||
} else if (service_data->segmented_message) {
|
||||
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
|
||||
true);
|
||||
len = abort_encode_apdu(
|
||||
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
|
||||
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
|
||||
} else {
|
||||
switch (wp_data.object_type) {
|
||||
case OBJECT_DEVICE:
|
||||
if (Device_Write_Property(
|
||||
&wp_data, &error_class, &error_code)) {
|
||||
len = encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
|
||||
len = encode_simple_ack(
|
||||
&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id,
|
||||
SERVICE_CONFIRMED_WRITE_PROPERTY);
|
||||
} else {
|
||||
len =
|
||||
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id,
|
||||
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
|
||||
error_code);
|
||||
len = bacerror_encode_apdu(
|
||||
&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id,
|
||||
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
|
||||
error_code);
|
||||
}
|
||||
break;
|
||||
case OBJECT_ANALOG_VALUE:
|
||||
if (Analog_Value_Write_Property(
|
||||
&wp_data, &error_class, &error_code)) {
|
||||
len = encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
|
||||
len = encode_simple_ack(
|
||||
&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id,
|
||||
SERVICE_CONFIRMED_WRITE_PROPERTY);
|
||||
} else {
|
||||
len =
|
||||
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id,
|
||||
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
|
||||
error_code);
|
||||
len = bacerror_encode_apdu(
|
||||
&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id,
|
||||
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
|
||||
error_code);
|
||||
}
|
||||
break;
|
||||
case OBJECT_BINARY_VALUE:
|
||||
if (Binary_Value_Write_Property(
|
||||
&wp_data, &error_class, &error_code)) {
|
||||
len = encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
|
||||
len = encode_simple_ack(
|
||||
&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id,
|
||||
SERVICE_CONFIRMED_WRITE_PROPERTY);
|
||||
} else {
|
||||
len =
|
||||
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id,
|
||||
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
|
||||
error_code);
|
||||
len = bacerror_encode_apdu(
|
||||
&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id,
|
||||
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
|
||||
error_code);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY,
|
||||
error_class, error_code);
|
||||
len = bacerror_encode_apdu(
|
||||
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
|
||||
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, error_code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,8 +32,8 @@
|
||||
extern bool Send_I_Am_Flag;
|
||||
/* local version override */
|
||||
const char *BACnet_Version = "1.0";
|
||||
static uint8_t Ethernet_MAC_Address[MAX_MAC_LEN] = { 0xDE, 0xAD, 0xBE, 0xEF,
|
||||
0xFE, 0xED };
|
||||
static uint8_t Ethernet_MAC_Address[MAX_MAC_LEN] = { 0xDE, 0xAD, 0xBE,
|
||||
0xEF, 0xFE, 0xED };
|
||||
uint8_t ipAddress[] = { 192, 168, 0, 185 };
|
||||
uint8_t gateway[] = { 192, 168, 0, 1 };
|
||||
uint8_t netmask[] = { 255, 255, 255, 0 };
|
||||
@@ -70,14 +70,17 @@ void setup()
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Static receive buffer, initialized with zeros by the C Library Startup Code. */
|
||||
/** Static receive buffer, initialized with zeros by the C Library Startup Code.
|
||||
*/
|
||||
|
||||
static uint8_t PDUBuffer[MAX_MPDU + 16 /* Add a little safety margin to the buffer,
|
||||
* so that in the rare case, the message
|
||||
* would be filled up to MAX_MPDU and some
|
||||
* decoding functions would overrun, these
|
||||
* decoding functions will just end up in
|
||||
* a safe field of static zeros. */];
|
||||
static uint8_t PDUBuffer
|
||||
[MAX_MPDU + 16 /* Add a little safety margin to the buffer,
|
||||
* so that in the rare case, the message
|
||||
* would be filled up to MAX_MPDU and some
|
||||
* decoding functions would overrun, these
|
||||
* decoding functions will just end up in
|
||||
* a safe field of static zeros. */
|
||||
];
|
||||
|
||||
/** Main */
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
typedef unsigned char uint8_t; /* 1 byte 0 to 255 */
|
||||
typedef signed char int8_t; /* 1 byte -127 to 127 */
|
||||
typedef unsigned short uint16_t; /* 2 bytes 0 to 65535 */
|
||||
typedef signed short int16_t; /* 2 bytes -32767 to 32767 */
|
||||
typedef unsigned char uint8_t; /* 1 byte 0 to 255 */
|
||||
typedef signed char int8_t; /* 1 byte -127 to 127 */
|
||||
typedef unsigned short uint16_t; /* 2 bytes 0 to 65535 */
|
||||
typedef signed short int16_t; /* 2 bytes -32767 to 32767 */
|
||||
typedef unsigned long uint32_t; /* 4 bytes 0 to 4294967295 */
|
||||
typedef signed long int32_t; /* 4 bytes -2147483647 to 2147483647 */
|
||||
typedef signed long int32_t; /* 4 bytes -2147483647 to 2147483647 */
|
||||
|
||||
#define INT8_MIN (-128)
|
||||
#define INT16_MIN (-32768)
|
||||
@@ -20,8 +20,8 @@ typedef signed long int32_t; /* 4 bytes -2147483647 to 2147483647 */
|
||||
#define INT16_MAX 32767
|
||||
#define INT32_MAX 2147483647
|
||||
|
||||
#define UINT8_MAX 0xff /* 255U */
|
||||
#define UINT16_MAX 0xffff /* 65535U */
|
||||
#define UINT32_MAX 0xffffffff /* 4294967295U */
|
||||
#define UINT8_MAX 0xff /* 255U */
|
||||
#define UINT16_MAX 0xffff /* 65535U */
|
||||
#define UINT32_MAX 0xffffffff /* 4294967295U */
|
||||
|
||||
#endif /* STDINT_H */
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
*
|
||||
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
#ifndef TXBUF_H
|
||||
#define TXBUF_H
|
||||
|
||||
|
||||
@@ -17,9 +17,8 @@ extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
void uart_init(void);
|
||||
void uart_putchar(char c,
|
||||
FILE * stream);
|
||||
char uart_getchar(FILE * stream);
|
||||
void uart_putchar(char c, FILE *stream);
|
||||
char uart_getchar(FILE *stream);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -437,11 +437,13 @@ extern "C" {
|
||||
* - The interface between the implemented Objects and the BAC-stack services,
|
||||
* specifically the handlers, which are mediated through function calls to
|
||||
* the Device object.
|
||||
*//** @defgroup ObjHelpers Object Helper Functions
|
||||
*/
|
||||
/** @defgroup ObjHelpers Object Helper Functions
|
||||
* @ingroup ObjFrmwk
|
||||
* This section describes the function templates for the helper functions that
|
||||
* provide common object support.
|
||||
*//** @defgroup ObjIntf Handler-to-Object Interface Functions
|
||||
*/
|
||||
/** @defgroup ObjIntf Handler-to-Object Interface Functions
|
||||
* @ingroup ObjFrmwk
|
||||
* This section describes the fairly limited set of functions that link the
|
||||
* BAC-stack handlers to the BACnet Object instances. All of these calls are
|
||||
|
||||
+54
-30
@@ -62,8 +62,9 @@ bool arcnet_valid(void)
|
||||
|
||||
void arcnet_cleanup(void)
|
||||
{
|
||||
if (arcnet_valid())
|
||||
if (arcnet_valid()) {
|
||||
close(ARCNET_Sock_FD);
|
||||
}
|
||||
ARCNET_Sock_FD = -1;
|
||||
|
||||
return;
|
||||
@@ -79,7 +80,8 @@ static int arcnet_bind(const char *interface_name)
|
||||
/* check to see if we are being run as root */
|
||||
uid = getuid();
|
||||
if (uid != 0) {
|
||||
fprintf(stderr,
|
||||
fprintf(
|
||||
stderr,
|
||||
"arcnet: Unable to open an af_packet socket. "
|
||||
"Try running with root priveleges.\n");
|
||||
return sock_fd;
|
||||
@@ -92,7 +94,8 @@ static int arcnet_bind(const char *interface_name)
|
||||
if ((sock_fd = socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ALL))) < 0) {
|
||||
/* Error occured */
|
||||
fprintf(stderr, "arcnet: Error opening socket: %s\n", strerror(errno));
|
||||
fprintf(stderr,
|
||||
fprintf(
|
||||
stderr,
|
||||
"You might need to add the following to modules.conf\n"
|
||||
"(or in /etc/modutils/alias on Debian with update-modules):\n"
|
||||
"alias net-pf-17 af_packet\n"
|
||||
@@ -108,19 +111,24 @@ static int arcnet_bind(const char *interface_name)
|
||||
ARCNET_Socket_Address.sa_family = ARPHRD_ARCNET;
|
||||
/*ARCNET_Socket_Address.sa_family = PF_INET; */
|
||||
/* Clear the memory before copying */
|
||||
memset(ARCNET_Socket_Address.sa_data, '\0',
|
||||
memset(
|
||||
ARCNET_Socket_Address.sa_data, '\0',
|
||||
sizeof(ARCNET_Socket_Address.sa_data));
|
||||
/* Strcpy the interface name into the address */
|
||||
strncpy(ARCNET_Socket_Address.sa_data, interface_name,
|
||||
strncpy(
|
||||
ARCNET_Socket_Address.sa_data, interface_name,
|
||||
sizeof(ARCNET_Socket_Address.sa_data) - 1);
|
||||
fprintf(
|
||||
stderr, "arcnet: binding \"%s\"\n", ARCNET_Socket_Address.sa_data);
|
||||
if (bind(sock_fd, &ARCNET_Socket_Address,
|
||||
if (bind(
|
||||
sock_fd, &ARCNET_Socket_Address,
|
||||
sizeof(ARCNET_Socket_Address)) != 0) {
|
||||
/* Bind problem, close socket and return */
|
||||
fprintf(stderr, "arcnet: Unable to bind socket : %s\n",
|
||||
fprintf(
|
||||
stderr, "arcnet: Unable to bind socket : %s\n",
|
||||
strerror(errno));
|
||||
fprintf(stderr,
|
||||
fprintf(
|
||||
stderr,
|
||||
"You might need to add the following to modules.conf\n"
|
||||
"(or in /etc/modutils/alias on Debian with update-modules):\n"
|
||||
"alias net-pf-17 af_packet\n"
|
||||
@@ -134,18 +142,22 @@ static int arcnet_bind(const char *interface_name)
|
||||
}
|
||||
strncpy(ifr.ifr_name, interface_name, sizeof(ifr.ifr_name));
|
||||
rv = ioctl(sock_fd, SIOCGIFHWADDR, &ifr);
|
||||
if (rv != -1) /* worked okay */
|
||||
if (rv != -1) { /* worked okay */
|
||||
ARCNET_MAC_Address = ifr.ifr_hwaddr.sa_data[0];
|
||||
}
|
||||
/* copy this info into the local copy since bind wiped it out */
|
||||
ARCNET_Socket_Address.sa_family = ARPHRD_ARCNET;
|
||||
/*ARCNET_Socket_Address.sa_family = PF_INET; */
|
||||
/* Clear the memory before copying */
|
||||
memset(ARCNET_Socket_Address.sa_data, '\0',
|
||||
memset(
|
||||
ARCNET_Socket_Address.sa_data, '\0',
|
||||
sizeof(ARCNET_Socket_Address.sa_data));
|
||||
/* Strcpy the interface name into the address */
|
||||
strncpy(ARCNET_Socket_Address.sa_data, interface_name,
|
||||
strncpy(
|
||||
ARCNET_Socket_Address.sa_data, interface_name,
|
||||
sizeof(ARCNET_Socket_Address.sa_data) - 1);
|
||||
fprintf(stderr, "arcnet: MAC=%02Xh iface=\"%s\"\n", ARCNET_MAC_Address,
|
||||
fprintf(
|
||||
stderr, "arcnet: MAC=%02Xh iface=\"%s\"\n", ARCNET_MAC_Address,
|
||||
ARCNET_Socket_Address.sa_data);
|
||||
|
||||
atexit(arcnet_cleanup);
|
||||
@@ -155,17 +167,19 @@ static int arcnet_bind(const char *interface_name)
|
||||
|
||||
bool arcnet_init(char *interface_name)
|
||||
{
|
||||
if (interface_name)
|
||||
if (interface_name) {
|
||||
ARCNET_Sock_FD = arcnet_bind(interface_name);
|
||||
else
|
||||
} else {
|
||||
ARCNET_Sock_FD = arcnet_bind("arc0");
|
||||
}
|
||||
|
||||
return arcnet_valid();
|
||||
}
|
||||
|
||||
/* function to send a PDU out the socket */
|
||||
/* returns number of bytes sent on success, negative on failure */
|
||||
int arcnet_send_pdu(BACNET_ADDRESS *dest, /* destination address */
|
||||
int arcnet_send_pdu(
|
||||
BACNET_ADDRESS *dest, /* destination address */
|
||||
BACNET_NPDU_DATA *npdu_data, /* network information */
|
||||
uint8_t *pdu, /* any data to be sent - may be null */
|
||||
unsigned pdu_len)
|
||||
@@ -186,15 +200,15 @@ int arcnet_send_pdu(BACNET_ADDRESS *dest, /* destination address */
|
||||
return -1;
|
||||
}
|
||||
/* load destination MAC address */
|
||||
if (dest->mac_len == 1)
|
||||
if (dest->mac_len == 1) {
|
||||
pkt->hard.dest = dest->mac[0];
|
||||
else {
|
||||
} else {
|
||||
fprintf(stderr, "arcnet: invalid destination MAC address!\n");
|
||||
return -2;
|
||||
}
|
||||
if (src.mac_len == 1)
|
||||
if (src.mac_len == 1) {
|
||||
pkt->hard.source = src.mac[0];
|
||||
else {
|
||||
} else {
|
||||
fprintf(stderr, "arcnet: invalid source MAC address!\n");
|
||||
return -3;
|
||||
}
|
||||
@@ -211,19 +225,22 @@ int arcnet_send_pdu(BACNET_ADDRESS *dest, /* destination address */
|
||||
}
|
||||
memcpy(&pkt->soft.raw[4], pdu, pdu_len);
|
||||
/* Send the packet */
|
||||
bytes = sendto(ARCNET_Sock_FD, &mtu, mtu_len, 0,
|
||||
bytes = sendto(
|
||||
ARCNET_Sock_FD, &mtu, mtu_len, 0,
|
||||
(struct sockaddr *)&ARCNET_Socket_Address,
|
||||
sizeof(ARCNET_Socket_Address));
|
||||
/* did it get sent? */
|
||||
if (bytes < 0)
|
||||
if (bytes < 0) {
|
||||
fprintf(stderr, "arcnet: Error sending packet: %s\n", strerror(errno));
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/* receives an framed packet */
|
||||
/* returns the number of octets in the PDU, or zero on failure */
|
||||
uint16_t arcnet_receive(BACNET_ADDRESS *src, /* source address */
|
||||
uint16_t arcnet_receive(
|
||||
BACNET_ADDRESS *src, /* source address */
|
||||
uint8_t *pdu, /* PDU data */
|
||||
uint16_t max_pdu, /* amount of space available in the PDU */
|
||||
unsigned timeout)
|
||||
@@ -237,8 +254,9 @@ uint16_t arcnet_receive(BACNET_ADDRESS *src, /* source address */
|
||||
struct archdr *pkt = (struct archdr *)buf;
|
||||
|
||||
/* Make sure the socket is open */
|
||||
if (ARCNET_Sock_FD <= 0)
|
||||
if (ARCNET_Sock_FD <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* we could just use a non-blocking socket, but that consumes all
|
||||
the CPU time. We can use a timeout; it is only supported as
|
||||
@@ -255,24 +273,28 @@ uint16_t arcnet_receive(BACNET_ADDRESS *src, /* source address */
|
||||
FD_SET(ARCNET_Sock_FD, &read_fds);
|
||||
max = ARCNET_Sock_FD;
|
||||
|
||||
if (select(max + 1, &read_fds, NULL, NULL, &select_timeout) > 0)
|
||||
if (select(max + 1, &read_fds, NULL, NULL, &select_timeout) > 0) {
|
||||
received_bytes = read(ARCNET_Sock_FD, &buf[0], sizeof(buf));
|
||||
else
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* See if there is a problem */
|
||||
if (received_bytes < 0) {
|
||||
/* EAGAIN Non-blocking I/O has been selected */
|
||||
/* using O_NONBLOCK and no data */
|
||||
/* was immediately available for reading. */
|
||||
if (errno != EAGAIN)
|
||||
fprintf(stderr, "ethernet: Read error in receiving packet: %s\n",
|
||||
if (errno != EAGAIN) {
|
||||
fprintf(
|
||||
stderr, "ethernet: Read error in receiving packet: %s\n",
|
||||
strerror(errno));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (received_bytes == 0)
|
||||
if (received_bytes == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* printf("arcnet: received %u bytes (offset=%02Xh %02Xh) "
|
||||
"from %02Xh (proto==%02Xh)\n",
|
||||
@@ -312,11 +334,13 @@ uint16_t arcnet_receive(BACNET_ADDRESS *src, /* source address */
|
||||
pdu_len = received_bytes - ARC_HDR_SIZE;
|
||||
pdu_len -= 4 /* SC, DSAP, SSAP, LLC Control */;
|
||||
/* copy the buffer into the PDU */
|
||||
if (pdu_len < max_pdu)
|
||||
if (pdu_len < max_pdu) {
|
||||
memmove(&pdu[0], &pkt->soft.raw[4], pdu_len);
|
||||
}
|
||||
/* silently ignore packets that are too large */
|
||||
else
|
||||
else {
|
||||
pdu_len = 0;
|
||||
}
|
||||
|
||||
return pdu_len;
|
||||
}
|
||||
|
||||
+43
-47
@@ -1,56 +1,56 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
*
|
||||
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef BACPORT_H
|
||||
#define BACPORT_H
|
||||
|
||||
/* common unix sockets headers needed */
|
||||
#include <sys/types.h> /* basic system data types */
|
||||
#include <sys/time.h> /* timeval{} for select() */
|
||||
#include <time.h> /* timespec{} for pselect() */
|
||||
#include <netinet/in.h> /* sockaddr_in{} and other Internet defns */
|
||||
#include <arpa/inet.h> /* inet(3) functions */
|
||||
#include <fcntl.h> /* for nonblocking */
|
||||
#include <netdb.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h> /* for S_xxx file mode constants */
|
||||
#include <sys/uio.h> /* for iovec{} and readv/writev */
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/un.h> /* for Unix domain sockets */
|
||||
#include <sys/types.h> /* basic system data types */
|
||||
#include <sys/time.h> /* timeval{} for select() */
|
||||
#include <time.h> /* timespec{} for pselect() */
|
||||
#include <netinet/in.h> /* sockaddr_in{} and other Internet defns */
|
||||
#include <arpa/inet.h> /* inet(3) functions */
|
||||
#include <fcntl.h> /* for nonblocking */
|
||||
#include <netdb.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h> /* for S_xxx file mode constants */
|
||||
#include <sys/uio.h> /* for iovec{} and readv/writev */
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/un.h> /* for Unix domain sockets */
|
||||
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
#include <sys/select.h> /* for convenience */
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
#include <sys/select.h> /* for convenience */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_POLL_H
|
||||
#include <poll.h> /* for convenience */
|
||||
#ifdef HAVE_POLL_H
|
||||
#include <poll.h> /* for convenience */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRINGS_H
|
||||
#include <strings.h> /* for convenience */
|
||||
#ifdef HAVE_STRINGS_H
|
||||
#include <strings.h> /* for convenience */
|
||||
#endif
|
||||
|
||||
/* Three headers are normally needed for socket/file ioctl's:
|
||||
* <sys/ioctl.h>, <sys/filio.h>, and <sys/sockio.h>.
|
||||
*/
|
||||
#ifdef HAVE_SYS_IOCTL_H
|
||||
#include <sys/ioctl.h>
|
||||
#ifdef HAVE_SYS_IOCTL_H
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_FILIO_H
|
||||
#include <sys/filio.h>
|
||||
#ifdef HAVE_SYS_FILIO_H
|
||||
#include <sys/filio.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKIO_H
|
||||
#include <sys/sockio.h>
|
||||
#ifdef HAVE_SYS_SOCKIO_H
|
||||
#include <sys/sockio.h>
|
||||
#endif
|
||||
|
||||
#include <pthread.h>
|
||||
@@ -65,10 +65,10 @@
|
||||
#ifndef __CYGWIN__
|
||||
#include <net/if_arp.h>
|
||||
#endif
|
||||
#include <features.h> /* for the glibc version number */
|
||||
#include <features.h> /* for the glibc version number */
|
||||
#if __GLIBC__ >= 2 && __GLIBC_MINOR >= 1
|
||||
#include <netpacket/packet.h>
|
||||
#include <net/ethernet.h> /* the L2 protocols */
|
||||
#include <net/ethernet.h> /* the L2 protocols */
|
||||
#else
|
||||
#include <asm/types.h>
|
||||
#ifndef __CYGWIN__
|
||||
@@ -84,24 +84,20 @@
|
||||
#include <netdb.h>
|
||||
#include "bacnet/basic/sys/bacnet_stack_exports.h"
|
||||
|
||||
#define BACNET_OBJECT_TABLE(table_name, _type, _init, _count, \
|
||||
_index_to_instance, _valid_instance, _object_name, \
|
||||
_read_property, _write_property, _RPM_list, \
|
||||
_RR_info, _iterator, _value_list, _COV, \
|
||||
_COV_clear, _intrinsic_reporting) \
|
||||
#define BACNET_OBJECT_TABLE( \
|
||||
table_name, _type, _init, _count, _index_to_instance, _valid_instance, \
|
||||
_object_name, _read_property, _write_property, _RPM_list, _RR_info, \
|
||||
_iterator, _value_list, _COV, _COV_clear, _intrinsic_reporting) \
|
||||
static_assert(false, "Unsupported BACNET_OBJECT_TABLE for this platform")
|
||||
|
||||
/** @file linux/bacport.h Includes Linux network headers. */
|
||||
|
||||
/* Local helper functions for this port */
|
||||
BACNET_STACK_EXPORT
|
||||
extern int bip_get_local_netmask(
|
||||
struct in_addr *netmask);
|
||||
extern int bip_get_local_netmask(struct in_addr *netmask);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
extern int bip_get_local_address_ioctl(
|
||||
const char *ifname,
|
||||
struct in_addr *addr,
|
||||
int request);
|
||||
const char *ifname, struct in_addr *addr, int request);
|
||||
|
||||
#endif
|
||||
|
||||
+40
-26
@@ -60,13 +60,15 @@ static char BIP_Interface_Name[IF_NAMESIZE] = { 0 };
|
||||
* @param str - debug info string
|
||||
* @param addr - IPv4 address
|
||||
*/
|
||||
static void debug_print_ipv4(const char *str,
|
||||
static void debug_print_ipv4(
|
||||
const char *str,
|
||||
const struct in_addr *addr,
|
||||
const unsigned int port,
|
||||
const unsigned int count)
|
||||
{
|
||||
if (BIP_Debug) {
|
||||
fprintf(stderr, "BIP: %s %s:%hu (%u bytes)\n", str, inet_ntoa(*addr),
|
||||
fprintf(
|
||||
stderr, "BIP: %s %s:%hu (%u bytes)\n", str, inet_ntoa(*addr),
|
||||
ntohs(port), count);
|
||||
fflush(stderr);
|
||||
}
|
||||
@@ -293,8 +295,9 @@ int bip_send_mpdu(
|
||||
/* Send the packet */
|
||||
debug_print_ipv4(
|
||||
"Sending MPDU->", &bip_dest.sin_addr, bip_dest.sin_port, mtu_len);
|
||||
return sendto(BIP_Socket, (const char *)mtu, mtu_len, 0,
|
||||
(struct sockaddr *)&bip_dest, sizeof(struct sockaddr));
|
||||
return sendto(
|
||||
BIP_Socket, (const char *)mtu, mtu_len, 0, (struct sockaddr *)&bip_dest,
|
||||
sizeof(struct sockaddr));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -345,10 +348,11 @@ uint16_t bip_receive(
|
||||
|
||||
/* see if there is a packet for us */
|
||||
if (select(max + 1, &read_fds, NULL, NULL, &select_timeout) > 0) {
|
||||
socket = FD_ISSET(BIP_Socket, &read_fds) ? BIP_Socket :
|
||||
BIP_Broadcast_Socket;
|
||||
received_bytes = recvfrom(socket, (char *)&npdu[0], max_npdu, 0,
|
||||
(struct sockaddr *)&sin, &sin_len);
|
||||
socket =
|
||||
FD_ISSET(BIP_Socket, &read_fds) ? BIP_Socket : BIP_Broadcast_Socket;
|
||||
received_bytes = recvfrom(
|
||||
socket, (char *)&npdu[0], max_npdu, 0, (struct sockaddr *)&sin,
|
||||
&sin_len);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
@@ -423,7 +427,8 @@ uint16_t bip_receive(
|
||||
* @return Upon successful completion, returns the number of bytes sent.
|
||||
* Otherwise, -1 shall be returned and errno set to indicate the error.
|
||||
*/
|
||||
int bip_send_pdu(BACNET_ADDRESS *dest,
|
||||
int bip_send_pdu(
|
||||
BACNET_ADDRESS *dest,
|
||||
BACNET_NPDU_DATA *npdu_data,
|
||||
uint8_t *pdu,
|
||||
unsigned pdu_len)
|
||||
@@ -466,8 +471,8 @@ bool bip_get_addr_by_name(const char *host_name, BACNET_IP_ADDRESS *addr)
|
||||
* @param request - the ioctl() request
|
||||
* @return 0 on success, else the error from the ioctl() call.
|
||||
*/
|
||||
static int get_local_ifr_ioctl(
|
||||
const char *ifname, struct ifreq *ifr, int request)
|
||||
static int
|
||||
get_local_ifr_ioctl(const char *ifname, struct ifreq *ifr, int request)
|
||||
{
|
||||
int fd;
|
||||
int rv; /* return value */
|
||||
@@ -526,8 +531,8 @@ struct route_info {
|
||||
* @param pId - process identifier of our specific request response
|
||||
* @return number of bytes placed into the buffer
|
||||
*/
|
||||
static int readNlSock(
|
||||
int sockFd, char *bufPtr, size_t buf_size, int seqNum, int pId)
|
||||
static int
|
||||
readNlSock(int sockFd, char *bufPtr, size_t buf_size, int seqNum, int pId)
|
||||
{
|
||||
struct nlmsghdr *nlHdr;
|
||||
int readLen = 0, msgLen = 0;
|
||||
@@ -574,7 +579,8 @@ static char *ntoa(uint32_t addr)
|
||||
{
|
||||
static char buffer[18];
|
||||
|
||||
snprintf(buffer, sizeof(buffer), "%d.%d.%d.%d", (addr & 0x000000FF),
|
||||
snprintf(
|
||||
buffer, sizeof(buffer), "%d.%d.%d.%d", (addr & 0x000000FF),
|
||||
(addr & 0x0000FF00) >> 8, (addr & 0x00FF0000) >> 16,
|
||||
(addr & 0xFF000000) >> 24);
|
||||
|
||||
@@ -589,18 +595,21 @@ static void printRoute(struct route_info *rtInfo)
|
||||
{
|
||||
if (BIP_Debug) {
|
||||
/* Print Destination address */
|
||||
fprintf(stderr, "%s\t",
|
||||
fprintf(
|
||||
stderr, "%s\t",
|
||||
rtInfo->dstAddr ? ntoa(rtInfo->dstAddr) : "0.0.0.0 ");
|
||||
|
||||
/* Print Gateway address */
|
||||
fprintf(stderr, "%s\t",
|
||||
fprintf(
|
||||
stderr, "%s\t",
|
||||
rtInfo->gateWay ? ntoa(rtInfo->gateWay) : "*.*.*.*");
|
||||
|
||||
/* Print Interface Name */
|
||||
fprintf(stderr, "%s\t", rtInfo->ifName);
|
||||
|
||||
/* Print Source address */
|
||||
fprintf(stderr, "%s\n",
|
||||
fprintf(
|
||||
stderr, "%s\n",
|
||||
rtInfo->srcAddr ? ntoa(rtInfo->srcAddr) : "*.*.*.*");
|
||||
}
|
||||
}
|
||||
@@ -620,8 +629,9 @@ static void parseRoutes(struct nlmsghdr *nlHdr, struct route_info *rtInfo)
|
||||
|
||||
/* If the route is not for AF_INET or does not belong to main routing table
|
||||
then return. */
|
||||
if ((rtMsg->rtm_family != AF_INET) || (rtMsg->rtm_table != RT_TABLE_MAIN))
|
||||
if ((rtMsg->rtm_family != AF_INET) || (rtMsg->rtm_table != RT_TABLE_MAIN)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* get the rtattr field */
|
||||
rtAttr = (struct rtattr *)RTM_RTA(rtMsg);
|
||||
@@ -700,7 +710,8 @@ static char *ifname_default(void)
|
||||
if (BIP_Interface_Name[0] == 0) {
|
||||
if ((rtInfo->dstAddr == 0) && (rtInfo->ifName[0] != 0)) {
|
||||
/* default route */
|
||||
memcpy(BIP_Interface_Name, rtInfo->ifName,
|
||||
memcpy(
|
||||
BIP_Interface_Name, rtInfo->ifName,
|
||||
sizeof(BIP_Interface_Name));
|
||||
}
|
||||
}
|
||||
@@ -734,8 +745,7 @@ int bip_get_local_netmask(struct in_addr *netmask)
|
||||
* @param baddr The broadcast socket binding address, in host order.
|
||||
* @return 0 on success
|
||||
*/
|
||||
int bip_set_broadcast_binding(
|
||||
const char *ip4_broadcast)
|
||||
int bip_set_broadcast_binding(const char *ip4_broadcast)
|
||||
{
|
||||
BIP_Broadcast_Binding_Address.s_addr = inet_addr(ip4_broadcast);
|
||||
BIP_Broadcast_Binding_Address_Override = true;
|
||||
@@ -799,9 +809,11 @@ void bip_set_interface(const char *ifname)
|
||||
}
|
||||
#endif
|
||||
if (BIP_Debug) {
|
||||
fprintf(stderr, "BIP: Broadcast Address: %s\n",
|
||||
fprintf(
|
||||
stderr, "BIP: Broadcast Address: %s\n",
|
||||
inet_ntoa(BIP_Broadcast_Addr));
|
||||
fprintf(stderr, "BIP: UDP Port: 0x%04X [%hu]\n", ntohs(BIP_Port),
|
||||
fprintf(
|
||||
stderr, "BIP: UDP Port: 0x%04X [%hu]\n", ntohs(BIP_Port),
|
||||
ntohs(BIP_Port));
|
||||
fflush(stderr);
|
||||
}
|
||||
@@ -835,8 +847,9 @@ static int createSocket(const struct sockaddr_in *sin)
|
||||
return status;
|
||||
}
|
||||
/* Bind to the proper interface to send without default gateway */
|
||||
status = setsockopt(sock_fd, SOL_SOCKET, SO_BINDTODEVICE,
|
||||
BIP_Interface_Name, strlen(BIP_Interface_Name));
|
||||
status = setsockopt(
|
||||
sock_fd, SOL_SOCKET, SO_BINDTODEVICE, BIP_Interface_Name,
|
||||
strlen(BIP_Interface_Name));
|
||||
if (status < 0) {
|
||||
if (BIP_Debug) {
|
||||
perror("SO_BINDTODEVICE: ");
|
||||
@@ -882,7 +895,8 @@ bool bip_init(char *ifname)
|
||||
bip_set_interface(ifname_default());
|
||||
}
|
||||
if (BIP_Address.s_addr == 0) {
|
||||
fprintf(stderr, "BIP: Failed to get an IP address from %s!\n",
|
||||
fprintf(
|
||||
stderr, "BIP: Failed to get an IP address from %s!\n",
|
||||
BIP_Interface_Name);
|
||||
fflush(stderr);
|
||||
return false;
|
||||
|
||||
+36
-24
@@ -55,16 +55,16 @@ static void debug_fprintf_bip6(FILE *stream, const char *format, ...)
|
||||
*/
|
||||
static void debug_print_ipv6(const char *str, const struct in6_addr *addr)
|
||||
{
|
||||
debug_fprintf_bip6(stdout, "BIP6: %s "
|
||||
debug_fprintf_bip6(
|
||||
stdout,
|
||||
"BIP6: %s "
|
||||
"%02x%02x:%02x%02x:%02x%02x:%02x%02x:"
|
||||
"%02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
|
||||
str, (int)addr->s6_addr[0], (int)addr->s6_addr[1],
|
||||
(int)addr->s6_addr[2], (int)addr->s6_addr[3],
|
||||
(int)addr->s6_addr[4], (int)addr->s6_addr[5],
|
||||
(int)addr->s6_addr[6], (int)addr->s6_addr[7],
|
||||
(int)addr->s6_addr[8], (int)addr->s6_addr[9],
|
||||
(int)addr->s6_addr[10], (int)addr->s6_addr[11],
|
||||
(int)addr->s6_addr[12], (int)addr->s6_addr[13],
|
||||
(int)addr->s6_addr[2], (int)addr->s6_addr[3], (int)addr->s6_addr[4],
|
||||
(int)addr->s6_addr[5], (int)addr->s6_addr[6], (int)addr->s6_addr[7],
|
||||
(int)addr->s6_addr[8], (int)addr->s6_addr[9], (int)addr->s6_addr[10],
|
||||
(int)addr->s6_addr[11], (int)addr->s6_addr[12], (int)addr->s6_addr[13],
|
||||
(int)addr->s6_addr[14], (int)addr->s6_addr[15]);
|
||||
}
|
||||
|
||||
@@ -106,12 +106,13 @@ void bip6_set_interface(char *ifname)
|
||||
while (ifa_tmp) {
|
||||
if ((ifa_tmp->ifa_addr) && (ifa_tmp->ifa_addr->sa_family == AF_INET6)) {
|
||||
debug_fprintf_bip6(
|
||||
stdout, "BIP6: found interface: %s\n",ifa_tmp->ifa_name);
|
||||
stdout, "BIP6: found interface: %s\n", ifa_tmp->ifa_name);
|
||||
}
|
||||
if ((ifa_tmp->ifa_addr) && (ifa_tmp->ifa_addr->sa_family == AF_INET6) &&
|
||||
(strcasecmp(ifa_tmp->ifa_name, ifname) == 0)) {
|
||||
sin = (struct sockaddr_in6 *)ifa_tmp->ifa_addr;
|
||||
bvlc6_address_set(&BIP6_Addr, ntohs(sin->sin6_addr.s6_addr16[0]),
|
||||
bvlc6_address_set(
|
||||
&BIP6_Addr, ntohs(sin->sin6_addr.s6_addr16[0]),
|
||||
ntohs(sin->sin6_addr.s6_addr16[1]),
|
||||
ntohs(sin->sin6_addr.s6_addr16[2]),
|
||||
ntohs(sin->sin6_addr.s6_addr16[3]),
|
||||
@@ -127,7 +128,8 @@ void bip6_set_interface(char *ifname)
|
||||
ifa_tmp = ifa_tmp->ifa_next;
|
||||
}
|
||||
if (!found) {
|
||||
debug_fprintf_bip6(stderr, "BIP6: unable to set interface: %s\n", ifname);
|
||||
debug_fprintf_bip6(
|
||||
stderr, "BIP6: unable to set interface: %s\n", ifname);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
@@ -246,8 +248,9 @@ int bip6_send_mpdu(
|
||||
}
|
||||
/* load destination IP address */
|
||||
bvlc_dest.sin6_family = AF_INET6;
|
||||
bvlc6_address_get(dest, &addr16[0], &addr16[1], &addr16[2], &addr16[3],
|
||||
&addr16[4], &addr16[5], &addr16[6], &addr16[7]);
|
||||
bvlc6_address_get(
|
||||
dest, &addr16[0], &addr16[1], &addr16[2], &addr16[3], &addr16[4],
|
||||
&addr16[5], &addr16[6], &addr16[7]);
|
||||
bvlc_dest.sin6_addr.s6_addr16[0] = htons(addr16[0]);
|
||||
bvlc_dest.sin6_addr.s6_addr16[1] = htons(addr16[1]);
|
||||
bvlc_dest.sin6_addr.s6_addr16[2] = htons(addr16[2]);
|
||||
@@ -260,7 +263,8 @@ int bip6_send_mpdu(
|
||||
bvlc_dest.sin6_scope_id = BIP6_Socket_Scope_Id;
|
||||
debug_print_ipv6("Sending MPDU->", &bvlc_dest.sin6_addr);
|
||||
/* Send the packet */
|
||||
return sendto(BIP6_Socket, (const char *)mtu, mtu_len, 0,
|
||||
return sendto(
|
||||
BIP6_Socket, (const char *)mtu, mtu_len, 0,
|
||||
(struct sockaddr *)&bvlc_dest, sizeof(bvlc_dest));
|
||||
}
|
||||
|
||||
@@ -276,7 +280,8 @@ int bip6_send_mpdu(
|
||||
* @return Upon successful completion, returns the number of bytes sent.
|
||||
* Otherwise, -1 shall be returned and errno set to indicate the error.
|
||||
*/
|
||||
int bip6_send_pdu(BACNET_ADDRESS *dest,
|
||||
int bip6_send_pdu(
|
||||
BACNET_ADDRESS *dest,
|
||||
BACNET_NPDU_DATA *npdu_data,
|
||||
uint8_t *pdu,
|
||||
unsigned pdu_len)
|
||||
@@ -328,8 +333,9 @@ uint16_t bip6_receive(
|
||||
max = BIP6_Socket;
|
||||
/* see if there is a packet for us */
|
||||
if (select(max + 1, &read_fds, NULL, NULL, &select_timeout) > 0) {
|
||||
received_bytes = recvfrom(BIP6_Socket, (char *)&npdu[0], max_npdu, 0,
|
||||
(struct sockaddr *)&sin, &sin_len);
|
||||
received_bytes = recvfrom(
|
||||
BIP6_Socket, (char *)&npdu[0], max_npdu, 0, (struct sockaddr *)&sin,
|
||||
&sin_len);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
@@ -347,7 +353,8 @@ uint16_t bip6_receive(
|
||||
}
|
||||
/* pass the packet into the BBMD handler */
|
||||
debug_print_ipv6("Received MPDU->", &sin.sin6_addr);
|
||||
bvlc6_address_set(&addr, ntohs(sin.sin6_addr.s6_addr16[0]),
|
||||
bvlc6_address_set(
|
||||
&addr, ntohs(sin.sin6_addr.s6_addr16[0]),
|
||||
ntohs(sin.sin6_addr.s6_addr16[1]), ntohs(sin.sin6_addr.s6_addr16[2]),
|
||||
ntohs(sin.sin6_addr.s6_addr16[3]), ntohs(sin.sin6_addr.s6_addr16[4]),
|
||||
ntohs(sin.sin6_addr.s6_addr16[5]), ntohs(sin.sin6_addr.s6_addr16[6]),
|
||||
@@ -418,13 +425,15 @@ bool bip6_init(char *ifname)
|
||||
}
|
||||
debug_fprintf_bip6(stdout, "BIP6: IPv6 UDP port: 0x%04X\n", BIP6_Addr.port);
|
||||
if (BIP6_Broadcast_Addr.address[0] == 0) {
|
||||
bvlc6_address_set(&BIP6_Broadcast_Addr, BIP6_MULTICAST_SITE_LOCAL, 0, 0,
|
||||
0, 0, 0, 0, BIP6_MULTICAST_GROUP_ID);
|
||||
bvlc6_address_set(
|
||||
&BIP6_Broadcast_Addr, BIP6_MULTICAST_SITE_LOCAL, 0, 0, 0, 0, 0, 0,
|
||||
BIP6_MULTICAST_GROUP_ID);
|
||||
}
|
||||
/* assumes that the driver has already been initialized */
|
||||
BIP6_Socket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (BIP6_Socket < 0)
|
||||
if (BIP6_Socket < 0) {
|
||||
return false;
|
||||
}
|
||||
/* Allow us to use the same socket for sending and receiving */
|
||||
/* This makes sure that the src port is correct when sending */
|
||||
sockopt = 1;
|
||||
@@ -444,14 +453,17 @@ bool bip6_init(char *ifname)
|
||||
return false;
|
||||
}
|
||||
/* subscribe to a multicast address */
|
||||
memcpy(&broadcast_address.s6_addr[0], &BIP6_Broadcast_Addr.address[0],
|
||||
memcpy(
|
||||
&broadcast_address.s6_addr[0], &BIP6_Broadcast_Addr.address[0],
|
||||
IP6_ADDRESS_MAX);
|
||||
memcpy(&join_request.ipv6mr_multiaddr, &broadcast_address,
|
||||
memcpy(
|
||||
&join_request.ipv6mr_multiaddr, &broadcast_address,
|
||||
sizeof(struct in6_addr));
|
||||
/* Let system not choose the interface */
|
||||
join_request.ipv6mr_interface = BIP6_Socket_Scope_Id;
|
||||
status = setsockopt(BIP6_Socket, IPPROTO_IPV6, IPV6_JOIN_GROUP,
|
||||
&join_request, sizeof(join_request));
|
||||
status = setsockopt(
|
||||
BIP6_Socket, IPPROTO_IPV6, IPV6_JOIN_GROUP, &join_request,
|
||||
sizeof(join_request));
|
||||
if (status < 0) {
|
||||
perror("BIP: setsockopt(IPV6_JOIN_GROUP)");
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ static int32_t Time_Offset; /* Time offset in ms */
|
||||
/**
|
||||
* @brief Calculate the time offset from the system clock.
|
||||
* @return Time offset in ms
|
||||
*/
|
||||
*/
|
||||
static int32_t time_difference(struct timeval t0, struct timeval t1)
|
||||
{
|
||||
return (t0.tv_sec - t1.tv_sec) * 1000 + (t0.tv_usec - t1.tv_usec) / 1000;
|
||||
|
||||
+10
-5
@@ -267,16 +267,19 @@ static void *dlmstp_master_fsm_task(void *pArg)
|
||||
silence = MSTP_Port.SilenceTimer(&MSTP_Port);
|
||||
switch (MSTP_Port.master_state) {
|
||||
case MSTP_MASTER_STATE_IDLE:
|
||||
if (silence >= Tno_token)
|
||||
if (silence >= Tno_token) {
|
||||
run_master = true;
|
||||
}
|
||||
break;
|
||||
case MSTP_MASTER_STATE_WAIT_FOR_REPLY:
|
||||
if (silence >= Treply_timeout)
|
||||
if (silence >= Treply_timeout) {
|
||||
run_master = true;
|
||||
}
|
||||
break;
|
||||
case MSTP_MASTER_STATE_POLL_FOR_MASTER:
|
||||
if (silence >= Tusage_timeout)
|
||||
if (silence >= Tusage_timeout) {
|
||||
run_master = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
run_master = true;
|
||||
@@ -290,8 +293,9 @@ static void *dlmstp_master_fsm_task(void *pArg)
|
||||
/* do nothing while immediate transitioning */
|
||||
run_loop = MSTP_Master_Node_FSM(&MSTP_Port);
|
||||
pthread_mutex_lock(&Thread_Mutex);
|
||||
if (!run_thread)
|
||||
if (!run_thread) {
|
||||
run_loop = false;
|
||||
}
|
||||
pthread_mutex_unlock(&Thread_Mutex);
|
||||
}
|
||||
} else if (MSTP_Port.This_Station < 255) {
|
||||
@@ -578,8 +582,9 @@ void dlmstp_set_mac_address(uint8_t mac_address)
|
||||
/* Master Nodes can only have address 0-127 */
|
||||
if (mac_address <= 127) {
|
||||
MSTP_Port.This_Station = mac_address;
|
||||
if (mac_address > MSTP_Port.Nmax_master)
|
||||
if (mac_address > MSTP_Port.Nmax_master) {
|
||||
dlmstp_set_max_master(mac_address);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
@@ -258,16 +258,19 @@ static void *dlmstp_master_fsm_task(void *pArg)
|
||||
silence = mstp_port->SilenceTimer(NULL);
|
||||
switch (mstp_port->master_state) {
|
||||
case MSTP_MASTER_STATE_IDLE:
|
||||
if (silence >= Tno_token)
|
||||
if (silence >= Tno_token) {
|
||||
run_master = true;
|
||||
}
|
||||
break;
|
||||
case MSTP_MASTER_STATE_WAIT_FOR_REPLY:
|
||||
if (silence >= mstp_port->Treply_timeout)
|
||||
if (silence >= mstp_port->Treply_timeout) {
|
||||
run_master = true;
|
||||
}
|
||||
break;
|
||||
case MSTP_MASTER_STATE_POLL_FOR_MASTER:
|
||||
if (silence >= mstp_port->Tusage_timeout)
|
||||
if (silence >= mstp_port->Tusage_timeout) {
|
||||
run_master = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
run_master = true;
|
||||
@@ -324,8 +327,9 @@ uint16_t MSTP_Put_Receive(struct mstp_port_struct_t *mstp_port)
|
||||
if (!poSharedData->Receive_Packet.ready) {
|
||||
/* bounds check - maybe this should send an abort? */
|
||||
pdu_len = mstp_port->DataLength;
|
||||
if (pdu_len > sizeof(poSharedData->Receive_Packet.pdu))
|
||||
if (pdu_len > sizeof(poSharedData->Receive_Packet.pdu)) {
|
||||
pdu_len = sizeof(poSharedData->Receive_Packet.pdu);
|
||||
}
|
||||
memmove(
|
||||
(void *)&poSharedData->Receive_Packet.pdu[0],
|
||||
(void *)&mstp_port->InputBuffer[0], pdu_len);
|
||||
@@ -580,8 +584,9 @@ void dlmstp_set_mac_address(void *poPort, uint8_t mac_address)
|
||||
/* Master Nodes can only have address 0-127 */
|
||||
if (mac_address <= 127) {
|
||||
mstp_port->This_Station = mac_address;
|
||||
if (mac_address > mstp_port->Nmax_master)
|
||||
if (mac_address > mstp_port->Nmax_master) {
|
||||
dlmstp_set_max_master(mstp_port, mac_address);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
+71
-92
@@ -1,10 +1,10 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2012 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
*
|
||||
* Copyright (C) 2012 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
#ifndef DLMSTP_LINUX_H
|
||||
#define DLMSTP_LINUX_H
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
#include "bacnet/basic/sys/ringbuf.h"
|
||||
/* defines specific to MS/TP */
|
||||
/* preamble+type+dest+src+len+crc8+crc16 */
|
||||
#define DLMSTP_HEADER_MAX (2+1+1+1+2+1+2)
|
||||
#define DLMSTP_MPDU_MAX (DLMSTP_HEADER_MAX+MAX_PDU)
|
||||
#define DLMSTP_HEADER_MAX (2 + 1 + 1 + 1 + 2 + 1 + 2)
|
||||
#define DLMSTP_MPDU_MAX (DLMSTP_HEADER_MAX + MAX_PDU)
|
||||
|
||||
/* count must be a power of 2 for ringbuf library */
|
||||
#ifndef MSTP_PDU_PACKET_COUNT
|
||||
@@ -35,10 +35,10 @@
|
||||
|
||||
typedef struct dlmstp_packet {
|
||||
bool ready; /* true if ready to be sent or received */
|
||||
BACNET_ADDRESS address; /* source address */
|
||||
BACNET_ADDRESS address; /* source address */
|
||||
uint8_t frame_type; /* type of message */
|
||||
uint16_t pdu_len; /* packet length */
|
||||
uint8_t pdu[DLMSTP_MPDU_MAX]; /* packet */
|
||||
uint16_t pdu_len; /* packet length */
|
||||
uint8_t pdu[DLMSTP_MPDU_MAX]; /* packet */
|
||||
} DLMSTP_PACKET;
|
||||
|
||||
/* data structure for MS/TP PDU Queue */
|
||||
@@ -103,96 +103,75 @@ typedef struct shared_mstp_data {
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
bool dlmstp_init(
|
||||
void *poShared,
|
||||
char *ifname);
|
||||
BACNET_STACK_EXPORT
|
||||
void dlmstp_reset(
|
||||
void *poShared);
|
||||
BACNET_STACK_EXPORT
|
||||
void dlmstp_cleanup(
|
||||
void *poShared);
|
||||
BACNET_STACK_EXPORT
|
||||
bool dlmstp_init(void *poShared, char *ifname);
|
||||
BACNET_STACK_EXPORT
|
||||
void dlmstp_reset(void *poShared);
|
||||
BACNET_STACK_EXPORT
|
||||
void dlmstp_cleanup(void *poShared);
|
||||
|
||||
/* returns number of bytes sent on success, negative on failure */
|
||||
BACNET_STACK_EXPORT
|
||||
int dlmstp_send_pdu(
|
||||
void *poShared,
|
||||
BACNET_ADDRESS * dest, /* destination address */
|
||||
uint8_t * pdu, /* any data to be sent - may be null */
|
||||
unsigned pdu_len); /* number of bytes of data */
|
||||
/* returns number of bytes sent on success, negative on failure */
|
||||
BACNET_STACK_EXPORT
|
||||
int dlmstp_send_pdu(
|
||||
void *poShared,
|
||||
BACNET_ADDRESS *dest, /* destination address */
|
||||
uint8_t *pdu, /* any data to be sent - may be null */
|
||||
unsigned pdu_len); /* number of bytes of data */
|
||||
|
||||
/* returns the number of octets in the PDU, or zero on failure */
|
||||
BACNET_STACK_EXPORT
|
||||
uint16_t dlmstp_receive(
|
||||
void *poShared,
|
||||
BACNET_ADDRESS * src, /* source address */
|
||||
uint8_t * pdu, /* PDU data */
|
||||
uint16_t max_pdu, /* amount of space available in the PDU */
|
||||
unsigned timeout); /* milliseconds to wait for a packet */
|
||||
/* returns the number of octets in the PDU, or zero on failure */
|
||||
BACNET_STACK_EXPORT
|
||||
uint16_t dlmstp_receive(
|
||||
void *poShared,
|
||||
BACNET_ADDRESS *src, /* source address */
|
||||
uint8_t *pdu, /* PDU data */
|
||||
uint16_t max_pdu, /* amount of space available in the PDU */
|
||||
unsigned timeout); /* milliseconds to wait for a packet */
|
||||
|
||||
/* This parameter represents the value of the Max_Info_Frames property of */
|
||||
/* the node's Device object. The value of Max_Info_Frames specifies the */
|
||||
/* maximum number of information frames the node may send before it must */
|
||||
/* pass the token. Max_Info_Frames may have different values on different */
|
||||
/* nodes. This may be used to allocate more or less of the available link */
|
||||
/* bandwidth to particular nodes. If Max_Info_Frames is not writable in a */
|
||||
/* node, its value shall be 1. */
|
||||
BACNET_STACK_EXPORT
|
||||
void dlmstp_set_max_info_frames(
|
||||
void *poShared,
|
||||
uint8_t max_info_frames);
|
||||
BACNET_STACK_EXPORT
|
||||
uint8_t dlmstp_max_info_frames(
|
||||
void *poShared);
|
||||
/* This parameter represents the value of the Max_Info_Frames property of */
|
||||
/* the node's Device object. The value of Max_Info_Frames specifies the */
|
||||
/* maximum number of information frames the node may send before it must */
|
||||
/* pass the token. Max_Info_Frames may have different values on different */
|
||||
/* nodes. This may be used to allocate more or less of the available link */
|
||||
/* bandwidth to particular nodes. If Max_Info_Frames is not writable in a */
|
||||
/* node, its value shall be 1. */
|
||||
BACNET_STACK_EXPORT
|
||||
void dlmstp_set_max_info_frames(void *poShared, uint8_t max_info_frames);
|
||||
BACNET_STACK_EXPORT
|
||||
uint8_t dlmstp_max_info_frames(void *poShared);
|
||||
|
||||
/* This parameter represents the value of the Max_Master property of the */
|
||||
/* node's Device object. The value of Max_Master specifies the highest */
|
||||
/* allowable address for master nodes. The value of Max_Master shall be */
|
||||
/* less than or equal to 127. If Max_Master is not writable in a node, */
|
||||
/* its value shall be 127. */
|
||||
BACNET_STACK_EXPORT
|
||||
void dlmstp_set_max_master(
|
||||
void *poShared,
|
||||
uint8_t max_master);
|
||||
BACNET_STACK_EXPORT
|
||||
uint8_t dlmstp_max_master(
|
||||
void *poShared);
|
||||
/* This parameter represents the value of the Max_Master property of the */
|
||||
/* node's Device object. The value of Max_Master specifies the highest */
|
||||
/* allowable address for master nodes. The value of Max_Master shall be */
|
||||
/* less than or equal to 127. If Max_Master is not writable in a node, */
|
||||
/* its value shall be 127. */
|
||||
BACNET_STACK_EXPORT
|
||||
void dlmstp_set_max_master(void *poShared, uint8_t max_master);
|
||||
BACNET_STACK_EXPORT
|
||||
uint8_t dlmstp_max_master(void *poShared);
|
||||
|
||||
/* MAC address 0-127 */
|
||||
BACNET_STACK_EXPORT
|
||||
void dlmstp_set_mac_address(
|
||||
void *poShared,
|
||||
uint8_t my_address);
|
||||
BACNET_STACK_EXPORT
|
||||
uint8_t dlmstp_mac_address(
|
||||
void *poShared);
|
||||
/* MAC address 0-127 */
|
||||
BACNET_STACK_EXPORT
|
||||
void dlmstp_set_mac_address(void *poShared, uint8_t my_address);
|
||||
BACNET_STACK_EXPORT
|
||||
uint8_t dlmstp_mac_address(void *poShared);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
void dlmstp_get_my_address(
|
||||
void *poShared,
|
||||
BACNET_ADDRESS * my_address);
|
||||
BACNET_STACK_EXPORT
|
||||
void dlmstp_get_broadcast_address(
|
||||
BACNET_ADDRESS * dest); /* destination address */
|
||||
BACNET_STACK_EXPORT
|
||||
void dlmstp_get_my_address(void *poShared, BACNET_ADDRESS *my_address);
|
||||
BACNET_STACK_EXPORT
|
||||
void dlmstp_get_broadcast_address(
|
||||
BACNET_ADDRESS *dest); /* destination address */
|
||||
|
||||
/* RS485 Baud Rate 9600, 19200, 38400, 57600, 115200 */
|
||||
BACNET_STACK_EXPORT
|
||||
void dlmstp_set_baud_rate(
|
||||
void *poShared,
|
||||
uint32_t baud);
|
||||
BACNET_STACK_EXPORT
|
||||
uint32_t dlmstp_baud_rate(
|
||||
void *poShared);
|
||||
/* RS485 Baud Rate 9600, 19200, 38400, 57600, 115200 */
|
||||
BACNET_STACK_EXPORT
|
||||
void dlmstp_set_baud_rate(void *poShared, uint32_t baud);
|
||||
BACNET_STACK_EXPORT
|
||||
uint32_t dlmstp_baud_rate(void *poShared);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
void dlmstp_fill_bacnet_address(
|
||||
BACNET_ADDRESS * src,
|
||||
uint8_t mstp_address);
|
||||
BACNET_STACK_EXPORT
|
||||
void dlmstp_fill_bacnet_address(BACNET_ADDRESS *src, uint8_t mstp_address);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
bool dlmstp_sole_master(
|
||||
void);
|
||||
BACNET_STACK_EXPORT
|
||||
bool dlmstp_sole_master(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
+48
-27
@@ -17,8 +17,9 @@
|
||||
* BACnet/Ethernet. */
|
||||
|
||||
/* commonly used comparison address for ethernet */
|
||||
uint8_t Ethernet_Broadcast[MAX_MAC_LEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF };
|
||||
uint8_t Ethernet_Broadcast[MAX_MAC_LEN] = {
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
|
||||
};
|
||||
/* commonly used empty address for ethernet quick compare */
|
||||
uint8_t Ethernet_Empty_MAC[MAX_MAC_LEN] = { 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
@@ -35,8 +36,9 @@ bool ethernet_valid(void)
|
||||
|
||||
void ethernet_cleanup(void)
|
||||
{
|
||||
if (ethernet_valid())
|
||||
if (ethernet_valid()) {
|
||||
close(eth802_sockfd);
|
||||
}
|
||||
eth802_sockfd = -1;
|
||||
|
||||
return;
|
||||
@@ -76,7 +78,8 @@ static int ethernet_bind(struct sockaddr *eth_addr, const char *interface_name)
|
||||
/* check to see if we are being run as root */
|
||||
uid = getuid();
|
||||
if (uid != 0) {
|
||||
fprintf(stderr,
|
||||
fprintf(
|
||||
stderr,
|
||||
"ethernet: Unable to open an 802.2 socket. "
|
||||
"Try running with root priveleges.\n");
|
||||
return sock_fd;
|
||||
@@ -93,7 +96,8 @@ static int ethernet_bind(struct sockaddr *eth_addr, const char *interface_name)
|
||||
/* Error occured */
|
||||
fprintf(
|
||||
stderr, "ethernet: Error opening socket: %s\n", strerror(errno));
|
||||
fprintf(stderr,
|
||||
fprintf(
|
||||
stderr,
|
||||
"You might need to add the following to modules.conf\n"
|
||||
"(or in /etc/modutils/alias on Debian with update-modules):\n"
|
||||
"alias net-pf-17 af_packet\n"
|
||||
@@ -121,9 +125,11 @@ static int ethernet_bind(struct sockaddr *eth_addr, const char *interface_name)
|
||||
/* Attempt to bind the socket to the interface */
|
||||
if (bind(sock_fd, eth_addr, sizeof(struct sockaddr)) != 0) {
|
||||
/* Bind problem, close socket and return */
|
||||
fprintf(stderr, "ethernet: Unable to bind 802.2 socket : %s\n",
|
||||
fprintf(
|
||||
stderr, "ethernet: Unable to bind 802.2 socket : %s\n",
|
||||
strerror(errno));
|
||||
fprintf(stderr,
|
||||
fprintf(
|
||||
stderr,
|
||||
"You might need to add the following to modules.conf\n"
|
||||
"(or in /etc/modutils/alias on Debian with update-modules):\n"
|
||||
"alias net-pf-17 af_packet\n"
|
||||
@@ -150,12 +156,13 @@ static int get_local_hwaddr(const char *ifname, unsigned char *mac)
|
||||
/* determine the local MAC address */
|
||||
strcpy(ifr.ifr_name, ifname);
|
||||
fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
|
||||
if (fd < 0)
|
||||
if (fd < 0) {
|
||||
rv = fd;
|
||||
else {
|
||||
} else {
|
||||
rv = ioctl(fd, SIOCGIFHWADDR, &ifr);
|
||||
if (rv >= 0) /* worked okay */
|
||||
if (rv >= 0) { /* worked okay */
|
||||
memcpy(mac, ifr.ifr_hwaddr.sa_data, IFHWADDRLEN);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
@@ -179,19 +186,22 @@ int ethernet_send(uint8_t *mtu, int mtu_len)
|
||||
int bytes = 0;
|
||||
|
||||
/* Send the packet */
|
||||
bytes = sendto(eth802_sockfd, &mtu, mtu_len, 0,
|
||||
(struct sockaddr *)ð_addr, sizeof(struct sockaddr));
|
||||
bytes = sendto(
|
||||
eth802_sockfd, &mtu, mtu_len, 0, (struct sockaddr *)ð_addr,
|
||||
sizeof(struct sockaddr));
|
||||
/* did it get sent? */
|
||||
if (bytes < 0)
|
||||
if (bytes < 0) {
|
||||
fprintf(
|
||||
stderr, "ethernet: Error sending packet: %s\n", strerror(errno));
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/* function to send a packet out the 802.2 socket */
|
||||
/* returns number of bytes sent on success, negative on failure */
|
||||
int ethernet_send_pdu(BACNET_ADDRESS *dest, /* destination address */
|
||||
int ethernet_send_pdu(
|
||||
BACNET_ADDRESS *dest, /* destination address */
|
||||
BACNET_NPDU_DATA *npdu_data, /* network information */
|
||||
uint8_t *pdu, /* any data to be sent - may be null */
|
||||
unsigned pdu_len)
|
||||
@@ -248,19 +258,22 @@ int ethernet_send_pdu(BACNET_ADDRESS *dest, /* destination address */
|
||||
encode_unsigned16(&mtu[12], 3 + pdu_len);
|
||||
|
||||
/* Send the packet */
|
||||
bytes = sendto(eth802_sockfd, &mtu, mtu_len, 0,
|
||||
(struct sockaddr *)ð_addr, sizeof(struct sockaddr));
|
||||
bytes = sendto(
|
||||
eth802_sockfd, &mtu, mtu_len, 0, (struct sockaddr *)ð_addr,
|
||||
sizeof(struct sockaddr));
|
||||
/* did it get sent? */
|
||||
if (bytes < 0)
|
||||
if (bytes < 0) {
|
||||
fprintf(
|
||||
stderr, "ethernet: Error sending packet: %s\n", strerror(errno));
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/* receives an 802.2 framed packet */
|
||||
/* returns the number of octets in the PDU, or zero on failure */
|
||||
uint16_t ethernet_receive(BACNET_ADDRESS *src, /* source address */
|
||||
uint16_t ethernet_receive(
|
||||
BACNET_ADDRESS *src, /* source address */
|
||||
uint8_t *pdu, /* PDU data */
|
||||
uint16_t max_pdu, /* amount of space available in the PDU */
|
||||
unsigned timeout)
|
||||
@@ -273,8 +286,9 @@ uint16_t ethernet_receive(BACNET_ADDRESS *src, /* source address */
|
||||
struct timeval select_timeout;
|
||||
|
||||
/* Make sure the socket is open */
|
||||
if (eth802_sockfd <= 0)
|
||||
if (eth802_sockfd <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* we could just use a non-blocking socket, but that consumes all
|
||||
the CPU time. We can use a timeout; it is only supported as
|
||||
@@ -291,24 +305,28 @@ uint16_t ethernet_receive(BACNET_ADDRESS *src, /* source address */
|
||||
FD_SET(eth802_sockfd, &read_fds);
|
||||
max = eth802_sockfd;
|
||||
|
||||
if (select(max + 1, &read_fds, NULL, NULL, &select_timeout) > 0)
|
||||
if (select(max + 1, &read_fds, NULL, NULL, &select_timeout) > 0) {
|
||||
received_bytes = read(eth802_sockfd, &buf[0], sizeof(buf));
|
||||
else
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* See if there is a problem */
|
||||
if (received_bytes < 0) {
|
||||
/* EAGAIN Non-blocking I/O has been selected */
|
||||
/* using O_NONBLOCK and no data */
|
||||
/* was immediately available for reading. */
|
||||
if (errno != EAGAIN)
|
||||
fprintf(stderr, "ethernet: Read error in receiving packet: %s\n",
|
||||
if (errno != EAGAIN) {
|
||||
fprintf(
|
||||
stderr, "ethernet: Read error in receiving packet: %s\n",
|
||||
strerror(errno));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (received_bytes == 0)
|
||||
if (received_bytes == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* the signature of an 802.2 BACnet packet */
|
||||
if ((buf[14] != 0x82) && (buf[15] != 0x82)) {
|
||||
@@ -330,11 +348,13 @@ uint16_t ethernet_receive(BACNET_ADDRESS *src, /* source address */
|
||||
(void)decode_unsigned16(&buf[12], &pdu_len);
|
||||
pdu_len -= 3 /* DSAP, SSAP, LLC Control */;
|
||||
/* copy the buffer into the PDU */
|
||||
if (pdu_len < max_pdu)
|
||||
if (pdu_len < max_pdu) {
|
||||
memmove(&pdu[0], &buf[17], pdu_len);
|
||||
}
|
||||
/* ignore packets that are too large */
|
||||
else
|
||||
else {
|
||||
pdu_len = 0;
|
||||
}
|
||||
|
||||
return pdu_len;
|
||||
}
|
||||
@@ -391,8 +411,9 @@ void ethernet_debug_address(const char *info, const BACNET_ADDRESS *dest)
|
||||
{
|
||||
int i = 0; /* counter */
|
||||
|
||||
if (info)
|
||||
if (info) {
|
||||
fprintf(stderr, "%s", info);
|
||||
}
|
||||
if (dest) {
|
||||
fprintf(stderr, "Address:\n");
|
||||
fprintf(stderr, " MAC Length=%d\n", dest->mac_len);
|
||||
|
||||
@@ -68,8 +68,7 @@ uint16_t MSTP_Put_Receive(struct mstp_port_struct_t *mstp_port)
|
||||
|
||||
/* for the MS/TP state machine to use for getting data to send */
|
||||
/* Return: amount of PDU data */
|
||||
uint16_t MSTP_Get_Send(
|
||||
struct mstp_port_struct_t *mstp_port, unsigned timeout)
|
||||
uint16_t MSTP_Get_Send(struct mstp_port_struct_t *mstp_port, unsigned timeout)
|
||||
{ /* milliseconds to wait for a packet */
|
||||
(void)mstp_port;
|
||||
(void)timeout;
|
||||
@@ -84,7 +83,7 @@ uint16_t MSTP_Get_Send(
|
||||
*/
|
||||
void MSTP_Send_Frame(
|
||||
struct mstp_port_struct_t *mstp_port,
|
||||
const uint8_t * buffer,
|
||||
const uint8_t *buffer,
|
||||
uint16_t nbytes)
|
||||
{
|
||||
(void)mstp_port;
|
||||
@@ -92,8 +91,7 @@ void MSTP_Send_Frame(
|
||||
(void)nbytes;
|
||||
}
|
||||
|
||||
uint16_t MSTP_Get_Reply(
|
||||
struct mstp_port_struct_t *mstp_port, unsigned timeout)
|
||||
uint16_t MSTP_Get_Reply(struct mstp_port_struct_t *mstp_port, unsigned timeout)
|
||||
{ /* milliseconds to wait for a packet */
|
||||
(void)mstp_port;
|
||||
(void)timeout;
|
||||
@@ -140,8 +138,8 @@ static int network_init(const char *name, int protocol)
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
static void snap_received_packet(
|
||||
const struct mstp_port_struct_t *mstp_port, int sockfd)
|
||||
static void
|
||||
snap_received_packet(const struct mstp_port_struct_t *mstp_port, int sockfd)
|
||||
{
|
||||
uint16_t mtu_len = 0; /* number of octets of packet saved in file */
|
||||
unsigned i = 0; /* counter */
|
||||
@@ -267,7 +265,8 @@ int main(int argc, char *argv[])
|
||||
MSTP_Port.SilenceTimer = Timer_Silence;
|
||||
MSTP_Port.SilenceTimerReset = Timer_Silence_Reset;
|
||||
MSTP_Init(mstp_port);
|
||||
fprintf(stdout, "mstpcap: Using %s for capture at %ld bps.\n",
|
||||
fprintf(
|
||||
stdout, "mstpcap: Using %s for capture at %ld bps.\n",
|
||||
RS485_Interface(), (long)RS485_Get_Baud_Rate());
|
||||
atexit(cleanup);
|
||||
#if defined(_WIN32)
|
||||
|
||||
+14
-8
@@ -569,12 +569,14 @@ void RS485_Initialize(void)
|
||||
newserial.custom_divisor = round(((float)newserial.baud_base) / 76800);
|
||||
/* we must check that we calculated some sane value;
|
||||
small baud bases yield bad custom divisor values */
|
||||
baud_error = fabs(1 -
|
||||
baud_error = fabs(
|
||||
1 -
|
||||
((float)newserial.baud_base) / ((float)newserial.custom_divisor) /
|
||||
76800);
|
||||
if ((newserial.custom_divisor == 0) || (baud_error > 0.02)) {
|
||||
/* bad divisor */
|
||||
fprintf(stderr, "RS485 bad custom divisor %d, base baud %d\n",
|
||||
fprintf(
|
||||
stderr, "RS485 bad custom divisor %d, base baud %d\n",
|
||||
newserial.custom_divisor, newserial.baud_base);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
@@ -617,19 +619,22 @@ void RS485_Print_Ports(void)
|
||||
while (n--) {
|
||||
if (strcmp(namelist[n]->d_name, "..") &&
|
||||
strcmp(namelist[n]->d_name, ".")) {
|
||||
snprintf(device_dir, sizeof(device_dir), "%s%s/device", sysdir,
|
||||
snprintf(
|
||||
device_dir, sizeof(device_dir), "%s%s/device", sysdir,
|
||||
namelist[n]->d_name);
|
||||
/* Stat the devicedir and handle it if it is a symlink */
|
||||
if (lstat(device_dir, &st) == 0 && S_ISLNK(st.st_mode)) {
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
snprintf(device_dir, sizeof(device_dir),
|
||||
"%s%s/device/driver", sysdir, namelist[n]->d_name);
|
||||
snprintf(
|
||||
device_dir, sizeof(device_dir), "%s%s/device/driver",
|
||||
sysdir, namelist[n]->d_name);
|
||||
if (readlink(device_dir, buffer, sizeof(buffer)) > 0) {
|
||||
valid_port = false;
|
||||
driver_name = basename(buffer);
|
||||
if (strcmp(driver_name, "serial8250") == 0) {
|
||||
/* serial8250-devices must be probed */
|
||||
snprintf(device_dir, sizeof(device_dir), "/dev/%s",
|
||||
snprintf(
|
||||
device_dir, sizeof(device_dir), "/dev/%s",
|
||||
namelist[n]->d_name);
|
||||
fd = open(
|
||||
device_dir, O_RDWR | O_NONBLOCK | O_NOCTTY);
|
||||
@@ -649,8 +654,9 @@ void RS485_Print_Ports(void)
|
||||
}
|
||||
if (valid_port) {
|
||||
/* print full absolute file path */
|
||||
printf("interface {value=/dev/%s}"
|
||||
"{display=MS/TP Capture on /dev/%s}\n",
|
||||
printf(
|
||||
"interface {value=/dev/%s}"
|
||||
"{display=MS/TP Capture on /dev/%s}\n",
|
||||
namelist[n]->d_name, namelist[n]->d_name);
|
||||
}
|
||||
}
|
||||
|
||||
+24
-32
@@ -15,42 +15,34 @@
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
void RS485_Set_Interface(
|
||||
char *ifname);
|
||||
BACNET_STACK_EXPORT
|
||||
const char *RS485_Interface(
|
||||
void);
|
||||
BACNET_STACK_EXPORT
|
||||
void RS485_Set_Interface(char *ifname);
|
||||
BACNET_STACK_EXPORT
|
||||
const char *RS485_Interface(void);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
void RS485_Initialize(
|
||||
void);
|
||||
BACNET_STACK_EXPORT
|
||||
void RS485_Initialize(void);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
void RS485_Send_Frame(
|
||||
struct mstp_port_struct_t *mstp_port, /* port specific data */
|
||||
const uint8_t * buffer, /* frame to send (up to 501 bytes of data) */
|
||||
uint16_t nbytes); /* number of bytes of data (up to 501) */
|
||||
BACNET_STACK_EXPORT
|
||||
void RS485_Send_Frame(
|
||||
struct mstp_port_struct_t *mstp_port, /* port specific data */
|
||||
const uint8_t *buffer, /* frame to send (up to 501 bytes of data) */
|
||||
uint16_t nbytes); /* number of bytes of data (up to 501) */
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
void RS485_Check_UART_Data(
|
||||
struct mstp_port_struct_t *mstp_port); /* port specific data */
|
||||
BACNET_STACK_EXPORT
|
||||
uint32_t RS485_Get_Port_Baud_Rate(
|
||||
struct mstp_port_struct_t *mstp_port);
|
||||
BACNET_STACK_EXPORT
|
||||
uint32_t RS485_Get_Baud_Rate(
|
||||
void);
|
||||
BACNET_STACK_EXPORT
|
||||
bool RS485_Set_Baud_Rate(
|
||||
uint32_t baud);
|
||||
BACNET_STACK_EXPORT
|
||||
void RS485_Check_UART_Data(
|
||||
struct mstp_port_struct_t *mstp_port); /* port specific data */
|
||||
BACNET_STACK_EXPORT
|
||||
uint32_t RS485_Get_Port_Baud_Rate(struct mstp_port_struct_t *mstp_port);
|
||||
BACNET_STACK_EXPORT
|
||||
uint32_t RS485_Get_Baud_Rate(void);
|
||||
BACNET_STACK_EXPORT
|
||||
bool RS485_Set_Baud_Rate(uint32_t baud);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
void RS485_Cleanup(
|
||||
void);
|
||||
BACNET_STACK_EXPORT
|
||||
void RS485_Print_Ports(
|
||||
void);
|
||||
BACNET_STACK_EXPORT
|
||||
void RS485_Cleanup(void);
|
||||
BACNET_STACK_EXPORT
|
||||
void RS485_Print_Ports(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
+10
-11
@@ -1,10 +1,10 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2020 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
*
|
||||
* Copyright (C) 2020 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef BACPORT_H
|
||||
#define BACPORT_H
|
||||
@@ -19,11 +19,10 @@
|
||||
#include "lwip/dhcp.h"
|
||||
#include "lwip/inet.h"
|
||||
|
||||
#define BACNET_OBJECT_TABLE(table_name, _type, _init, _count, \
|
||||
_index_to_instance, _valid_instance, _object_name, \
|
||||
_read_property, _write_property, _RPM_list, \
|
||||
_RR_info, _iterator, _value_list, _COV, \
|
||||
_COV_clear, _intrinsic_reporting) \
|
||||
#define BACNET_OBJECT_TABLE( \
|
||||
table_name, _type, _init, _count, _index_to_instance, _valid_instance, \
|
||||
_object_name, _read_property, _write_property, _RPM_list, _RR_info, \
|
||||
_iterator, _value_list, _COV, _COV_clear, _intrinsic_reporting) \
|
||||
static_assert(false, "Unsupported BACNET_OBJECT_TABLE for this platform")
|
||||
|
||||
#endif
|
||||
|
||||
+9
-9
@@ -153,9 +153,8 @@ static void bip_mac_to_addr(ip4_addr_t *address, const uint8_t *mac)
|
||||
* @param address - IPv4 address from LwIP
|
||||
* @param port - IPv4 UDP port number
|
||||
*/
|
||||
static int bip_decode_bip_address(const BACNET_IP_ADDRESS *baddr,
|
||||
ip_addr_t *address,
|
||||
uint16_t *port)
|
||||
static int bip_decode_bip_address(
|
||||
const BACNET_IP_ADDRESS *baddr, ip_addr_t *address, uint16_t *port)
|
||||
{
|
||||
int len = 0;
|
||||
|
||||
@@ -190,9 +189,8 @@ static void bip_addr_to_mac(uint8_t *mac, const ip4_addr_t *address)
|
||||
* @param address - IPv4 address from LwIP
|
||||
* @param port - IPv4 UDP port number
|
||||
*/
|
||||
static int bip_encode_bip_address(BACNET_IP_ADDRESS *baddr,
|
||||
const ip_addr_t *address,
|
||||
uint16_t port)
|
||||
static int bip_encode_bip_address(
|
||||
BACNET_IP_ADDRESS *baddr, const ip_addr_t *address, uint16_t port)
|
||||
{
|
||||
int len = 0;
|
||||
|
||||
@@ -249,7 +247,8 @@ int bip_send_mpdu(
|
||||
*
|
||||
* @return number of bytes sent
|
||||
*/
|
||||
int bip_send_pdu(BACNET_ADDRESS *dest, /* destination address */
|
||||
int bip_send_pdu(
|
||||
BACNET_ADDRESS *dest, /* destination address */
|
||||
BACNET_NPDU_DATA *npdu_data, /* network information */
|
||||
uint8_t *pdu, /* any data to be sent - may be null */
|
||||
unsigned pdu_len)
|
||||
@@ -265,7 +264,8 @@ int bip_send_pdu(BACNET_ADDRESS *dest, /* destination address */
|
||||
* @param addr [in] UDP source address
|
||||
* @param port [in] UDP port number
|
||||
*/
|
||||
void bip_server_callback(void *arg,
|
||||
void bip_server_callback(
|
||||
void *arg,
|
||||
struct udp_pcb *upcb,
|
||||
struct pbuf *pkt,
|
||||
const ip_addr_t *addr,
|
||||
@@ -275,7 +275,7 @@ void bip_server_callback(void *arg,
|
||||
uint16_t npdu_offset = 0;
|
||||
BACNET_ADDRESS src = { 0 }; /* address where message came from */
|
||||
BACNET_IP_ADDRESS saddr;
|
||||
uint8_t *npdu = (uint8_t *) pkt->payload;
|
||||
uint8_t *npdu = (uint8_t *)pkt->payload;
|
||||
uint16_t npdu_len = pkt->tot_len;
|
||||
|
||||
bip_encode_bip_address(&saddr, addr, port);
|
||||
|
||||
+6
-6
@@ -1,10 +1,10 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2012 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
*
|
||||
* Copyright (C) 2012 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef NET_H
|
||||
#define NET_H
|
||||
|
||||
+12
-8
@@ -49,7 +49,8 @@ void bacnet_init(void)
|
||||
apdu_set_confirmed_handler(
|
||||
SERVICE_CONFIRMED_WRITE_PROPERTY, handler_write_property);
|
||||
/* handle communication so we can shutup when asked */
|
||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
|
||||
apdu_set_confirmed_handler(
|
||||
SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
|
||||
handler_device_communication_control);
|
||||
/* start the cyclic 1 second timer for DCC */
|
||||
mstimer_set(&DCC_Timer, DCC_CYCLE_SECONDS * 1000);
|
||||
@@ -57,14 +58,17 @@ void bacnet_init(void)
|
||||
Send_I_Am(&Handler_Transmit_Buffer[0]);
|
||||
}
|
||||
|
||||
/** Static receive buffer, initialized with zeros by the C Library Startup Code. */
|
||||
/** Static receive buffer, initialized with zeros by the C Library Startup Code.
|
||||
*/
|
||||
|
||||
static uint8_t PDUBuffer[MAX_MPDU + 16 /* Add a little safety margin to the buffer,
|
||||
* so that in the rare case, the message
|
||||
* would be filled up to MAX_MPDU and some
|
||||
* decoding functions would overrun, these
|
||||
* decoding functions will just end up in
|
||||
* a safe field of static zeros. */];
|
||||
static uint8_t PDUBuffer
|
||||
[MAX_MPDU + 16 /* Add a little safety margin to the buffer,
|
||||
* so that in the rare case, the message
|
||||
* would be filled up to MAX_MPDU and some
|
||||
* decoding functions would overrun, these
|
||||
* decoding functions will just end up in
|
||||
* a safe field of static zeros. */
|
||||
];
|
||||
|
||||
void bacnet_task(void)
|
||||
{
|
||||
|
||||
+8
-10
@@ -1,10 +1,10 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
*
|
||||
* Copyright (C) 2010 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
#ifndef BACNET_H
|
||||
#define BACNET_H
|
||||
|
||||
@@ -14,10 +14,8 @@
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
void bacnet_init(
|
||||
void);
|
||||
void bacnet_task(
|
||||
void);
|
||||
void bacnet_init(void);
|
||||
void bacnet_task(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
+41
-24
@@ -37,25 +37,38 @@ static uint8_t Out_Of_Service[MAX_BINARY_OUTPUTS];
|
||||
static uint8_t Polarity[MAX_BINARY_OUTPUTS];
|
||||
|
||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||
static const int Binary_Output_Properties_Required[] = { PROP_OBJECT_IDENTIFIER,
|
||||
PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS,
|
||||
PROP_EVENT_STATE, PROP_OUT_OF_SERVICE, PROP_POLARITY, PROP_PRIORITY_ARRAY,
|
||||
PROP_RELINQUISH_DEFAULT, -1 };
|
||||
static const int Binary_Output_Properties_Required[] = {
|
||||
PROP_OBJECT_IDENTIFIER,
|
||||
PROP_OBJECT_NAME,
|
||||
PROP_OBJECT_TYPE,
|
||||
PROP_PRESENT_VALUE,
|
||||
PROP_STATUS_FLAGS,
|
||||
PROP_EVENT_STATE,
|
||||
PROP_OUT_OF_SERVICE,
|
||||
PROP_POLARITY,
|
||||
PROP_PRIORITY_ARRAY,
|
||||
PROP_RELINQUISH_DEFAULT,
|
||||
-1
|
||||
};
|
||||
|
||||
static const int Binary_Output_Properties_Optional[] = { PROP_ACTIVE_TEXT,
|
||||
PROP_INACTIVE_TEXT, -1 };
|
||||
PROP_INACTIVE_TEXT,
|
||||
-1 };
|
||||
|
||||
static const int Binary_Output_Properties_Proprietary[] = { -1 };
|
||||
|
||||
void Binary_Output_Property_Lists(
|
||||
const int **pRequired, const int **pOptional, const int **pProprietary)
|
||||
{
|
||||
if (pRequired)
|
||||
if (pRequired) {
|
||||
*pRequired = Binary_Output_Properties_Required;
|
||||
if (pOptional)
|
||||
}
|
||||
if (pOptional) {
|
||||
*pOptional = Binary_Output_Properties_Optional;
|
||||
if (pProprietary)
|
||||
}
|
||||
if (pProprietary) {
|
||||
*pProprietary = Binary_Output_Properties_Proprietary;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -63,8 +76,9 @@ void Binary_Output_Property_Lists(
|
||||
/* we simply have 0-n object instances. */
|
||||
bool Binary_Output_Valid_Instance(uint32_t object_instance)
|
||||
{
|
||||
if (object_instance < MAX_BINARY_OUTPUTS)
|
||||
if (object_instance < MAX_BINARY_OUTPUTS) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -86,8 +100,9 @@ unsigned Binary_Output_Instance_To_Index(uint32_t object_instance)
|
||||
{
|
||||
unsigned index = MAX_BINARY_OUTPUTS;
|
||||
|
||||
if (object_instance < MAX_BINARY_OUTPUTS)
|
||||
if (object_instance < MAX_BINARY_OUTPUTS) {
|
||||
index = object_instance;
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
@@ -135,8 +150,8 @@ bool Binary_Output_Present_Value_Set(
|
||||
return status;
|
||||
}
|
||||
|
||||
static void Binary_Output_Polarity_Set(
|
||||
uint32_t instance, BACNET_POLARITY polarity)
|
||||
static void
|
||||
Binary_Output_Polarity_Set(uint32_t instance, BACNET_POLARITY polarity)
|
||||
{
|
||||
if (instance < MAX_BINARY_OUTPUTS) {
|
||||
if (polarity < MAX_POLARITY) {
|
||||
@@ -241,9 +256,10 @@ int Binary_Output_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
|
||||
break;
|
||||
case PROP_PRIORITY_ARRAY:
|
||||
/* Array element zero is the number of elements in the array */
|
||||
if (rpdata->array_index == 0)
|
||||
if (rpdata->array_index == 0) {
|
||||
apdu_len =
|
||||
encode_application_unsigned(&apdu[0], BACNET_MAX_PRIORITY);
|
||||
}
|
||||
/* if no index was specified, then try to encode the entire list */
|
||||
/* into one packet. */
|
||||
else if (rpdata->array_index == BACNET_ARRAY_ALL) {
|
||||
@@ -260,9 +276,9 @@ int Binary_Output_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
|
||||
&apdu[apdu_len], present_value);
|
||||
}
|
||||
/* add it if we have room */
|
||||
if ((apdu_len + len) < MAX_APDU)
|
||||
if ((apdu_len + len) < MAX_APDU) {
|
||||
apdu_len += len;
|
||||
else {
|
||||
} else {
|
||||
rpdata->error_code =
|
||||
ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED;
|
||||
apdu_len = BACNET_STATUS_ABORT;
|
||||
@@ -348,8 +364,8 @@ bool Binary_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
||||
}
|
||||
switch (wp_data->object_property) {
|
||||
case PROP_PRESENT_VALUE:
|
||||
status = write_property_type_valid(wp_data, &value,
|
||||
BACNET_APPLICATION_TAG_ENUMERATED);
|
||||
status = write_property_type_valid(
|
||||
wp_data, &value, BACNET_APPLICATION_TAG_ENUMERATED);
|
||||
if (status) {
|
||||
priority = wp_data->priority;
|
||||
/* Command priority 6 is reserved for use by Minimum On/Off
|
||||
@@ -375,8 +391,8 @@ bool Binary_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
||||
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
}
|
||||
} else {
|
||||
status = write_property_type_valid(wp_data, &value,
|
||||
BACNET_APPLICATION_TAG_NULL);
|
||||
status = write_property_type_valid(
|
||||
wp_data, &value, BACNET_APPLICATION_TAG_NULL);
|
||||
if (status) {
|
||||
level = BINARY_NULL;
|
||||
priority = wp_data->priority;
|
||||
@@ -400,19 +416,20 @@ bool Binary_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
||||
}
|
||||
break;
|
||||
case PROP_OUT_OF_SERVICE:
|
||||
status = write_property_type_valid(wp_data, &value,
|
||||
BACNET_APPLICATION_TAG_BOOLEAN);
|
||||
status = write_property_type_valid(
|
||||
wp_data, &value, BACNET_APPLICATION_TAG_BOOLEAN);
|
||||
if (status) {
|
||||
Binary_Output_Out_Of_Service_Set(
|
||||
wp_data->object_instance, value.type.Boolean);
|
||||
}
|
||||
break;
|
||||
case PROP_POLARITY:
|
||||
status = write_property_type_valid(wp_data, &value,
|
||||
BACNET_APPLICATION_TAG_ENUMERATED);
|
||||
status = write_property_type_valid(
|
||||
wp_data, &value, BACNET_APPLICATION_TAG_ENUMERATED);
|
||||
if (status) {
|
||||
if (value.type.Enumerated < MAX_POLARITY) {
|
||||
Binary_Output_Polarity_Set(wp_data->object_instance,
|
||||
Binary_Output_Polarity_Set(
|
||||
wp_data->object_instance,
|
||||
(BACNET_POLARITY)value.type.Enumerated);
|
||||
} else {
|
||||
status = false;
|
||||
|
||||
+73
-53
@@ -45,16 +45,18 @@ static struct my_object_functions {
|
||||
read_property_function Object_Read_Property;
|
||||
write_property_function Object_Write_Property;
|
||||
rpm_property_lists_function Object_RPM_List;
|
||||
} Object_Table[] = { { OBJECT_DEVICE, NULL, /* don't init - recursive! */
|
||||
Device_Count, Device_Index_To_Instance,
|
||||
Device_Valid_Object_Instance_Number, Device_Name,
|
||||
Device_Read_Property_Local,
|
||||
Device_Write_Property_Local, Device_Property_Lists },
|
||||
} Object_Table[] = {
|
||||
{ OBJECT_DEVICE, NULL, /* don't init - recursive! */
|
||||
Device_Count, Device_Index_To_Instance,
|
||||
Device_Valid_Object_Instance_Number, Device_Name,
|
||||
Device_Read_Property_Local, Device_Write_Property_Local,
|
||||
Device_Property_Lists },
|
||||
{ OBJECT_BINARY_OUTPUT, Binary_Output_Init, Binary_Output_Count,
|
||||
Binary_Output_Index_To_Instance, Binary_Output_Valid_Instance,
|
||||
Binary_Output_Name, Binary_Output_Read_Property,
|
||||
Binary_Output_Write_Property, Binary_Output_Property_Lists },
|
||||
{ MAX_BACNET_OBJECT_TYPE, NULL, NULL, NULL, NULL, NULL, NULL, NULL } };
|
||||
Binary_Output_Index_To_Instance, Binary_Output_Valid_Instance,
|
||||
Binary_Output_Name, Binary_Output_Read_Property,
|
||||
Binary_Output_Write_Property, Binary_Output_Property_Lists },
|
||||
{ MAX_BACNET_OBJECT_TYPE, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
/* note: you really only need to define variables for
|
||||
properties that are writable or that may change.
|
||||
@@ -73,23 +75,38 @@ static char Description[MAX_DEV_DESC_LEN + 1] = "Renesas Rulz!";
|
||||
static uint32_t Database_Revision = 0;
|
||||
|
||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||
static const int Device_Properties_Required[] = { PROP_OBJECT_IDENTIFIER,
|
||||
PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_SYSTEM_STATUS, PROP_VENDOR_NAME,
|
||||
PROP_VENDOR_IDENTIFIER, PROP_MODEL_NAME, PROP_FIRMWARE_REVISION,
|
||||
PROP_APPLICATION_SOFTWARE_VERSION, PROP_PROTOCOL_VERSION,
|
||||
PROP_PROTOCOL_REVISION, PROP_PROTOCOL_SERVICES_SUPPORTED,
|
||||
PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED, PROP_OBJECT_LIST,
|
||||
PROP_MAX_APDU_LENGTH_ACCEPTED, PROP_SEGMENTATION_SUPPORTED,
|
||||
PROP_APDU_TIMEOUT, PROP_NUMBER_OF_APDU_RETRIES, PROP_MAX_MASTER,
|
||||
PROP_MAX_INFO_FRAMES, PROP_DEVICE_ADDRESS_BINDING, PROP_DATABASE_REVISION,
|
||||
-1 };
|
||||
static const int Device_Properties_Required[] = {
|
||||
PROP_OBJECT_IDENTIFIER,
|
||||
PROP_OBJECT_NAME,
|
||||
PROP_OBJECT_TYPE,
|
||||
PROP_SYSTEM_STATUS,
|
||||
PROP_VENDOR_NAME,
|
||||
PROP_VENDOR_IDENTIFIER,
|
||||
PROP_MODEL_NAME,
|
||||
PROP_FIRMWARE_REVISION,
|
||||
PROP_APPLICATION_SOFTWARE_VERSION,
|
||||
PROP_PROTOCOL_VERSION,
|
||||
PROP_PROTOCOL_REVISION,
|
||||
PROP_PROTOCOL_SERVICES_SUPPORTED,
|
||||
PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED,
|
||||
PROP_OBJECT_LIST,
|
||||
PROP_MAX_APDU_LENGTH_ACCEPTED,
|
||||
PROP_SEGMENTATION_SUPPORTED,
|
||||
PROP_APDU_TIMEOUT,
|
||||
PROP_NUMBER_OF_APDU_RETRIES,
|
||||
PROP_MAX_MASTER,
|
||||
PROP_MAX_INFO_FRAMES,
|
||||
PROP_DEVICE_ADDRESS_BINDING,
|
||||
PROP_DATABASE_REVISION,
|
||||
-1
|
||||
};
|
||||
|
||||
static const int Device_Properties_Optional[] = { PROP_DESCRIPTION, -1 };
|
||||
|
||||
static const int Device_Properties_Proprietary[] = { -1 };
|
||||
|
||||
static struct my_object_functions *Device_Objects_Find_Functions(
|
||||
BACNET_OBJECT_TYPE Object_Type)
|
||||
static struct my_object_functions *
|
||||
Device_Objects_Find_Functions(BACNET_OBJECT_TYPE Object_Type)
|
||||
{
|
||||
struct my_object_functions *pObject = NULL;
|
||||
|
||||
@@ -148,14 +165,10 @@ static int Read_Property_Common(
|
||||
#if (BACNET_PROTOCOL_REVISION >= 14)
|
||||
case PROP_PROPERTY_LIST:
|
||||
Device_Objects_Property_List(
|
||||
rpdata->object_type,
|
||||
rpdata->object_instance,
|
||||
&property_list);
|
||||
rpdata->object_type, rpdata->object_instance, &property_list);
|
||||
apdu_len = property_list_encode(
|
||||
rpdata,
|
||||
property_list.Required.pList,
|
||||
property_list.Optional.pList,
|
||||
property_list.Proprietary.pList);
|
||||
rpdata, property_list.Required.pList,
|
||||
property_list.Optional.pList, property_list.Proprietary.pList);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
@@ -193,7 +206,8 @@ static unsigned property_list_count(const int *pList)
|
||||
* list, separately, the Required, Optional, and Proprietary object
|
||||
* properties with their counts.
|
||||
*/
|
||||
void Device_Objects_Property_List(BACNET_OBJECT_TYPE object_type,
|
||||
void Device_Objects_Property_List(
|
||||
BACNET_OBJECT_TYPE object_type,
|
||||
uint32_t object_instance,
|
||||
struct special_property_list_t *pPropertyList)
|
||||
{
|
||||
@@ -211,8 +225,9 @@ void Device_Objects_Property_List(BACNET_OBJECT_TYPE object_type,
|
||||
|
||||
pObject = Device_Objects_Find_Functions(object_type);
|
||||
if ((pObject != NULL) && (pObject->Object_RPM_List != NULL)) {
|
||||
pObject->Object_RPM_List(&pPropertyList->Required.pList,
|
||||
&pPropertyList->Optional.pList, &pPropertyList->Proprietary.pList);
|
||||
pObject->Object_RPM_List(
|
||||
&pPropertyList->Required.pList, &pPropertyList->Optional.pList,
|
||||
&pPropertyList->Proprietary.pList);
|
||||
}
|
||||
|
||||
/* Fetch the counts if available otherwise zero them */
|
||||
@@ -234,12 +249,15 @@ void Device_Objects_Property_List(BACNET_OBJECT_TYPE object_type,
|
||||
void Device_Property_Lists(
|
||||
const int **pRequired, const int **pOptional, const int **pProprietary)
|
||||
{
|
||||
if (pRequired)
|
||||
if (pRequired) {
|
||||
*pRequired = Device_Properties_Required;
|
||||
if (pOptional)
|
||||
}
|
||||
if (pOptional) {
|
||||
*pOptional = Device_Properties_Optional;
|
||||
if (pProprietary)
|
||||
}
|
||||
if (pProprietary) {
|
||||
*pProprietary = Device_Properties_Proprietary;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -364,8 +382,9 @@ bool Device_Set_Object_Instance_Number(uint32_t object_id)
|
||||
|
||||
if (object_id <= BACNET_MAX_INSTANCE) {
|
||||
Object_Instance_Number = object_id;
|
||||
} else
|
||||
} else {
|
||||
status = false;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -584,7 +603,8 @@ int Device_Object_List_Element_Encode(
|
||||
* Object.
|
||||
* @return True on success or else False if not found.
|
||||
*/
|
||||
bool Device_Valid_Object_Name(const char *object_name,
|
||||
bool Device_Valid_Object_Name(
|
||||
const char *object_name,
|
||||
BACNET_OBJECT_TYPE *object_type,
|
||||
uint32_t *object_instance)
|
||||
{
|
||||
@@ -617,8 +637,8 @@ bool Device_Valid_Object_Name(const char *object_name,
|
||||
}
|
||||
|
||||
/* returns the name or NULL if not found */
|
||||
char *Device_Valid_Object_Id(
|
||||
BACNET_OBJECT_TYPE object_type, uint32_t object_instance)
|
||||
char *
|
||||
Device_Valid_Object_Id(BACNET_OBJECT_TYPE object_type, uint32_t object_instance)
|
||||
{
|
||||
char *name = NULL; /* return value */
|
||||
struct my_object_functions *pObject = NULL;
|
||||
@@ -701,7 +721,8 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
|
||||
bitstring_init(&bit_string);
|
||||
for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++) {
|
||||
/* automatic lookup based on handlers set */
|
||||
bitstring_set_bit(&bit_string, (uint8_t)i,
|
||||
bitstring_set_bit(
|
||||
&bit_string, (uint8_t)i,
|
||||
apdu_service_supported((BACNET_SERVICES_SUPPORTED)i));
|
||||
}
|
||||
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
|
||||
@@ -728,10 +749,9 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
|
||||
break;
|
||||
case PROP_OBJECT_LIST:
|
||||
count = Device_Object_List_Count();
|
||||
apdu_len = bacnet_array_encode(rpdata->object_instance,
|
||||
rpdata->array_index,
|
||||
Device_Object_List_Element_Encode,
|
||||
count, apdu, apdu_max);
|
||||
apdu_len = bacnet_array_encode(
|
||||
rpdata->object_instance, rpdata->array_index,
|
||||
Device_Object_List_Element_Encode, count, apdu, apdu_max);
|
||||
if (apdu_len == BACNET_STATUS_ABORT) {
|
||||
rpdata->error_code =
|
||||
ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED;
|
||||
@@ -837,8 +857,8 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
||||
}
|
||||
switch (wp_data->object_property) {
|
||||
case PROP_OBJECT_IDENTIFIER:
|
||||
status = write_property_type_valid(wp_data, &value,
|
||||
BACNET_APPLICATION_TAG_OBJECT_ID);
|
||||
status = write_property_type_valid(
|
||||
wp_data, &value, BACNET_APPLICATION_TAG_OBJECT_ID);
|
||||
if (status) {
|
||||
if ((value.type.Object_Id.type == OBJECT_DEVICE) &&
|
||||
(Device_Set_Object_Instance_Number(
|
||||
@@ -853,8 +873,8 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
||||
}
|
||||
break;
|
||||
case PROP_SYSTEM_STATUS:
|
||||
status = write_property_type_valid(wp_data, &value,
|
||||
BACNET_APPLICATION_TAG_ENUMERATED);
|
||||
status = write_property_type_valid(
|
||||
wp_data, &value, BACNET_APPLICATION_TAG_ENUMERATED);
|
||||
if (status) {
|
||||
temp = Device_Set_System_Status(
|
||||
(BACNET_DEVICE_STATUS)value.type.Enumerated, false);
|
||||
@@ -871,8 +891,8 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
||||
}
|
||||
break;
|
||||
case PROP_OBJECT_NAME:
|
||||
status = write_property_string_valid(&wp_data, &value,
|
||||
MAX_DEV_NAME_LEN);
|
||||
status =
|
||||
write_property_string_valid(&wp_data, &value, MAX_DEV_NAME_LEN);
|
||||
if (status) {
|
||||
Device_Set_Object_Name(
|
||||
characterstring_value(&value.type.Character_String),
|
||||
@@ -880,8 +900,8 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
||||
}
|
||||
break;
|
||||
case PROP_LOCATION:
|
||||
status = write_property_empty_string_valid(&wp_data, &value,
|
||||
MAX_DEV_LOC_LEN);
|
||||
status = write_property_empty_string_valid(
|
||||
&wp_data, &value, MAX_DEV_LOC_LEN);
|
||||
if (status) {
|
||||
Device_Set_Location(
|
||||
characterstring_value(&value.type.Character_String),
|
||||
@@ -890,8 +910,8 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
||||
break;
|
||||
|
||||
case PROP_DESCRIPTION:
|
||||
status = write_property_empty_string_valid(&wp_data, &value,
|
||||
MAX_DEV_DESC_LEN);
|
||||
status = write_property_empty_string_valid(
|
||||
&wp_data, &value, MAX_DEV_DESC_LEN);
|
||||
if (status) {
|
||||
Device_Set_Description(
|
||||
characterstring_value(&value.type.Character_String),
|
||||
|
||||
+16
-10
@@ -16,8 +16,8 @@
|
||||
for BACnet/Ethernet. */
|
||||
|
||||
/* commonly used comparison address for ethernet */
|
||||
static uint8_t Ethernet_Broadcast[MAX_MAC_LEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF };
|
||||
static uint8_t Ethernet_Broadcast[MAX_MAC_LEN] = { 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF };
|
||||
|
||||
/* IEEE maintains list of 48-bit MAC "addresses" AKA EUI-48 identifiers.
|
||||
An EUI-48 is structured into an initial 3-octet OUI
|
||||
@@ -26,8 +26,8 @@ static uint8_t Ethernet_Broadcast[MAX_MAC_LEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
/* see [RFC5342] for current information and registration procedures. */
|
||||
/* The OUI 00-00-5E has been allocated to IANA. */
|
||||
/* my local device data - MAC address */
|
||||
static uint8_t Ethernet_MAC_Address[MAX_MAC_LEN] = { 0x00, 0x00, 0x5E, 0x00,
|
||||
0x00, 0x01 };
|
||||
static uint8_t Ethernet_MAC_Address[MAX_MAC_LEN] = { 0x00, 0x00, 0x5E,
|
||||
0x00, 0x00, 0x01 };
|
||||
|
||||
/* status of the link */
|
||||
static int32_t Ethernet_Status = R_ETHER_ERROR;
|
||||
@@ -69,7 +69,8 @@ int ethernet_send(uint8_t *mtu, int mtu_len)
|
||||
|
||||
/* function to send a packet out the 802.2 socket */
|
||||
/* returns number of bytes sent on success, negative on failure */
|
||||
int ethernet_send_pdu(BACNET_ADDRESS *dest, /* destination address */
|
||||
int ethernet_send_pdu(
|
||||
BACNET_ADDRESS *dest, /* destination address */
|
||||
BACNET_NPDU_DATA *npdu_data, /* network information */
|
||||
uint8_t *pdu, /* any data to be sent - may be null */
|
||||
unsigned pdu_len)
|
||||
@@ -129,7 +130,8 @@ int ethernet_send_pdu(BACNET_ADDRESS *dest, /* destination address */
|
||||
|
||||
/* receives an 802.2 framed packet */
|
||||
/* returns the number of octets in the PDU, or zero on failure */
|
||||
uint16_t ethernet_receive(BACNET_ADDRESS *src, /* source address */
|
||||
uint16_t ethernet_receive(
|
||||
BACNET_ADDRESS *src, /* source address */
|
||||
uint8_t *pdu, /* PDU data */
|
||||
uint16_t max_pdu, /* amount of space available in the PDU */
|
||||
unsigned timeout)
|
||||
@@ -139,13 +141,15 @@ uint16_t ethernet_receive(BACNET_ADDRESS *src, /* source address */
|
||||
uint16_t pdu_len = 0; /* return value */
|
||||
|
||||
/* Make sure the socket is open */
|
||||
if (!ethernet_valid())
|
||||
if (!ethernet_valid()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
received_bytes = R_Ether_Read(0, (void *)buf);
|
||||
|
||||
if (received_bytes == 0)
|
||||
if (received_bytes == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* the signature of an 802.2 BACnet packet */
|
||||
if ((buf[14] != 0x82) && (buf[15] != 0x82)) {
|
||||
@@ -165,11 +169,13 @@ uint16_t ethernet_receive(BACNET_ADDRESS *src, /* source address */
|
||||
(void)decode_unsigned16(&buf[12], &pdu_len);
|
||||
pdu_len -= 3 /* DSAP, SSAP, LLC Control */;
|
||||
/* copy the buffer into the PDU */
|
||||
if (pdu_len < max_pdu)
|
||||
if (pdu_len < max_pdu) {
|
||||
memmove(&pdu[0], &buf[17], pdu_len);
|
||||
}
|
||||
/* ignore packets that are too large */
|
||||
else
|
||||
else {
|
||||
pdu_len = 0;
|
||||
}
|
||||
|
||||
return pdu_len;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2011 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
*
|
||||
* Copyright (C) 2011 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
#ifndef HARDWARE_H
|
||||
#define HARDWARE_H
|
||||
|
||||
|
||||
+14
-24
@@ -1,10 +1,10 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
*
|
||||
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
#ifndef LED_H
|
||||
#define LED_H
|
||||
|
||||
@@ -15,24 +15,14 @@
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
void led_on(
|
||||
uint8_t index);
|
||||
void led_on_interval(
|
||||
uint8_t index,
|
||||
uint16_t interval_ms);
|
||||
void led_off(
|
||||
uint8_t index);
|
||||
void led_off_delay(
|
||||
uint8_t index,
|
||||
uint32_t delay_ms);
|
||||
void led_toggle(
|
||||
uint8_t index);
|
||||
bool led_state(
|
||||
uint8_t index);
|
||||
void led_task(
|
||||
void);
|
||||
void led_init(
|
||||
void);
|
||||
void led_on(uint8_t index);
|
||||
void led_on_interval(uint8_t index, uint16_t interval_ms);
|
||||
void led_off(uint8_t index);
|
||||
void led_off_delay(uint8_t index, uint32_t delay_ms);
|
||||
void led_toggle(uint8_t index);
|
||||
bool led_state(uint8_t index);
|
||||
void led_task(void);
|
||||
void led_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
+18
-20
@@ -1,10 +1,10 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
*
|
||||
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef BACPORT_H
|
||||
#define BACPORT_H
|
||||
@@ -15,10 +15,10 @@
|
||||
#define STRICT 1
|
||||
/* Windows XP minimum */
|
||||
#if (_WIN32_WINNT < _WIN32_WINNT_WINXP)
|
||||
#undef _WIN32_WINNT
|
||||
#define _WIN32_WINNT _WIN32_WINNT_WINXP
|
||||
#undef NTDDI_VERSION
|
||||
#define NTDDI_VERSION NTDDI_WINXP
|
||||
#undef _WIN32_WINNT
|
||||
#define _WIN32_WINNT _WIN32_WINNT_WINXP
|
||||
#undef NTDDI_VERSION
|
||||
#define NTDDI_VERSION NTDDI_WINXP
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
@@ -38,10 +38,10 @@
|
||||
#ifdef __MINGW32__
|
||||
#include <ws2spi.h>
|
||||
#else
|
||||
#pragma warning( push )
|
||||
#pragma warning(disable: 4101 4191)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4101 4191)
|
||||
#include <wspiapi.h>
|
||||
#pragma warning( pop )
|
||||
#pragma warning(pop)
|
||||
/* add winmm.lib to our build */
|
||||
#pragma comment(lib, "winmm.lib")
|
||||
#endif
|
||||
@@ -60,14 +60,12 @@
|
||||
#endif
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
extern int bip_get_local_netmask(
|
||||
struct in_addr *netmask);
|
||||
extern int bip_get_local_netmask(struct in_addr *netmask);
|
||||
|
||||
#define BACNET_OBJECT_TABLE(table_name, _type, _init, _count, \
|
||||
_index_to_instance, _valid_instance, _object_name, \
|
||||
_read_property, _write_property, _RPM_list, \
|
||||
_RR_info, _iterator, _value_list, _COV, \
|
||||
_COV_clear, _intrinsic_reporting) \
|
||||
#define BACNET_OBJECT_TABLE( \
|
||||
table_name, _type, _init, _count, _index_to_instance, _valid_instance, \
|
||||
_object_name, _read_property, _write_property, _RPM_list, _RR_info, \
|
||||
_iterator, _value_list, _COV, _COV_clear, _intrinsic_reporting) \
|
||||
static_assert(false, "Unsupported BACNET_OBJECT_TABLE for this platform")
|
||||
|
||||
#endif
|
||||
|
||||
+36
-25
@@ -44,13 +44,15 @@ static bool BIP_Debug;
|
||||
* @param str - debug info string
|
||||
* @param addr - IPv4 address
|
||||
*/
|
||||
static void debug_print_ipv4(const char *str,
|
||||
static void debug_print_ipv4(
|
||||
const char *str,
|
||||
const struct in_addr *addr,
|
||||
const unsigned int port,
|
||||
const unsigned int count)
|
||||
{
|
||||
if (BIP_Debug) {
|
||||
fprintf(stderr, "BIP: %s %s:%hu (%u bytes)\n", str, inet_ntoa(*addr),
|
||||
fprintf(
|
||||
stderr, "BIP: %s %s:%hu (%u bytes)\n", str, inet_ntoa(*addr),
|
||||
ntohs(port), count);
|
||||
fflush(stderr);
|
||||
}
|
||||
@@ -222,7 +224,8 @@ static char *winsock_error_code_text(int code)
|
||||
static void print_last_error(const char *info)
|
||||
{
|
||||
int Code = WSAGetLastError();
|
||||
fprintf(stderr, "BIP: %s [error code %i] %s\n", info, Code,
|
||||
fprintf(
|
||||
stderr, "BIP: %s [error code %i] %s\n", info, Code,
|
||||
winsock_error_code_text(Code));
|
||||
fflush(stderr);
|
||||
}
|
||||
@@ -433,8 +436,9 @@ int bip_send_mpdu(
|
||||
/* Send the packet */
|
||||
debug_print_ipv4(
|
||||
"Sending MPDU->", &bip_dest.sin_addr, bip_dest.sin_port, mtu_len);
|
||||
rv = sendto(BIP_Socket, (const char *)mtu, mtu_len, 0,
|
||||
(struct sockaddr *)&bip_dest, sizeof(struct sockaddr));
|
||||
rv = sendto(
|
||||
BIP_Socket, (const char *)mtu, mtu_len, 0, (struct sockaddr *)&bip_dest,
|
||||
sizeof(struct sockaddr));
|
||||
if (rv == SOCKET_ERROR) {
|
||||
print_last_error("sendto");
|
||||
}
|
||||
@@ -490,10 +494,11 @@ uint16_t bip_receive(
|
||||
|
||||
/* see if there is a packet for us */
|
||||
if (select(max + 1, &read_fds, NULL, NULL, &select_timeout) > 0) {
|
||||
socket = FD_ISSET(BIP_Socket, &read_fds) ? BIP_Socket :
|
||||
BIP_Broadcast_Socket;
|
||||
received_bytes = recvfrom(socket, (char *)&npdu[0], max_npdu, 0,
|
||||
(struct sockaddr *)&sin, &sin_len);
|
||||
socket =
|
||||
FD_ISSET(BIP_Socket, &read_fds) ? BIP_Socket : BIP_Broadcast_Socket;
|
||||
received_bytes = recvfrom(
|
||||
socket, (char *)&npdu[0], max_npdu, 0, (struct sockaddr *)&sin,
|
||||
&sin_len);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
@@ -530,9 +535,9 @@ uint16_t bip_receive(
|
||||
debug_print_ipv4(
|
||||
"Received MPDU->", &sin.sin_addr, sin.sin_port, received_bytes);
|
||||
/* pass the packet into the BBMD handler */
|
||||
offset = socket == BIP_Socket ?
|
||||
bvlc_handler(&addr, src, npdu, received_bytes) :
|
||||
bvlc_broadcast_handler(&addr, src, npdu, received_bytes);
|
||||
offset = socket == BIP_Socket
|
||||
? bvlc_handler(&addr, src, npdu, received_bytes)
|
||||
: bvlc_broadcast_handler(&addr, src, npdu, received_bytes);
|
||||
if (offset > 0) {
|
||||
npdu_len = received_bytes - offset;
|
||||
if (npdu_len <= max_npdu) {
|
||||
@@ -560,7 +565,8 @@ uint16_t bip_receive(
|
||||
* @return Upon successful completion, returns the number of bytes sent.
|
||||
* Otherwise, -1 shall be returned and errno set to indicate the error.
|
||||
*/
|
||||
int bip_send_pdu(BACNET_ADDRESS *dest,
|
||||
int bip_send_pdu(
|
||||
BACNET_ADDRESS *dest,
|
||||
BACNET_NPDU_DATA *npdu_data,
|
||||
uint8_t *pdu,
|
||||
unsigned pdu_len)
|
||||
@@ -612,7 +618,8 @@ static long gethostaddr(void)
|
||||
exit(1);
|
||||
}
|
||||
if (BIP_Debug) {
|
||||
fprintf(stderr, "BIP: host %s at %u.%u.%u.%u\n", host_name,
|
||||
fprintf(
|
||||
stderr, "BIP: host %s at %u.%u.%u.%u\n", host_name,
|
||||
(unsigned)((uint8_t *)host_ent->h_addr)[0],
|
||||
(unsigned)((uint8_t *)host_ent->h_addr)[1],
|
||||
(unsigned)((uint8_t *)host_ent->h_addr)[2],
|
||||
@@ -685,8 +692,7 @@ int bip_get_local_netmask(struct in_addr *netmask)
|
||||
* @param baddr The broadcast socket binding address, in host order.
|
||||
* @return 0 on success
|
||||
*/
|
||||
int bip_set_broadcast_binding(
|
||||
const char *ip4_broadcast)
|
||||
int bip_set_broadcast_binding(const char *ip4_broadcast)
|
||||
{
|
||||
BIP_Broadcast_Binding_Address.s_addr = inet_addr(ip4_broadcast);
|
||||
BIP_Broadcast_Binding_Address_Override = true;
|
||||
@@ -699,20 +705,21 @@ static void set_broadcast_address(uint32_t net_address)
|
||||
#ifdef BACNET_IP_BROADCAST_USE_CLASSADDR
|
||||
long broadcast_address = 0;
|
||||
|
||||
if (IN_CLASSA(ntohl(net_address)))
|
||||
if (IN_CLASSA(ntohl(net_address))) {
|
||||
broadcast_address =
|
||||
(ntohl(net_address) & ~IN_CLASSA_HOST) | IN_CLASSA_HOST;
|
||||
else if (IN_CLASSB(ntohl(net_address)))
|
||||
} else if (IN_CLASSB(ntohl(net_address))) {
|
||||
broadcast_address =
|
||||
(ntohl(net_address) & ~IN_CLASSB_HOST) | IN_CLASSB_HOST;
|
||||
else if (IN_CLASSC(ntohl(net_address)))
|
||||
} else if (IN_CLASSC(ntohl(net_address))) {
|
||||
broadcast_address =
|
||||
(ntohl(net_address) & ~IN_CLASSC_HOST) | IN_CLASSC_HOST;
|
||||
else if (IN_CLASSD(ntohl(net_address)))
|
||||
} else if (IN_CLASSD(ntohl(net_address))) {
|
||||
broadcast_address =
|
||||
(ntohl(net_address) & ~IN_CLASSD_HOST) | IN_CLASSD_HOST;
|
||||
else
|
||||
} else {
|
||||
broadcast_address = INADDR_BROADCAST;
|
||||
}
|
||||
BIP_Broadcast_Addr.s_addr = htonl(broadcast_address);
|
||||
#else
|
||||
/* these are network byte order variables */
|
||||
@@ -830,9 +837,11 @@ bool bip_init(char *ifname)
|
||||
}
|
||||
if (BIP_Debug) {
|
||||
fprintf(stderr, "BIP: Address: %s\n", inet_ntoa(BIP_Address));
|
||||
fprintf(stderr, "BIP: Broadcast Address: %s\n",
|
||||
fprintf(
|
||||
stderr, "BIP: Broadcast Address: %s\n",
|
||||
inet_ntoa(BIP_Broadcast_Addr));
|
||||
fprintf(stderr, "BIP: UDP Port: 0x%04X [%hu]\n", ntohs(BIP_Port),
|
||||
fprintf(
|
||||
stderr, "BIP: UDP Port: 0x%04X [%hu]\n", ntohs(BIP_Port),
|
||||
ntohs(BIP_Port));
|
||||
fflush(stderr);
|
||||
}
|
||||
@@ -842,7 +851,8 @@ bool bip_init(char *ifname)
|
||||
memset(&(sin.sin_zero), '\0', sizeof(sin.sin_zero));
|
||||
sin.sin_addr.s_addr = BIP_Address.s_addr;
|
||||
if (BIP_Debug) {
|
||||
fprintf(stderr, "BIP: bind %s:%hu\n", inet_ntoa(sin.sin_addr),
|
||||
fprintf(
|
||||
stderr, "BIP: bind %s:%hu\n", inet_ntoa(sin.sin_addr),
|
||||
ntohs(sin.sin_port));
|
||||
fflush(stderr);
|
||||
}
|
||||
@@ -863,7 +873,8 @@ bool bip_init(char *ifname)
|
||||
#endif
|
||||
}
|
||||
if (BIP_Debug) {
|
||||
fprintf(stderr, "BIP: broadcast bind %s:%hu\n", inet_ntoa(sin.sin_addr),
|
||||
fprintf(
|
||||
stderr, "BIP: broadcast bind %s:%hu\n", inet_ntoa(sin.sin_addr),
|
||||
ntohs(sin.sin_port));
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
+2
-1
@@ -348,7 +348,8 @@ bool bip6_get_broadcast_addr(BACNET_IP6_ADDRESS *addr)
|
||||
* @return Upon successful completion, returns the number of bytes sent.
|
||||
* Otherwise, -1 shall be returned and errno set to indicate the error.
|
||||
*/
|
||||
int bip6_send_mpdu(const BACNET_IP6_ADDRESS *dest, const uint8_t *mtu, uint16_t mtu_len)
|
||||
int bip6_send_mpdu(
|
||||
const BACNET_IP6_ADDRESS *dest, const uint8_t *mtu, uint16_t mtu_len)
|
||||
{
|
||||
struct sockaddr_in6 bvlc_dest = { 0 };
|
||||
uint16_t addr16[8];
|
||||
|
||||
@@ -118,7 +118,8 @@ void datetime_timesync(BACNET_DATE *bdate, BACNET_TIME *btime, bool utc)
|
||||
* @param true if DST is enabled and active
|
||||
* @return true if local time was retrieved
|
||||
*/
|
||||
bool datetime_local(BACNET_DATE *bdate,
|
||||
bool datetime_local(
|
||||
BACNET_DATE *bdate,
|
||||
BACNET_TIME *btime,
|
||||
int16_t *utc_offset_minutes,
|
||||
bool *dst_active)
|
||||
@@ -152,15 +153,17 @@ bool datetime_local(BACNET_DATE *bdate,
|
||||
* int tm_yday Day of year [0,365].
|
||||
* int tm_isdst Daylight Savings flag.
|
||||
*/
|
||||
datetime_set_date(bdate, (uint16_t)tblock->tm_year + 1900,
|
||||
datetime_set_date(
|
||||
bdate, (uint16_t)tblock->tm_year + 1900,
|
||||
(uint8_t)tblock->tm_mon + 1, (uint8_t)tblock->tm_mday);
|
||||
#if !defined(_MSC_VER)
|
||||
datetime_set_time(btime, (uint8_t)tblock->tm_hour,
|
||||
(uint8_t)tblock->tm_min, (uint8_t)tblock->tm_sec,
|
||||
(uint8_t)(tv.tv_usec / 10000));
|
||||
datetime_set_time(
|
||||
btime, (uint8_t)tblock->tm_hour, (uint8_t)tblock->tm_min,
|
||||
(uint8_t)tblock->tm_sec, (uint8_t)(tv.tv_usec / 10000));
|
||||
#else
|
||||
datetime_set_time(btime, (uint8_t)tblock->tm_hour,
|
||||
(uint8_t)tblock->tm_min, (uint8_t)tblock->tm_sec, 0);
|
||||
datetime_set_time(
|
||||
btime, (uint8_t)tblock->tm_hour, (uint8_t)tblock->tm_min,
|
||||
(uint8_t)tblock->tm_sec, 0);
|
||||
#endif
|
||||
if (dst_active) {
|
||||
/* The value of tm_isdst is:
|
||||
|
||||
+49
-37
@@ -93,7 +93,8 @@ void dlmstp_cleanup(void)
|
||||
}
|
||||
|
||||
/* returns number of bytes sent on success, zero on failure */
|
||||
int dlmstp_send_pdu(BACNET_ADDRESS *dest, /* destination address */
|
||||
int dlmstp_send_pdu(
|
||||
BACNET_ADDRESS *dest, /* destination address */
|
||||
BACNET_NPDU_DATA *npdu_data, /* network information */
|
||||
uint8_t *pdu, /* any data to be sent - may be null */
|
||||
unsigned pdu_len)
|
||||
@@ -120,7 +121,8 @@ int dlmstp_send_pdu(BACNET_ADDRESS *dest, /* destination address */
|
||||
return bytes_sent;
|
||||
}
|
||||
|
||||
uint16_t dlmstp_receive(BACNET_ADDRESS *src, /* source address */
|
||||
uint16_t dlmstp_receive(
|
||||
BACNET_ADDRESS *src, /* source address */
|
||||
uint8_t *pdu, /* PDU data */
|
||||
uint16_t max_pdu, /* amount of space available in the PDU */
|
||||
unsigned timeout)
|
||||
@@ -137,7 +139,8 @@ uint16_t dlmstp_receive(BACNET_ADDRESS *src, /* source address */
|
||||
if (Receive_Packet.pdu_len) {
|
||||
MSTP_Packets++;
|
||||
if (src) {
|
||||
memmove(src, &Receive_Packet.address,
|
||||
memmove(
|
||||
src, &Receive_Packet.address,
|
||||
sizeof(Receive_Packet.address));
|
||||
}
|
||||
if (pdu) {
|
||||
@@ -198,8 +201,9 @@ static void dlmstp_master_fsm_task(void *pArg)
|
||||
dwMilliseconds = 0;
|
||||
break;
|
||||
}
|
||||
if (dwMilliseconds)
|
||||
if (dwMilliseconds) {
|
||||
WaitForSingleObject(Received_Frame_Flag, dwMilliseconds);
|
||||
}
|
||||
MSTP_Master_Node_FSM(&MSTP_Port);
|
||||
}
|
||||
}
|
||||
@@ -236,10 +240,12 @@ uint16_t MSTP_Put_Receive(struct mstp_port_struct_t *mstp_port)
|
||||
if (!Receive_Packet.ready) {
|
||||
/* bounds check - maybe this should send an abort? */
|
||||
pdu_len = mstp_port->DataLength;
|
||||
if (pdu_len > sizeof(Receive_Packet.pdu))
|
||||
if (pdu_len > sizeof(Receive_Packet.pdu)) {
|
||||
pdu_len = sizeof(Receive_Packet.pdu);
|
||||
memmove((void *)&Receive_Packet.pdu[0],
|
||||
(void *)&mstp_port->InputBuffer[0], pdu_len);
|
||||
}
|
||||
memmove(
|
||||
(void *)&Receive_Packet.pdu[0], (void *)&mstp_port->InputBuffer[0],
|
||||
pdu_len);
|
||||
dlmstp_fill_bacnet_address(
|
||||
&Receive_Packet.address, mstp_port->SourceAddress);
|
||||
Receive_Packet.pdu_len = mstp_port->DataLength;
|
||||
@@ -252,8 +258,7 @@ uint16_t MSTP_Put_Receive(struct mstp_port_struct_t *mstp_port)
|
||||
|
||||
/* for the MS/TP state machine to use for getting data to send */
|
||||
/* Return: amount of PDU data */
|
||||
uint16_t MSTP_Get_Send(
|
||||
struct mstp_port_struct_t *mstp_port, unsigned timeout)
|
||||
uint16_t MSTP_Get_Send(struct mstp_port_struct_t *mstp_port, unsigned timeout)
|
||||
{ /* milliseconds to wait for a packet */
|
||||
uint16_t pdu_len = 0;
|
||||
uint8_t destination = 0; /* destination address */
|
||||
@@ -273,11 +278,11 @@ uint16_t MSTP_Get_Send(
|
||||
return 0;
|
||||
}
|
||||
/* convert the PDU into the MSTP Frame */
|
||||
pdu_len =
|
||||
MSTP_Create_Frame(&mstp_port->OutputBuffer[0], /* <-- loading this */
|
||||
mstp_port->OutputBufferSize, Transmit_Packet.frame_type,
|
||||
destination, mstp_port->This_Station, &Transmit_Packet.pdu[0],
|
||||
Transmit_Packet.pdu_len);
|
||||
pdu_len = MSTP_Create_Frame(
|
||||
&mstp_port->OutputBuffer[0], /* <-- loading this */
|
||||
mstp_port->OutputBufferSize, Transmit_Packet.frame_type, destination,
|
||||
mstp_port->This_Station, &Transmit_Packet.pdu[0],
|
||||
Transmit_Packet.pdu_len);
|
||||
Transmit_Packet.ready = false;
|
||||
|
||||
return pdu_len;
|
||||
@@ -291,13 +296,14 @@ uint16_t MSTP_Get_Send(
|
||||
*/
|
||||
void MSTP_Send_Frame(
|
||||
struct mstp_port_struct_t *mstp_port,
|
||||
const uint8_t * buffer,
|
||||
const uint8_t *buffer,
|
||||
uint16_t nbytes)
|
||||
{
|
||||
RS485_Send_Frame(mstp_port, buffer, nbytes);
|
||||
}
|
||||
|
||||
bool dlmstp_compare_data_expecting_reply(const uint8_t *request_pdu,
|
||||
bool dlmstp_compare_data_expecting_reply(
|
||||
const uint8_t *request_pdu,
|
||||
uint16_t request_pdu_len,
|
||||
uint8_t src_address,
|
||||
const uint8_t *reply_pdu,
|
||||
@@ -324,8 +330,9 @@ bool dlmstp_compare_data_expecting_reply(const uint8_t *request_pdu,
|
||||
/* decode the request data */
|
||||
request.address.mac[0] = src_address;
|
||||
request.address.mac_len = 1;
|
||||
offset = bacnet_npdu_decode(request_pdu, request_pdu_len, NULL,
|
||||
&request.address, &request.npdu_data);
|
||||
offset = bacnet_npdu_decode(
|
||||
request_pdu, request_pdu_len, NULL, &request.address,
|
||||
&request.npdu_data);
|
||||
if (request.npdu_data.network_layer_message) {
|
||||
return false;
|
||||
}
|
||||
@@ -335,10 +342,11 @@ bool dlmstp_compare_data_expecting_reply(const uint8_t *request_pdu,
|
||||
}
|
||||
request.invoke_id = request_pdu[offset + 2];
|
||||
/* segmented message? */
|
||||
if (request_pdu[offset] & BIT(3))
|
||||
if (request_pdu[offset] & BIT(3)) {
|
||||
request.service_choice = request_pdu[offset + 5];
|
||||
else
|
||||
} else {
|
||||
request.service_choice = request_pdu[offset + 3];
|
||||
}
|
||||
/* decode the reply data */
|
||||
bacnet_address_copy(&reply.address, dest_address);
|
||||
offset = bacnet_npdu_decode(
|
||||
@@ -357,10 +365,11 @@ bool dlmstp_compare_data_expecting_reply(const uint8_t *request_pdu,
|
||||
case PDU_TYPE_COMPLEX_ACK:
|
||||
reply.invoke_id = reply_pdu[offset + 1];
|
||||
/* segmented message? */
|
||||
if (reply_pdu[offset] & BIT(3))
|
||||
if (reply_pdu[offset] & BIT(3)) {
|
||||
reply.service_choice = reply_pdu[offset + 4];
|
||||
else
|
||||
} else {
|
||||
reply.service_choice = reply_pdu[offset + 2];
|
||||
}
|
||||
break;
|
||||
case PDU_TYPE_ERROR:
|
||||
reply.invoke_id = reply_pdu[offset + 1];
|
||||
@@ -406,8 +415,7 @@ bool dlmstp_compare_data_expecting_reply(const uint8_t *request_pdu,
|
||||
}
|
||||
|
||||
/* Get the reply to a DATA_EXPECTING_REPLY frame, or nothing */
|
||||
uint16_t MSTP_Get_Reply(
|
||||
struct mstp_port_struct_t *mstp_port, unsigned timeout)
|
||||
uint16_t MSTP_Get_Reply(struct mstp_port_struct_t *mstp_port, unsigned timeout)
|
||||
{ /* milliseconds to wait for a packet */
|
||||
uint16_t pdu_len = 0; /* return value */
|
||||
uint8_t destination = 0; /* destination address */
|
||||
@@ -427,18 +435,19 @@ uint16_t MSTP_Get_Reply(
|
||||
return 0;
|
||||
}
|
||||
/* is this the reply to the DER? */
|
||||
matched = dlmstp_compare_data_expecting_reply(&mstp_port->InputBuffer[0],
|
||||
mstp_port->DataLength, mstp_port->SourceAddress,
|
||||
&Transmit_Packet.pdu[0], Transmit_Packet.pdu_len,
|
||||
&Transmit_Packet.address);
|
||||
if (!matched)
|
||||
matched = dlmstp_compare_data_expecting_reply(
|
||||
&mstp_port->InputBuffer[0], mstp_port->DataLength,
|
||||
mstp_port->SourceAddress, &Transmit_Packet.pdu[0],
|
||||
Transmit_Packet.pdu_len, &Transmit_Packet.address);
|
||||
if (!matched) {
|
||||
return 0;
|
||||
}
|
||||
/* convert the PDU into the MSTP Frame */
|
||||
pdu_len =
|
||||
MSTP_Create_Frame(&mstp_port->OutputBuffer[0], /* <-- loading this */
|
||||
mstp_port->OutputBufferSize, Transmit_Packet.frame_type,
|
||||
destination, mstp_port->This_Station, &Transmit_Packet.pdu[0],
|
||||
Transmit_Packet.pdu_len);
|
||||
pdu_len = MSTP_Create_Frame(
|
||||
&mstp_port->OutputBuffer[0], /* <-- loading this */
|
||||
mstp_port->OutputBufferSize, Transmit_Packet.frame_type, destination,
|
||||
mstp_port->This_Station, &Transmit_Packet.pdu[0],
|
||||
Transmit_Packet.pdu_len);
|
||||
Transmit_Packet.ready = false;
|
||||
|
||||
return pdu_len;
|
||||
@@ -454,8 +463,9 @@ void dlmstp_set_mac_address(uint8_t mac_address)
|
||||
EEPROM_DEVICE_ADDRESS,
|
||||
mac_address,
|
||||
EEPROM_MSTP_MAC_ADDR); */
|
||||
if (mac_address > MSTP_Port.Nmax_master)
|
||||
if (mac_address > MSTP_Port.Nmax_master) {
|
||||
dlmstp_set_max_master(mac_address);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -571,8 +581,9 @@ bool dlmstp_init(char *ifname)
|
||||
Receive_Packet.ready = false;
|
||||
Receive_Packet.pdu_len = 0;
|
||||
Receive_Packet_Flag = CreateSemaphore(NULL, 0, 1, "dlmstpReceivePacket");
|
||||
if (Receive_Packet_Flag == NULL)
|
||||
if (Receive_Packet_Flag == NULL) {
|
||||
exit(1);
|
||||
}
|
||||
Received_Frame_Flag = CreateSemaphore(NULL, 0, 1, "dlsmtpReceiveFrame");
|
||||
if (Received_Frame_Flag == NULL) {
|
||||
CloseHandle(Receive_Packet_Flag);
|
||||
@@ -651,7 +662,8 @@ bool dlmstp_init(char *ifname)
|
||||
#ifdef TEST_DLMSTP
|
||||
#include <stdio.h>
|
||||
|
||||
void apdu_handler(BACNET_ADDRESS *src, /* source address */
|
||||
void apdu_handler(
|
||||
BACNET_ADDRESS *src, /* source address */
|
||||
uint8_t *apdu, /* APDU data */
|
||||
uint16_t pdu_len)
|
||||
{ /* for confirmed messages */
|
||||
|
||||
+53
-39
@@ -79,7 +79,8 @@ void dlmstp_cleanup(void)
|
||||
}
|
||||
|
||||
/* returns number of bytes sent on success, zero on failure */
|
||||
int dlmstp_send_pdu(BACNET_ADDRESS *dest, /* destination address */
|
||||
int dlmstp_send_pdu(
|
||||
BACNET_ADDRESS *dest, /* destination address */
|
||||
BACNET_NPDU_DATA *npdu_data, /* network information */
|
||||
uint8_t *pdu, /* any data to be sent - may be null */
|
||||
unsigned pdu_len)
|
||||
@@ -106,7 +107,8 @@ int dlmstp_send_pdu(BACNET_ADDRESS *dest, /* destination address */
|
||||
return bytes_sent;
|
||||
}
|
||||
|
||||
uint16_t dlmstp_receive(BACNET_ADDRESS *src, /* source address */
|
||||
uint16_t dlmstp_receive(
|
||||
BACNET_ADDRESS *src, /* source address */
|
||||
uint8_t *pdu, /* PDU data */
|
||||
uint16_t max_pdu, /* amount of space available in the PDU */
|
||||
unsigned timeout)
|
||||
@@ -123,7 +125,8 @@ uint16_t dlmstp_receive(BACNET_ADDRESS *src, /* source address */
|
||||
if (Receive_Packet.pdu_len) {
|
||||
MSTP_Packets++;
|
||||
if (src) {
|
||||
memmove(src, &Receive_Packet.address,
|
||||
memmove(
|
||||
src, &Receive_Packet.address,
|
||||
sizeof(Receive_Packet.address));
|
||||
}
|
||||
if (pdu) {
|
||||
@@ -184,9 +187,11 @@ static void dlmstp_master_fsm_task(void *pArg)
|
||||
dwMilliseconds = 0;
|
||||
break;
|
||||
}
|
||||
if (dwMilliseconds)
|
||||
if (dwMilliseconds) {
|
||||
WaitForSingleObject(Received_Frame_Flag, dwMilliseconds);
|
||||
while (MSTP_Master_Node_FSM(&MSTP_Port));
|
||||
}
|
||||
while (MSTP_Master_Node_FSM(&MSTP_Port))
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,10 +227,12 @@ uint16_t MSTP_Put_Receive(struct mstp_port_struct_t *mstp_port)
|
||||
if (!Receive_Packet.ready) {
|
||||
/* bounds check - maybe this should send an abort? */
|
||||
pdu_len = mstp_port->DataLength;
|
||||
if (pdu_len > sizeof(Receive_Packet.pdu))
|
||||
if (pdu_len > sizeof(Receive_Packet.pdu)) {
|
||||
pdu_len = sizeof(Receive_Packet.pdu);
|
||||
memmove((void *)&Receive_Packet.pdu[0],
|
||||
(void *)&mstp_port->InputBuffer[0], pdu_len);
|
||||
}
|
||||
memmove(
|
||||
(void *)&Receive_Packet.pdu[0], (void *)&mstp_port->InputBuffer[0],
|
||||
pdu_len);
|
||||
dlmstp_fill_bacnet_address(
|
||||
&Receive_Packet.address, mstp_port->SourceAddress);
|
||||
Receive_Packet.pdu_len = mstp_port->DataLength;
|
||||
@@ -239,8 +246,7 @@ uint16_t MSTP_Put_Receive(struct mstp_port_struct_t *mstp_port)
|
||||
|
||||
/* for the MS/TP state machine to use for getting data to send */
|
||||
/* Return: amount of PDU data */
|
||||
uint16_t MSTP_Get_Send(
|
||||
struct mstp_port_struct_t *mstp_port, unsigned timeout)
|
||||
uint16_t MSTP_Get_Send(struct mstp_port_struct_t *mstp_port, unsigned timeout)
|
||||
{ /* milliseconds to wait for a packet */
|
||||
uint16_t pdu_len = 0;
|
||||
uint8_t destination = 0; /* destination address */
|
||||
@@ -259,11 +265,11 @@ uint16_t MSTP_Get_Send(
|
||||
return 0;
|
||||
}
|
||||
/* convert the PDU into the MSTP Frame */
|
||||
pdu_len =
|
||||
MSTP_Create_Frame(&mstp_port->OutputBuffer[0], /* <-- loading this */
|
||||
mstp_port->OutputBufferSize, Transmit_Packet.frame_type,
|
||||
destination, mstp_port->This_Station, &Transmit_Packet.pdu[0],
|
||||
Transmit_Packet.pdu_len);
|
||||
pdu_len = MSTP_Create_Frame(
|
||||
&mstp_port->OutputBuffer[0], /* <-- loading this */
|
||||
mstp_port->OutputBufferSize, Transmit_Packet.frame_type, destination,
|
||||
mstp_port->This_Station, &Transmit_Packet.pdu[0],
|
||||
Transmit_Packet.pdu_len);
|
||||
Transmit_Packet.ready = false;
|
||||
|
||||
return pdu_len;
|
||||
@@ -277,13 +283,14 @@ uint16_t MSTP_Get_Send(
|
||||
*/
|
||||
void MSTP_Send_Frame(
|
||||
struct mstp_port_struct_t *mstp_port,
|
||||
const uint8_t * buffer,
|
||||
const uint8_t *buffer,
|
||||
uint16_t nbytes)
|
||||
{
|
||||
RS485_Send_Frame(mstp_port, buffer, nbytes);
|
||||
}
|
||||
|
||||
static bool dlmstp_compare_data_expecting_reply(const uint8_t *request_pdu,
|
||||
static bool dlmstp_compare_data_expecting_reply(
|
||||
const uint8_t *request_pdu,
|
||||
uint16_t request_pdu_len,
|
||||
uint8_t src_address,
|
||||
const uint8_t *reply_pdu,
|
||||
@@ -310,8 +317,9 @@ static bool dlmstp_compare_data_expecting_reply(const uint8_t *request_pdu,
|
||||
/* decode the request data */
|
||||
request.address.mac[0] = src_address;
|
||||
request.address.mac_len = 1;
|
||||
offset = (uint16_t)bacnet_npdu_decode(request_pdu, request_pdu_len, NULL,
|
||||
&request.address, &request.npdu_data);
|
||||
offset = (uint16_t)bacnet_npdu_decode(
|
||||
request_pdu, request_pdu_len, NULL, &request.address,
|
||||
&request.npdu_data);
|
||||
if (request.npdu_data.network_layer_message) {
|
||||
return false;
|
||||
}
|
||||
@@ -321,10 +329,11 @@ static bool dlmstp_compare_data_expecting_reply(const uint8_t *request_pdu,
|
||||
}
|
||||
request.invoke_id = request_pdu[offset + 2];
|
||||
/* segmented message? */
|
||||
if (request_pdu[offset] & BIT(3))
|
||||
if (request_pdu[offset] & BIT(3)) {
|
||||
request.service_choice = request_pdu[offset + 5];
|
||||
else
|
||||
} else {
|
||||
request.service_choice = request_pdu[offset + 3];
|
||||
}
|
||||
/* decode the reply data */
|
||||
bacnet_address_copy(&reply.address, dest_address);
|
||||
offset = (uint16_t)bacnet_npdu_decode(
|
||||
@@ -343,10 +352,11 @@ static bool dlmstp_compare_data_expecting_reply(const uint8_t *request_pdu,
|
||||
case PDU_TYPE_COMPLEX_ACK:
|
||||
reply.invoke_id = reply_pdu[offset + 1];
|
||||
/* segmented message? */
|
||||
if (reply_pdu[offset] & BIT(3))
|
||||
if (reply_pdu[offset] & BIT(3)) {
|
||||
reply.service_choice = reply_pdu[offset + 4];
|
||||
else
|
||||
} else {
|
||||
reply.service_choice = reply_pdu[offset + 2];
|
||||
}
|
||||
break;
|
||||
case PDU_TYPE_ERROR:
|
||||
reply.invoke_id = reply_pdu[offset + 1];
|
||||
@@ -392,8 +402,7 @@ static bool dlmstp_compare_data_expecting_reply(const uint8_t *request_pdu,
|
||||
}
|
||||
|
||||
/* Get the reply to a DATA_EXPECTING_REPLY frame, or nothing */
|
||||
uint16_t MSTP_Get_Reply(
|
||||
struct mstp_port_struct_t *mstp_port, unsigned timeout)
|
||||
uint16_t MSTP_Get_Reply(struct mstp_port_struct_t *mstp_port, unsigned timeout)
|
||||
{ /* milliseconds to wait for a packet */
|
||||
uint16_t pdu_len = 0; /* return value */
|
||||
uint8_t destination = 0; /* destination address */
|
||||
@@ -413,18 +422,19 @@ uint16_t MSTP_Get_Reply(
|
||||
return 0;
|
||||
}
|
||||
/* is this the reply to the DER? */
|
||||
matched = dlmstp_compare_data_expecting_reply(&mstp_port->InputBuffer[0],
|
||||
mstp_port->DataLength, mstp_port->SourceAddress,
|
||||
&Transmit_Packet.pdu[0], Transmit_Packet.pdu_len,
|
||||
&Transmit_Packet.address);
|
||||
if (!matched)
|
||||
matched = dlmstp_compare_data_expecting_reply(
|
||||
&mstp_port->InputBuffer[0], mstp_port->DataLength,
|
||||
mstp_port->SourceAddress, &Transmit_Packet.pdu[0],
|
||||
Transmit_Packet.pdu_len, &Transmit_Packet.address);
|
||||
if (!matched) {
|
||||
return 0;
|
||||
}
|
||||
/* convert the PDU into the MSTP Frame */
|
||||
pdu_len =
|
||||
MSTP_Create_Frame(&mstp_port->OutputBuffer[0], /* <-- loading this */
|
||||
mstp_port->OutputBufferSize, Transmit_Packet.frame_type,
|
||||
destination, mstp_port->This_Station, &Transmit_Packet.pdu[0],
|
||||
Transmit_Packet.pdu_len);
|
||||
pdu_len = MSTP_Create_Frame(
|
||||
&mstp_port->OutputBuffer[0], /* <-- loading this */
|
||||
mstp_port->OutputBufferSize, Transmit_Packet.frame_type, destination,
|
||||
mstp_port->This_Station, &Transmit_Packet.pdu[0],
|
||||
Transmit_Packet.pdu_len);
|
||||
Transmit_Packet.ready = false;
|
||||
|
||||
return pdu_len;
|
||||
@@ -440,8 +450,9 @@ void dlmstp_set_mac_address(uint8_t mac_address)
|
||||
EEPROM_DEVICE_ADDRESS,
|
||||
mac_address,
|
||||
EEPROM_MSTP_MAC_ADDR); */
|
||||
if (mac_address > MSTP_Port.Nmax_master)
|
||||
if (mac_address > MSTP_Port.Nmax_master) {
|
||||
dlmstp_set_max_master(mac_address);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -556,8 +567,9 @@ bool dlmstp_init(char *ifname)
|
||||
Receive_Packet.ready = false;
|
||||
Receive_Packet.pdu_len = 0;
|
||||
Receive_Packet_Flag = CreateSemaphore(NULL, 0, 1, "dlmstpReceivePacket");
|
||||
if (Receive_Packet_Flag == NULL)
|
||||
if (Receive_Packet_Flag == NULL) {
|
||||
exit(1);
|
||||
}
|
||||
Received_Frame_Flag = CreateSemaphore(NULL, 0, 1, "dlsmtpReceiveFrame");
|
||||
if (Received_Frame_Flag == NULL) {
|
||||
CloseHandle(Receive_Packet_Flag);
|
||||
@@ -608,7 +620,8 @@ bool dlmstp_init(char *ifname)
|
||||
#if PRINT_ENABLED
|
||||
fprintf(stderr, "MS/TP MAC: %02X\n", MSTP_Port.This_Station);
|
||||
fprintf(stderr, "MS/TP Max_Master: %02X\n", MSTP_Port.Nmax_master);
|
||||
fprintf(stderr, "MS/TP Max_Info_Frames: %u\n",
|
||||
fprintf(
|
||||
stderr, "MS/TP Max_Info_Frames: %u\n",
|
||||
(unsigned)MSTP_Port.Nmax_info_frames);
|
||||
#endif
|
||||
hThread = _beginthread(dlmstp_receive_fsm_task, 4096, &arg_value);
|
||||
@@ -626,7 +639,8 @@ bool dlmstp_init(char *ifname)
|
||||
#ifdef TEST_DLMSTP
|
||||
#include <stdio.h>
|
||||
|
||||
void apdu_handler(BACNET_ADDRESS *src, /* source address */
|
||||
void apdu_handler(
|
||||
BACNET_ADDRESS *src, /* source address */
|
||||
uint8_t *apdu, /* APDU data */
|
||||
uint16_t pdu_len)
|
||||
{ /* for confirmed messages */
|
||||
|
||||
+14
-7
@@ -110,8 +110,9 @@ bool ethernet_init(char *if_name)
|
||||
int i;
|
||||
char msg[200];
|
||||
|
||||
if (ethernet_valid())
|
||||
if (ethernet_valid()) {
|
||||
ethernet_cleanup();
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the interface user specified
|
||||
@@ -126,8 +127,9 @@ bool ethernet_init(char *if_name)
|
||||
}
|
||||
/* Scan the list printing every entry */
|
||||
for (dev = pcap_all_if; dev; dev = dev->next) {
|
||||
if (strcmp(if_name, dev->name) == 0)
|
||||
if (strcmp(if_name, dev->name) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
pcap_freealldevs(pcap_all_if); /* we don't need it anymore */
|
||||
if (dev == NULL) {
|
||||
@@ -161,8 +163,9 @@ bool ethernet_init(char *if_name)
|
||||
LogError("ethernet.c: error in PacketRequest()\n");
|
||||
return false;
|
||||
}
|
||||
for (i = 0; i < 6; ++i)
|
||||
for (i = 0; i < 6; ++i) {
|
||||
Ethernet_MAC_Address[i] = pOidData->Data[i];
|
||||
}
|
||||
PacketCloseAdapter(lpAdapter);
|
||||
|
||||
/**
|
||||
@@ -317,11 +320,13 @@ uint16_t ethernet_receive(
|
||||
msg, sizeof(), "ethernet.c: error in receiving packet: %s\n",
|
||||
pcap_geterr(pcap_eth802_fp));
|
||||
return 0;
|
||||
} else if (res == 0)
|
||||
} else if (res == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (header->len == 0 || header->caplen == 0)
|
||||
if (header->len == 0 || header->caplen == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* the signature of an 802.2 BACnet packet */
|
||||
if ((pkt_data[14] != 0x82) && (pkt_data[15] != 0x82)) {
|
||||
@@ -343,11 +348,13 @@ uint16_t ethernet_receive(
|
||||
(void)decode_unsigned16(&pkt_data[12], &pdu_len);
|
||||
pdu_len -= 3 /* DSAP, SSAP, LLC Control */;
|
||||
/* copy the buffer into the PDU */
|
||||
if (pdu_len < max_pdu)
|
||||
if (pdu_len < max_pdu) {
|
||||
memmove(&pdu[0], &pkt_data[17], pdu_len);
|
||||
}
|
||||
/* ignore packets that are too large */
|
||||
else
|
||||
else {
|
||||
pdu_len = 0;
|
||||
}
|
||||
|
||||
return pdu_len;
|
||||
}
|
||||
|
||||
+28
-18
@@ -42,14 +42,17 @@
|
||||
#include "bacnet/basic/object/bacfile.h"
|
||||
#endif
|
||||
|
||||
/** Static receive buffer, initialized with zeros by the C Library Startup Code. */
|
||||
/** Static receive buffer, initialized with zeros by the C Library Startup Code.
|
||||
*/
|
||||
|
||||
static uint8_t Rx_Buf[MAX_MPDU + 16 /* Add a little safety margin to the buffer,
|
||||
* so that in the rare case, the message
|
||||
* would be filled up to MAX_MPDU and some
|
||||
* decoding functions would overrun, these
|
||||
* decoding functions will just end up in
|
||||
* a safe field of static zeros. */] = { 0 };
|
||||
static uint8_t Rx_Buf
|
||||
[MAX_MPDU + 16 /* Add a little safety margin to the buffer,
|
||||
* so that in the rare case, the message
|
||||
* would be filled up to MAX_MPDU and some
|
||||
* decoding functions would overrun, these
|
||||
* decoding functions will just end up in
|
||||
* a safe field of static zeros. */
|
||||
] = { 0 };
|
||||
|
||||
/* send a whois to see who is on the network */
|
||||
static bool Who_Is_Request = true;
|
||||
@@ -68,9 +71,10 @@ static void Read_Properties(void)
|
||||
Device Object
|
||||
note: you could just loop through
|
||||
all the properties in all the objects. */
|
||||
const int object_props[] = { PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME,
|
||||
PROP_OBJECT_TYPE, PROP_SYSTEM_STATUS, PROP_VENDOR_NAME,
|
||||
PROP_VENDOR_IDENTIFIER, PROP_MODEL_NAME, PROP_FIRMWARE_REVISION,
|
||||
const int object_props[] = {
|
||||
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE,
|
||||
PROP_SYSTEM_STATUS, PROP_VENDOR_NAME, PROP_VENDOR_IDENTIFIER,
|
||||
PROP_MODEL_NAME, PROP_FIRMWARE_REVISION,
|
||||
PROP_APPLICATION_SOFTWARE_VERSION, PROP_PROTOCOL_VERSION,
|
||||
PROP_PROTOCOL_SERVICES_SUPPORTED, PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED,
|
||||
PROP_MAX_APDU_LENGTH_ACCEPTED, PROP_SEGMENTATION_SUPPORTED,
|
||||
@@ -85,27 +89,31 @@ static void Read_Properties(void)
|
||||
/* some proprietary properties */
|
||||
514, 515,
|
||||
/* end of list */
|
||||
-1 };
|
||||
-1
|
||||
};
|
||||
|
||||
if (address_count()) {
|
||||
if (address_get_by_index(index, &device_id, &max_apdu, &src)) {
|
||||
if (object_props[property] < 0)
|
||||
if (object_props[property] < 0) {
|
||||
next_device = true;
|
||||
else {
|
||||
} else {
|
||||
status = Send_Read_Property_Request(
|
||||
device_id, /* destination device */
|
||||
OBJECT_DEVICE, device_id, object_props[property],
|
||||
BACNET_ARRAY_ALL);
|
||||
if (status)
|
||||
if (status) {
|
||||
property++;
|
||||
}
|
||||
}
|
||||
} else
|
||||
} else {
|
||||
next_device = true;
|
||||
}
|
||||
if (next_device) {
|
||||
next_device = false;
|
||||
index++;
|
||||
if (index >= MAX_ADDRESS_CACHE)
|
||||
if (index >= MAX_ADDRESS_CACHE) {
|
||||
index = 0;
|
||||
}
|
||||
property = 0;
|
||||
}
|
||||
}
|
||||
@@ -130,8 +138,9 @@ static void LocalIAmHandler(
|
||||
if (len != -1) {
|
||||
fprintf(stderr, " from %u!\n", device_id);
|
||||
address_add(device_id, max_apdu, src);
|
||||
} else
|
||||
} else {
|
||||
fprintf(stderr, "!\n");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -261,8 +270,9 @@ int main(int argc, char *argv[])
|
||||
/* blink LEDs, Turn on or off outputs, etc */
|
||||
|
||||
/* wait for ESC from keyboard before quitting */
|
||||
if (kbhit() && (getch() == 0x1B))
|
||||
if (kbhit() && (getch() == 0x1B)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
print_address_cache();
|
||||
|
||||
@@ -49,7 +49,8 @@ void mstimer_init(void)
|
||||
/* configure for 1ms resolution - if possible */
|
||||
Timer_Period = min(max(tc.wPeriodMin, 1L), tc.wPeriodMax);
|
||||
if (Timer_Period != 1L) {
|
||||
fprintf(stderr,
|
||||
fprintf(
|
||||
stderr,
|
||||
"Failed to set timer to 1ms. "
|
||||
"Time period set to %ums\n",
|
||||
(unsigned)Timer_Period);
|
||||
|
||||
+13
-10
@@ -137,8 +137,9 @@ void RS485_Print_Error(void)
|
||||
{
|
||||
LPVOID lpMsgBuf;
|
||||
|
||||
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL,
|
||||
GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPTSTR)&lpMsgBuf, 0, NULL);
|
||||
MessageBox(NULL, lpMsgBuf, "GetLastError", MB_OK | MB_ICONINFORMATION);
|
||||
LocalFree(lpMsgBuf);
|
||||
@@ -237,8 +238,8 @@ static void RS485_Cleanup(void)
|
||||
*****************************************************************************/
|
||||
void RS485_Initialize(void)
|
||||
{
|
||||
RS485_Handle = CreateFile(RS485_Port_Name, GENERIC_READ | GENERIC_WRITE, 0,
|
||||
0, OPEN_EXISTING,
|
||||
RS485_Handle = CreateFile(
|
||||
RS485_Port_Name, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING,
|
||||
/*FILE_FLAG_OVERLAPPED */ 0, 0);
|
||||
if (RS485_Handle == INVALID_HANDLE_VALUE) {
|
||||
fprintf(stderr, "RS485 unable to open %s\n", RS485_Port_Name);
|
||||
@@ -397,7 +398,7 @@ bool RS485_Set_Baud_Rate(uint32_t baud)
|
||||
/* Transmits a Frame on the wire */
|
||||
void RS485_Send_Frame(
|
||||
struct mstp_port_struct_t *mstp_port, /* port specific data */
|
||||
const uint8_t *buffer, /* frame to send (up to 501 bytes of data) */
|
||||
const uint8_t *buffer, /* frame to send (up to 501 bytes of data) */
|
||||
uint16_t nbytes)
|
||||
{ /* number of bytes of data (up to 501) */
|
||||
DWORD dwWritten = 0;
|
||||
@@ -407,12 +408,13 @@ void RS485_Send_Frame(
|
||||
uint8_t turnaround_time;
|
||||
baud = RS485_Get_Baud_Rate();
|
||||
/* wait about 40 bit times since reception */
|
||||
if (baud == 9600)
|
||||
if (baud == 9600) {
|
||||
turnaround_time = 4;
|
||||
else if (baud == 19200)
|
||||
} else if (baud == 19200) {
|
||||
turnaround_time = 2;
|
||||
else
|
||||
} else {
|
||||
turnaround_time = 2;
|
||||
}
|
||||
while (mstp_port->SilenceTimer(NULL) < turnaround_time) {
|
||||
/* do nothing - wait for timer to increment */
|
||||
};
|
||||
@@ -465,8 +467,9 @@ void RS485_Print_Ports(void)
|
||||
for (i = 1; i < 256; i++) {
|
||||
if (RS485_Interface_Valid(i)) {
|
||||
/* note: format for Wireshark ExtCap */
|
||||
printf("interface {value=COM%u}"
|
||||
"{display=BACnet MS/TP on COM%u}\n",
|
||||
printf(
|
||||
"interface {value=COM%u}"
|
||||
"{display=BACnet MS/TP on COM%u}\n",
|
||||
i, i);
|
||||
}
|
||||
}
|
||||
|
||||
+24
-33
@@ -16,45 +16,36 @@
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
void RS485_Set_Interface(
|
||||
char *ifname);
|
||||
BACNET_STACK_EXPORT
|
||||
const char *RS485_Interface(
|
||||
void);
|
||||
BACNET_STACK_EXPORT
|
||||
void RS485_Set_Interface(char *ifname);
|
||||
BACNET_STACK_EXPORT
|
||||
const char *RS485_Interface(void);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
void RS485_Initialize(
|
||||
void);
|
||||
BACNET_STACK_EXPORT
|
||||
void RS485_Initialize(void);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
void RS485_Send_Frame(
|
||||
struct mstp_port_struct_t *mstp_port, /* port specific data */
|
||||
const uint8_t * buffer, /* frame to send (up to 501 bytes of data) */
|
||||
uint16_t nbytes); /* number of bytes of data (up to 501) */
|
||||
BACNET_STACK_EXPORT
|
||||
void RS485_Send_Frame(
|
||||
struct mstp_port_struct_t *mstp_port, /* port specific data */
|
||||
const uint8_t *buffer, /* frame to send (up to 501 bytes of data) */
|
||||
uint16_t nbytes); /* number of bytes of data (up to 501) */
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
void RS485_Check_UART_Data(
|
||||
struct mstp_port_struct_t *mstp_port); /* port specific data */
|
||||
BACNET_STACK_EXPORT
|
||||
void RS485_Check_UART_Data(
|
||||
struct mstp_port_struct_t *mstp_port); /* port specific data */
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
uint32_t RS485_Get_Baud_Rate(
|
||||
void);
|
||||
BACNET_STACK_EXPORT
|
||||
bool RS485_Set_Baud_Rate(
|
||||
uint32_t baud);
|
||||
BACNET_STACK_EXPORT
|
||||
uint32_t RS485_Get_Baud_Rate(void);
|
||||
BACNET_STACK_EXPORT
|
||||
bool RS485_Set_Baud_Rate(uint32_t baud);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
void RS485_Print_Error(
|
||||
void);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
bool RS485_Interface_Valid(
|
||||
unsigned port_number);
|
||||
BACNET_STACK_EXPORT
|
||||
void RS485_Print_Ports(
|
||||
void);
|
||||
BACNET_STACK_EXPORT
|
||||
void RS485_Print_Error(void);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
bool RS485_Interface_Valid(unsigned port_number);
|
||||
BACNET_STACK_EXPORT
|
||||
void RS485_Print_Ports(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user