Added MS/TP datalink option to BACnet basic server example. (#1077)

This commit is contained in:
Steve Karg
2025-08-25 11:02:43 -05:00
committed by GitHub
parent a3cd49eb37
commit ad5a43042c
10 changed files with 207 additions and 10 deletions
+6
View File
@@ -20,6 +20,8 @@
#include "bacnet/basic/server/bacnet_port_ipv4.h"
#elif defined(BACDL_BIP6)
#include "bacnet/basic/server/bacnet_port_ipv6.h"
#elif defined(BACDL_MSTP)
#include "bacnet/basic/server/bacnet_port_mstp.h"
#endif
/* me! */
#include "bacnet/basic/server/bacnet_port.h"
@@ -45,6 +47,8 @@ void bacnet_port_task(void)
bacnet_port_ipv4_task(elapsed_seconds);
#elif defined(BACDL_BIP6)
bacnet_port_ipv6_task(elapsed_seconds);
#elif defined(BACDL_MSTP)
bacnet_port_mstp_task(elapsed_seconds);
#else
/* nothing to do */
(void)elapsed_seconds;
@@ -64,6 +68,8 @@ bool bacnet_port_init(void)
status = bacnet_port_ipv4_init();
#elif defined(BACDL_BIP6)
status = bacnet_port_ipv6_init();
#elif defined(BACDL_MSTP)
status = bacnet_port_mstp_init();
#endif
return status;
}
@@ -0,0 +1,70 @@
/**
* @file
* @brief The BACnet datalink tasks for handling the device specific
* data link layer
* @author Steve Karg <skarg@users.sourceforge.net>
* @date January 2025
* @copyright SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
/* BACnet definitions */
#include "bacnet/bacdef.h"
/* BACnet library API */
#include "bacnet/basic/object/netport.h"
#include "bacnet/datalink/datalink.h"
#include "bacnet/datalink/dlmstp.h"
/* BACnet Basic network port */
#include "bacnet/basic/server/bacnet_port_mstp.h"
#if defined(BACDL_MSTP)
static struct dlmstp_statistics Statistics = { 0 };
static uint16_t Timer_Seconds;
/**
* @brief Application Task
*/
void bacnet_port_mstp_task(uint16_t elapsed_seconds)
{
Timer_Seconds += elapsed_seconds;
if (Timer_Seconds >= 60) {
Timer_Seconds = 0;
dlmstp_fill_statistics(&Statistics);
}
}
/**
* Initialize the network port object.
* @return true if successful
*/
bool bacnet_port_mstp_init(void)
{
uint32_t instance = 1;
BACNET_ADDRESS addr = { 0 };
if (!dlmstp_init(NULL)) {
return false;
}
Network_Port_Object_Instance_Number_Set(0, instance);
Network_Port_Name_Set(instance, "BACnet MS/TP Port");
Network_Port_Type_Set(instance, PORT_TYPE_MSTP);
dlmstp_get_my_address(&addr);
Network_Port_MAC_Address_Set(instance, &addr.mac[0], addr.mac_len);
Network_Port_Reliability_Set(instance, RELIABILITY_NO_FAULT_DETECTED);
Network_Port_Out_Of_Service_Set(instance, false);
Network_Port_Quality_Set(instance, PORT_QUALITY_UNKNOWN);
Network_Port_APDU_Length_Set(instance, MAX_APDU);
Network_Port_Network_Number_Set(instance, 0);
/* MS/TP specific */
Network_Port_Link_Speed_Set(instance, dlmstp_baud_rate());
Network_Port_MSTP_Max_Info_Frames_Set(instance, dlmstp_max_info_frames());
Network_Port_MSTP_Max_Master_Set(instance, dlmstp_max_master());
/* last thing - clear pending changes - we don't want to set these
since they are already set */
Network_Port_Changes_Pending_Set(instance, false);
return true;
}
#endif
@@ -0,0 +1,28 @@
/**
* @file
* @brief The BACnet MS/TP datalink tasks for handling the device specific
* data link network port layer
* @author Steve Karg <skarg@users.sourceforge.net>
* @date January 2025
* @copyright SPDX-License-Identifier: Apache-2.0
*/
#ifndef BACNET_PORT_MSTP_H
#define BACNET_PORT_MSTP_H
#include <stdbool.h>
#include <stdint.h>
/* BACnet Stack defines - first */
#include "bacnet/bacdef.h"
#include "bacnet/datalink/dlmstp.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
void bacnet_port_mstp_task(uint16_t elapsed_seconds);
bool bacnet_port_mstp_init(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
+25 -2
View File
@@ -1094,6 +1094,24 @@ void dlmstp_silence_reset(void *arg)
}
}
/**
* @brief set the MS/TP datalink interface
* @param ifname - interface name to set
*/
void dlmstp_set_interface(const char *ifname)
{
MSTP_Port = (struct mstp_port_struct_t *)ifname;
}
/**
* @brief get the MS/TP datalink intferface name
* @return interface name
*/
const char *dlmstp_get_interface(void)
{
return (const char *)MSTP_Port;
}
/**
* @brief Initialize this MS/TP datalink
* @param ifname user data structure
@@ -1101,8 +1119,12 @@ void dlmstp_silence_reset(void *arg)
*/
bool dlmstp_init(char *ifname)
{
bool status = false;
struct dlmstp_user_data_t *user;
MSTP_Port = (struct mstp_port_struct_t *)ifname;
if (ifname) {
MSTP_Port = (struct mstp_port_struct_t *)ifname;
}
if (MSTP_Port) {
MSTP_Port->SilenceTimer = dlmstp_silence_milliseconds;
MSTP_Port->SilenceTimerReset = dlmstp_silence_reset;
@@ -1119,7 +1141,8 @@ bool dlmstp_init(char *ifname)
MSTP_Init(MSTP_Port);
user->Initialized = true;
}
status = true;
}
return true;
return status;
}
+4
View File
@@ -120,6 +120,10 @@ extern "C" {
BACNET_STACK_EXPORT
bool dlmstp_init(char *ifname);
BACNET_STACK_EXPORT
void dlmstp_set_interface(const char *ifname);
BACNET_STACK_EXPORT
const char *dlmstp_get_interface(void);
BACNET_STACK_EXPORT
void dlmstp_reset(void);
BACNET_STACK_EXPORT
void dlmstp_cleanup(void);