Added BACnet Zigbee Link Layer (#1052)

This commit is contained in:
Steve Karg
2025-07-28 13:06:48 -05:00
committed by GitHub
parent 85ba0b2315
commit b326563a3c
13 changed files with 497 additions and 70 deletions
+62
View File
@@ -0,0 +1,62 @@
/**
* @file
* @brief A BACnet/ZigBee Data Link Layer (BZLL)
* @author Steve Karg <skarg@users.sourceforge.net>
* @date July 2025
* @copyright SPDX-License-Identifier: MIT
* @defgroup DL_ZIGBEE BACnet/ZigBee Data Link Layer (BZLL)
* @ingroup DataLink
*/
#ifndef BACNET_ZIGBEE_LINK_LAYER_H
#define BACNET_ZIGBEE_LINK_LAYER_H
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
/* BACnet Stack defines - first */
#include "bacnet/bacdef.h"
/* BACnet Stack API */
#include "bacnet/npdu.h"
/* ZigBee Cluster Library (ZCL) client to server frame */
#define BZLL_HEADER_MAX (1 + 1)
#define BZLL_MPDU_MAX (BZLL_HEADER_MAX + MAX_PDU)
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
BACNET_STACK_EXPORT
bool bzll_valid(void);
BACNET_STACK_EXPORT
void bzll_cleanup(void);
BACNET_STACK_EXPORT
bool bzll_init(char *interface_name);
BACNET_STACK_EXPORT
int bzll_send_pdu(
BACNET_ADDRESS *dest,
BACNET_NPDU_DATA *npdu_data,
uint8_t *pdu,
unsigned pdu_len);
BACNET_STACK_EXPORT
uint16_t bzll_receive(
BACNET_ADDRESS *src, uint8_t *pdu, uint16_t max_pdu, unsigned timeout);
BACNET_STACK_EXPORT
int bzll_send(uint8_t *mtu, int mtu_len);
BACNET_STACK_EXPORT
void bzll_set_my_address(const BACNET_ADDRESS *my_address);
BACNET_STACK_EXPORT
void bzll_get_my_address(BACNET_ADDRESS *my_address);
BACNET_STACK_EXPORT
void bzll_get_broadcast_address(BACNET_ADDRESS *dest);
BACNET_STACK_EXPORT
void bzll_maintenance_timer(uint16_t seconds);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
+49
View File
@@ -30,6 +30,9 @@
#if defined(BACDL_MSTP)
#include "bacnet/datalink/dlmstp.h"
#endif
#if defined(BACDL_ZIGBEE)
#include "bacnet/datalink/bzll.h"
#endif
#if defined(BACDL_BSC)
#include "bacnet/datalink/bsc/bsc-datalink.h"
#endif
@@ -41,6 +44,7 @@ static enum {
DATALINK_BIP,
DATALINK_BIP6,
DATALINK_MSTP,
DATALINK_ZIGBEE,
DATALINK_BSC
} Datalink_Transport;
@@ -74,6 +78,11 @@ void datalink_set(char *datalink_string)
Datalink_Transport = DATALINK_MSTP;
}
#endif
#if defined(BACDL_ZIGBEE)
else if (bacnet_stricmp("zigbee", datalink_string) == 0) {
Datalink_Transport = DATALINK_ARCNET;
}
#endif
#if defined(BACDL_BSC)
else if (bacnet_stricmp("bsc", datalink_string) == 0) {
Datalink_Transport = DATALINK_BSC;
@@ -114,6 +123,11 @@ bool datalink_init(char *ifname)
status = dlmstp_init(ifname);
break;
#endif
#if defined(BACDL_ZIGBEE)
case DATALINK_ZIGBEE:
status = bzll_init(ifname);
break;
#endif
#if defined(BACDL_BSC)
case DATALINK_BSC:
status = bsc_init(ifname);
@@ -163,6 +177,11 @@ int datalink_send_pdu(
bytes = dlmstp_send_pdu(dest, npdu_data, pdu, pdu_len);
break;
#endif
#if defined(BACDL_ZIGBEE)
case DATALINK_ZIGBEE:
bytes = bzll_send_pdu(dest, npdu_data, pdu, pdu_len);
break;
#endif
#if defined(BACDL_BSC)
case DATALINK_BSC:
bytes = bsc_send_pdu(dest, npdu_data, pdu, pdu_len);
@@ -208,6 +227,11 @@ uint16_t datalink_receive(
bytes = dlmstp_receive(src, pdu, max_pdu, timeout);
break;
#endif
#if defined(BACDL_ZIGBEE)
case DATALINK_ZIGBEE:
bytes = bzll_receive(src, pdu, max_pdu, timeout);
break;
#endif
#if defined(BACDL_BSC)
case DATALINK_BSC:
bytes = bsc_receive(src, pdu, max_pdu, timeout);
@@ -250,6 +274,11 @@ void datalink_cleanup(void)
dlmstp_cleanup();
break;
#endif
#if defined(BACDL_ZIGBEE)
case DATALINK_ZIGBEE:
bytes = bzll_cleanup();
break;
#endif
#if defined(BACDL_BSC)
case DATALINK_BSC:
bsc_cleanup();
@@ -290,6 +319,11 @@ void datalink_get_broadcast_address(BACNET_ADDRESS *dest)
dlmstp_get_broadcast_address(dest);
break;
#endif
#if defined(BACDL_ZIGBEE)
case DATALINK_ZIGBEE:
bytes = bzll_get_broadcast_address(dest);
break;
#endif
#if defined(BACDL_BSC)
case DATALINK_BSC:
bsc_get_broadcast_address(dest);
@@ -330,6 +364,11 @@ void datalink_get_my_address(BACNET_ADDRESS *my_address)
dlmstp_get_my_address(my_address);
break;
#endif
#if defined(BACDL_ZIGBEE)
case DATALINK_ZIGBEE:
bytes = bzll_get_my_address(my_address);
break;
#endif
#if defined(BACDL_BSC)
case DATALINK_BSC:
bsc_get_my_address(my_address);
@@ -371,6 +410,11 @@ void datalink_set_interface(char *ifname)
(void)ifname;
break;
#endif
#if defined(BACDL_ZIGBEE)
case DATALINK_ZIGBEE:
(void)ifname;
break;
#endif
#if defined(BACDL_BSC)
case DATALINK_BSC:
(void)ifname;
@@ -408,6 +452,11 @@ void datalink_maintenance_timer(uint16_t seconds)
case DATALINK_MSTP:
break;
#endif
#if defined(BACDL_ZIGBEE)
case DATALINK_ZIGBEE:
bzll_maintenance_timer(seconds);
break;
#endif
#if defined(BACDL_BSC)
case DATALINK_BSC:
bsc_maintenance_timer(seconds);
+15 -1
View File
@@ -31,7 +31,9 @@
#include "bacnet/datalink/bvlc6.h"
#include "bacnet/basic/bbmd6/h_bbmd6.h"
#endif
#if defined(BACDL_ZIGBEE)
#include "bacnet/datalink/bzll.h"
#endif
#if defined(BACDL_BSC)
#include "bacnet/datalink/bsc/bsc-conf.h"
#include "bacnet/datalink/bsc/bsc-datalink.h"
@@ -104,6 +106,18 @@ void routed_get_my_address(BACNET_ADDRESS *my_address);
#define datalink_get_my_address bip6_get_my_address
#define datalink_maintenance_timer(s) bvlc6_maintenance_timer(s)
#elif defined(BACDL_ZIGBEE) && !defined(BACDL_MULTIPLE)
/* A BACnet/ZigBee Data Link Layer (BZLL) */
#define MAX_MPDU BZLL_MPDU_MAX
#define datalink_init bzll_init
#define datalink_send_pdu bzll_send_pdu
#define datalink_receive bzll_receive
#define datalink_cleanup bzll_cleanup
#define datalink_get_broadcast_address bzll_get_broadcast_address
#define datalink_get_my_address bzll_get_my_address
#define datalink_maintenance_timer bzll_maintenance_timer
#elif defined(BACDL_BSC) && !defined(BACDL_MULTIPLE)
#define MAX_MPDU BVLC_SC_NPDU_SIZE_CONF
+36
View File
@@ -580,6 +580,34 @@ void dlenv_network_port_bip6_init(uint32_t instance)
Network_Port_Changes_Pending_Set(instance, false);
}
/**
* Datalink network port object settings
*/
void dlenv_network_port_zigbee_init(uint32_t instance)
{
BACNET_ADDRESS addr = { 0 };
char *pEnv = NULL;
pEnv = getenv("BACNET_ZIGBEE_DEBUG");
if (pEnv) {
dlenv_debug_enable();
}
Network_Port_Object_Instance_Number_Set(0, instance);
Network_Port_Name_Set(instance, "BACnet Zigbee Link Layer Port");
Network_Port_Type_Set(instance, PORT_TYPE_ZIGBEE);
addr.mac_len = encode_unsigned24(&addr.mac[0], instance);
Network_Port_MAC_Address_Set(instance, &addr.mac[0], addr.mac_len);
Network_Port_Reliability_Set(instance, RELIABILITY_NO_FAULT_DETECTED);
Network_Port_Link_Speed_Set(instance, 0.0);
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);
/* last thing - clear pending changes - we don't want to set these
since they are already set */
Network_Port_Changes_Pending_Set(instance, false);
}
/**
* @brief Datalink network port object settings
*/
@@ -929,6 +957,9 @@ void dlenv_init(void)
#elif defined(BACDL_ARCNET)
datalink_set("arcnet");
port_type = PORT_TYPE_ARCNET;
#elif defined(BACDL_ZIGBEE)
datalink_set("zigbee");
port_type = PORT_TYPE_ZIGBEE;
#elif defined(BACDL_BSC)
datalink_set("bsc");
port_type = PORT_TYPE_BSC;
@@ -950,6 +981,8 @@ void dlenv_init(void)
port_type = PORT_TYPE_ETHERNET;
#elif defined(BACDL_ARCNET)
port_type = PORT_TYPE_ARCNET;
#elif defined(BACDL_ZIGBEE)
port_type = PORT_TYPE_ZIGBEE;
#elif defined(BACDL_BSC)
port_type = PORT_TYPE_BSC;
#else
@@ -967,6 +1000,9 @@ void dlenv_init(void)
case PORT_TYPE_BIP6:
dlenv_network_port_bip6_init(Network_Port_Instance);
break;
case PORT_TYPE_ZIGBEE:
dlenv_network_port_zigbee_init(Network_Port_Instance);
break;
case PORT_TYPE_BSC:
dlenv_network_port_bsc_init();
bacnet_secure_connect_network_port_init(Network_Port_Instance);