From 7b6a0923f08777b8fe9737bce54a3a8ce6bcd792 Mon Sep 17 00:00:00 2001 From: Steve Karg Date: Tue, 29 Oct 2024 20:09:16 -0500 Subject: [PATCH] Added missing MS/TP zero configuration preferred address API and usage. (#840) --- ports/stm32f4xx/main.c | 4 +- src/bacnet/datalink/dlmstp.c | 110 +++++++++++++++++++++++++++++++++++ src/bacnet/datalink/dlmstp.h | 14 +++++ src/bacnet/datalink/mstp.c | 7 ++- src/bacnet/datalink/mstp.h | 2 + 5 files changed, 135 insertions(+), 2 deletions(-) diff --git a/ports/stm32f4xx/main.c b/ports/stm32f4xx/main.c index 4699c3dc..14e670af 100644 --- a/ports/stm32f4xx/main.c +++ b/ports/stm32f4xx/main.c @@ -98,9 +98,11 @@ int main(void) MSTP_Port.InputBufferSize = sizeof(Input_Buffer); MSTP_Port.OutputBuffer = Output_Buffer; MSTP_Port.OutputBufferSize = sizeof(Output_Buffer); - /* user data */ + /* choose from non-volatile configuration for zero-config or slave mode */ MSTP_Port.ZeroConfigEnabled = true; + MSTP_Port.Zero_Config_Preferred_Station = 0; MSTP_Port.SlaveNodeEnabled = false; + /* user data */ MSTP_User_Data.RS485_Driver = &RS485_Driver; MSTP_Port.UserData = &MSTP_User_Data; dlmstp_init((char *)&MSTP_Port); diff --git a/src/bacnet/datalink/dlmstp.c b/src/bacnet/datalink/dlmstp.c index c783713e..5f28175a 100644 --- a/src/bacnet/datalink/dlmstp.c +++ b/src/bacnet/datalink/dlmstp.c @@ -611,6 +611,116 @@ void dlmstp_get_broadcast_address(BACNET_ADDRESS *dest) return; } +/** + * @brief Get the MSTP port SoleMaster status + * @return true if the MSTP port is the SoleMaster + */ +bool dlmstp_sole_master(void) +{ + if (!MSTP_Port) { + return false; + } + if (MSTP_Port->SoleMaster) { + return true; + } + + return false; +} + +/** + * @brief Get the MSTP port SlaveNodeEnabled status + * @return true if the MSTP port has SlaveNodeEnabled + */ +bool dlmstp_slave_mode_enabled(void) +{ + if (!MSTP_Port) { + return false; + } + return MSTP_Port->SlaveNodeEnabled; +} + +/** + * @brief Set the MSTP port SlaveNodeEnabled flag + * @param flag - true if the MSTP port has SlaveNodeEnabled + * @return true if the MSTP port SlaveNodeEnabled was set + * @note This flag is used to enable the Slave Node state machine + * for the MSTP port. The Slave Node state machine is used to + * respond to requests from the Master Node. + */ +bool dlmstp_slave_mode_enabled_set(bool flag) +{ + if (!MSTP_Port) { + return false; + } + MSTP_Port->SlaveNodeEnabled = flag; + + return true; +} + +/** + * @brief Get the MSTP port ZeroConfigEnabled status + * @return true if the MSTP port has ZeroConfigEnabled + */ +bool dlmstp_zero_config_enabled(void) +{ + if (!MSTP_Port) { + return false; + } + return MSTP_Port->ZeroConfigEnabled; +} + +/** + * @brief Set the MSTP port ZeroConfigEnabled flag + * @param flag - true if the MSTP port has ZeroConfigEnabled + * @return true if the MSTP port ZeroConfigEnabled was set + * @note This flag is used to enable the Zero Configuration state machine + * for the MSTP port. The Zero Configuration state machine is used to + * automatically assign a MAC address to the MSTP port. + */ +bool dlmstp_zero_config_enabled_set(bool flag) +{ + if (!MSTP_Port) { + return false; + } + MSTP_Port->ZeroConfigEnabled = flag; + + return true; +} + +/** + * @brief Get the MSTP port MAC address that this node prefers to use. + * @return ZeroConfigStation value + */ +uint8_t dlmstp_zero_config_preferred_station(void) +{ + if (!MSTP_Port) { + return Nmin_poll_station; + } + if ((MSTP_Port->Zero_Config_Preferred_Station < Nmin_poll_station) || + (MSTP_Port->Zero_Config_Preferred_Station > Nmax_poll_station)) { + return Nmin_poll_station; + } + + return MSTP_Port->Zero_Config_Preferred_Station; +} + +/** + * @brief Set the MSTP port MAC address that this node prefers to use. + * @param station - Zero_Config_Preferred_Station value + * @return true if the MSTP port Zero_Config_Preferred_Station was set + */ +bool dlmstp_zero_config_preferred_station_set(uint8_t station) +{ + if (!MSTP_Port) { + return false; + } + /* note: valid values are between Nmin_poll_station and Nmax_poll_station + but other values such as 0 or 255 could mean 'unconfigured' */ + MSTP_Port->Zero_Config_Preferred_Station = station; + + return true; +} + /** * @brief Determine if the send PDU queue is empty * @return true if the send PDU is empty diff --git a/src/bacnet/datalink/dlmstp.h b/src/bacnet/datalink/dlmstp.h index 78849f89..da12eafd 100644 --- a/src/bacnet/datalink/dlmstp.h +++ b/src/bacnet/datalink/dlmstp.h @@ -179,6 +179,20 @@ 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_slave_mode_enabled(void); +BACNET_STACK_EXPORT +bool dlmstp_slave_mode_enabled_set(bool flag); + +BACNET_STACK_EXPORT +bool dlmstp_zero_config_enabled(void); +BACNET_STACK_EXPORT +bool dlmstp_zero_config_enabled_set(bool flag); +BACNET_STACK_EXPORT +uint8_t dlmstp_zero_config_preferred_station(void); +BACNET_STACK_EXPORT +bool dlmstp_zero_config_preferred_station_set(uint8_t station); + BACNET_STACK_EXPORT bool dlmstp_send_pdu_queue_empty(void); BACNET_STACK_EXPORT diff --git a/src/bacnet/datalink/mstp.c b/src/bacnet/datalink/mstp.c index d06e7820..ce4c4fcd 100644 --- a/src/bacnet/datalink/mstp.c +++ b/src/bacnet/datalink/mstp.c @@ -1403,7 +1403,12 @@ static void MSTP_Zero_Config_State_Init(struct mstp_port_struct_t *mstp_port) return; } mstp_port->Poll_Count = 0; - mstp_port->Zero_Config_Station = Nmin_poll_station; + /* initialize the zero config station address */ + if ((mstp_port->Zero_Config_Preferred_Station < Nmin_poll_station) || + (mstp_port->Zero_Config_Preferred_Station > Nmax_poll_station)) { + mstp_port->Zero_Config_Preferred_Station = Nmin_poll_station; + } + mstp_port->Zero_Config_Station = mstp_port->Zero_Config_Preferred_Station; mstp_port->Npoll_slot = 1 + (mstp_port->UUID[0] % Nmax_poll_slot); /* basic silence timeout is the dropped token time plus one Tslot after the last master node. Add one Tslot of diff --git a/src/bacnet/datalink/mstp.h b/src/bacnet/datalink/mstp.h index 5c2f7e19..8bec38c0 100644 --- a/src/bacnet/datalink/mstp.h +++ b/src/bacnet/datalink/mstp.h @@ -164,6 +164,8 @@ struct mstp_port_struct_t { /* the MAC address that this node is testing for MAC addresses that are not in-use.*/ uint8_t Zero_Config_Station; + /* the MAC address that this node prefers to use.*/ + uint8_t Zero_Config_Preferred_Station; /* Used to count the number of received poll-for-master frames This is used in the detection of addresses not in-use. */ uint8_t Poll_Count;