Moved west manifest, zephyr folder, and ports/zephyr folders to another repository bacnet-stack-zephyr (#757)
This commit is contained in:
@@ -1,43 +0,0 @@
|
|||||||
name: Zephyr OS CMake
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- '*'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
container: zephyrprojectrtos/ci:latest
|
|
||||||
env:
|
|
||||||
CMAKE_PREFIX_PATH: /opt/toolchains
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
path: bacnet-stack
|
|
||||||
|
|
||||||
- name: Initialize
|
|
||||||
working-directory: bacnet-stack
|
|
||||||
run: |
|
|
||||||
west init -l .
|
|
||||||
west update
|
|
||||||
|
|
||||||
- name: Twister Tests unit_testing
|
|
||||||
working-directory: bacnet-stack
|
|
||||||
run: |
|
|
||||||
rm -rf twister-out.unit_testing &&
|
|
||||||
../zephyr/scripts/twister -O twister-out.unit_testing -p unit_testing -T zephyr/tests &&
|
|
||||||
for file in CMakeFiles CMakeCache.txt cmake_install.cmake Makefile
|
|
||||||
do
|
|
||||||
find twister-out.unit_testing -name $file -exec rm -rf {} \; || true
|
|
||||||
done
|
|
||||||
|
|
||||||
- name: Archive firmware
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: firmware
|
|
||||||
path: bacnet-stack/twister-out.unit_testing
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
* @brief Port specific configuration for BACnet Stack for Zephyr OS
|
|
||||||
* @author Steve Karg
|
|
||||||
* @date 2024
|
|
||||||
* @section LICENSE
|
|
||||||
*
|
|
||||||
* Copyright (C) 2024 Steve Karg <skarg@users.sourceforge.net>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
#ifndef BACNET_PORTS_ZEPHYR_BACNET_CONFIG_H
|
|
||||||
#define BACNET_PORTS_ZEPHYR_BACNET_CONFIG_H
|
|
||||||
|
|
||||||
#if ! defined BACNET_CONFIG_H || ! BACNET_CONFIG_H
|
|
||||||
#error bacnet-config.h included outside of BACNET_CONFIG_H control
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* provides platform specific define for ARRAY_SIZE */
|
|
||||||
#include <zephyr/sys/util.h>
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright (C) 2012 Steve Karg <skarg@users.sourceforge.net>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*
|
|
||||||
*********************************************************************/
|
|
||||||
#ifndef BITS_H
|
|
||||||
#define BITS_H
|
|
||||||
|
|
||||||
#include <zephyr/sys/util.h> /* defines BIT(n) */
|
|
||||||
|
|
||||||
/********************************************************************
|
|
||||||
* Bit Masks
|
|
||||||
*********************************************************************/
|
|
||||||
#define BIT0 BIT( 0)
|
|
||||||
#define BIT1 BIT( 1)
|
|
||||||
#define BIT2 BIT( 2)
|
|
||||||
#define BIT3 BIT( 3)
|
|
||||||
#define BIT4 BIT( 4)
|
|
||||||
#define BIT5 BIT( 5)
|
|
||||||
#define BIT6 BIT( 6)
|
|
||||||
#define BIT7 BIT( 7)
|
|
||||||
#define BIT8 BIT( 8)
|
|
||||||
#define BIT9 BIT( 9)
|
|
||||||
#define BIT10 BIT(10)
|
|
||||||
#define BIT11 BIT(11)
|
|
||||||
#define BIT12 BIT(12)
|
|
||||||
#define BIT13 BIT(13)
|
|
||||||
#define BIT14 BIT(14)
|
|
||||||
#define BIT15 BIT(15)
|
|
||||||
#define BIT16 BIT(16)
|
|
||||||
#define BIT17 BIT(17)
|
|
||||||
#define BIT18 BIT(18)
|
|
||||||
#define BIT19 BIT(19)
|
|
||||||
#define BIT20 BIT(20)
|
|
||||||
#define BIT21 BIT(21)
|
|
||||||
#define BIT22 BIT(22)
|
|
||||||
#define BIT23 BIT(23)
|
|
||||||
#define BIT24 BIT(24)
|
|
||||||
#define BIT25 BIT(25)
|
|
||||||
#define BIT26 BIT(26)
|
|
||||||
#define BIT27 BIT(27)
|
|
||||||
#define BIT28 BIT(28)
|
|
||||||
#define BIT29 BIT(29)
|
|
||||||
#define BIT30 BIT(30)
|
|
||||||
#define BIT31 BIT(31)
|
|
||||||
|
|
||||||
/* a=register, b=bit number to act upon 0-n */
|
|
||||||
#define BIT_SET(a,b) ((a) |= (1<<(b)))
|
|
||||||
#define BIT_CLEAR(a,b) ((a) &= ~(1<<(b)))
|
|
||||||
#define BIT_FLIP(a,b) ((a) ^= (1<<(b)))
|
|
||||||
#define BIT_CHECK(a,b) ((a) & (1<<(b)))
|
|
||||||
|
|
||||||
/* x=target variable, y=mask */
|
|
||||||
#define BITMASK_SET(x,y) ((x) |= (y))
|
|
||||||
#define BITMASK_CLEAR(x,y) ((x) &= (~(y)))
|
|
||||||
#define BITMASK_FLIP(x,y) ((x) ^= (y))
|
|
||||||
#define BITMASK_CHECK(x,y) (((x) & (y)) == (y))
|
|
||||||
|
|
||||||
#ifndef _BV
|
|
||||||
#define _BV(x) (1<<(x))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright (C) 2012 Steve Karg <skarg@users.sourceforge.net>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*
|
|
||||||
*********************************************************************/
|
|
||||||
#ifndef ETHERNET_H
|
|
||||||
#define ETHERNET_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"
|
|
||||||
|
|
||||||
/* specific defines for Ethernet */
|
|
||||||
#define ETHERNET_HEADER_MAX (6+6+2+1+1+1)
|
|
||||||
#define ETHERNET_MPDU_MAX (ETHERNET_HEADER_MAX+MAX_PDU)
|
|
||||||
|
|
||||||
/* Unless we explicitly need these remaps to be NOT exposed
|
|
||||||
* (e.g. implementation where we need both bacnet and Zephyr symbols),
|
|
||||||
* replace the BACnet Ethernet API symbols with non-conflicting ones.
|
|
||||||
*/
|
|
||||||
#if !defined(BACNET_ETHERNET_NO_REMAP_DEFINES)
|
|
||||||
#define ethernet_valid bacnet_ethernet_valid
|
|
||||||
#define ethernet_cleanup bacnet_ethernet_cleanup
|
|
||||||
#define ethernet_init bacnet_ethernet_init
|
|
||||||
#define ethernet_send_pdu bacnet_ethernet_send_pdu
|
|
||||||
#define ethernet_receive bacnet_ethernet_receive
|
|
||||||
#define ethernet_set_my_address bacnet_ethernet_set_my_address
|
|
||||||
#define ethernet_get_my_address bacnet_ethernet_get_my_address
|
|
||||||
#define ethernet_get_broadcast_address bacnet_ethernet_get_broadcast_address
|
|
||||||
#define ethernet_debug_address bacnet_ethernet_debug_address
|
|
||||||
#define ethernet_send bacnet_ethernet_send
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
BACNET_STACK_EXPORT
|
|
||||||
bool bacnet_ethernet_valid(
|
|
||||||
void);
|
|
||||||
BACNET_STACK_EXPORT
|
|
||||||
void bacnet_ethernet_cleanup(
|
|
||||||
void);
|
|
||||||
BACNET_STACK_EXPORT
|
|
||||||
bool bacnet_ethernet_init(
|
|
||||||
char *interface_name);
|
|
||||||
|
|
||||||
/* function to send a packet out the 802.2 socket */
|
|
||||||
/* returns number of bytes sent on success, negative on failure */
|
|
||||||
BACNET_STACK_EXPORT
|
|
||||||
int bacnet_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); /* number of bytes of data */
|
|
||||||
|
|
||||||
/* receives an 802.2 framed packet */
|
|
||||||
/* returns the number of octets in the PDU, or zero on failure */
|
|
||||||
BACNET_STACK_EXPORT
|
|
||||||
uint16_t bacnet_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); /* milliseconds to wait for a packet */
|
|
||||||
|
|
||||||
BACNET_STACK_EXPORT
|
|
||||||
void bacnet_ethernet_set_my_address(
|
|
||||||
const BACNET_ADDRESS * my_address);
|
|
||||||
BACNET_STACK_EXPORT
|
|
||||||
void bacnet_ethernet_get_my_address(
|
|
||||||
BACNET_ADDRESS * my_address);
|
|
||||||
BACNET_STACK_EXPORT
|
|
||||||
void bacnet_ethernet_get_broadcast_address(
|
|
||||||
BACNET_ADDRESS * dest); /* destination address */
|
|
||||||
|
|
||||||
/* some functions from Linux driver */
|
|
||||||
BACNET_STACK_EXPORT
|
|
||||||
void bacnet_ethernet_debug_address(
|
|
||||||
const char *info,
|
|
||||||
BACNET_ADDRESS * dest);
|
|
||||||
BACNET_STACK_EXPORT
|
|
||||||
int bacnet_ethernet_send(
|
|
||||||
uint8_t * mtu,
|
|
||||||
int mtu_len);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
#endif
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020 Legrand North America, LLC.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*
|
|
||||||
*********************************************************************/
|
|
||||||
|
|
||||||
#ifndef NET_H
|
|
||||||
#define NET_H
|
|
||||||
|
|
||||||
#include <zephyr/net/net_ip.h>
|
|
||||||
#include <zephyr/net/socket.h>
|
|
||||||
#include <zephyr/kernel.h>
|
|
||||||
/* BACnet Stack defines - first */
|
|
||||||
#include "bacnet/bacdef.h"
|
|
||||||
/* BACnet Stack API */
|
|
||||||
#include "bacnet/basic/object/device.h"
|
|
||||||
|
|
||||||
static inline char *inet_ntoa(struct in_addr in) {
|
|
||||||
return "(inet_ntoa() to be implemented)";
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Local helper functions for this port */
|
|
||||||
extern int bip_get_local_netmask(
|
|
||||||
struct in_addr *netmask);
|
|
||||||
|
|
||||||
#ifdef CONFIG_BACNET_USE_SECTION_ITERABLE_OBJECT_TABLE
|
|
||||||
|
|
||||||
#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) \
|
|
||||||
STRUCT_SECTION_ITERABLE(object_functions, table_name) = { \
|
|
||||||
.Object_Type = _type, \
|
|
||||||
.Object_Init = _init, \
|
|
||||||
.Object_Count = _count, \
|
|
||||||
.Object_Index_To_Instance = _index_to_instance, \
|
|
||||||
.Object_Valid_Instance = _valid_instance, \
|
|
||||||
.Object_Name = _object_name, \
|
|
||||||
.Object_Read_Property = _read_property, \
|
|
||||||
.Object_Write_Property = _write_property, \
|
|
||||||
.Object_RPM_List = _RPM_list, \
|
|
||||||
.Object_RR_Info = _RR_info, \
|
|
||||||
.Object_Iterator = _iterator, \
|
|
||||||
.Object_Value_List = _value_list, \
|
|
||||||
.Object_COV = _COV, \
|
|
||||||
.Object_COV_Clear = _COV_clear, \
|
|
||||||
.Object_Intrinsic_Reporting = _intrinsic_reporting \
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#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) \
|
|
||||||
while{}(0)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,613 +0,0 @@
|
|||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright (C) 2005 Steve Karg
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-or-later WITH GCC-exception-2.0
|
|
||||||
*
|
|
||||||
*********************************************************************/
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <zephyr/device.h>
|
|
||||||
#include <zephyr/init.h>
|
|
||||||
#include <zephyr/kernel.h>
|
|
||||||
#include <zephyr/sys/printk.h>
|
|
||||||
#include <zephyr/net/net_ip.h>
|
|
||||||
#include <zephyr/net/socket.h>
|
|
||||||
#include <zephyr/net/socket_select.h>
|
|
||||||
/* BACnet Stack defines - first */
|
|
||||||
#include "bacnet/bacdef.h"
|
|
||||||
/* BACnet Stack API */
|
|
||||||
#include "bacnet/bacdcode.h"
|
|
||||||
#include "bacnet/bacint.h"
|
|
||||||
#include "bacnet/datalink/bip.h"
|
|
||||||
#include "bacnet/basic/sys/debug.h"
|
|
||||||
#include "bacnet/basic/bbmd/h_bbmd.h"
|
|
||||||
|
|
||||||
/* Logging module registration is already done in ports/zephyr/main.c */
|
|
||||||
#include <zephyr/logging/log.h>
|
|
||||||
#include <zephyr/logging/log_ctrl.h>
|
|
||||||
|
|
||||||
LOG_MODULE_DECLARE(bacnet, CONFIG_BACNETSTACK_LOG_LEVEL);
|
|
||||||
|
|
||||||
#define THIS_FILE "bip-init.c"
|
|
||||||
|
|
||||||
/* zephyr sockets */
|
|
||||||
static int BIP_Socket = -1;
|
|
||||||
static int BIP_Broadcast_Socket = -1;
|
|
||||||
|
|
||||||
/* NOTE: we store address and port in network byte order
|
|
||||||
since BACnet/IP uses network byte order for all address byte arrays
|
|
||||||
*/
|
|
||||||
/* port to use - stored here in network byte order */
|
|
||||||
static uint16_t BIP_Port = htons(CONFIG_BACDL_BIP_PORT);
|
|
||||||
/* IP address - stored here in network byte order */
|
|
||||||
static struct in_addr BIP_Address;
|
|
||||||
/* IP broadcast address - stored here in network byte order */
|
|
||||||
static struct in_addr BIP_Broadcast_Addr;
|
|
||||||
|
|
||||||
/* Used by inet_ntoa */
|
|
||||||
#if CONFIG_BACNETSTACK_LOG_LEVEL
|
|
||||||
static char ipv4_addr_str[16] = { 0 };
|
|
||||||
#else
|
|
||||||
static char ipv4_addr_str[] = "";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Return a string representation of an IPv4 address
|
|
||||||
* @param a - IPv4 address
|
|
||||||
* @return Pointer to global string
|
|
||||||
*/
|
|
||||||
char *inet_ntoa(struct in_addr *a)
|
|
||||||
{
|
|
||||||
if (IS_ENABLED(CONFIG_BACNETSTACK_LOG_LEVEL)) {
|
|
||||||
snprintf(ipv4_addr_str, sizeof(ipv4_addr_str), "%d.%d.%d.%d",
|
|
||||||
a->s4_addr[0], a->s4_addr[1], a->s4_addr[2], a->s4_addr[3]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return &ipv4_addr_str[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Print the IPv4 address with debug info
|
|
||||||
* @param str - debug info string
|
|
||||||
* @param addr - IPv4 address
|
|
||||||
*/
|
|
||||||
static void debug_print_ipv4(const char *str,
|
|
||||||
const struct in_addr *addr,
|
|
||||||
const unsigned int port,
|
|
||||||
const unsigned int count)
|
|
||||||
{
|
|
||||||
LOG_DBG("%s %s:%hu (%u bytes)", str, inet_ntoa((struct in_addr *)&addr),
|
|
||||||
ntohs(port), count);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Set the BACnet IPv4 UDP port number
|
|
||||||
* @param port - IPv4 UDP port number - in host byte order
|
|
||||||
*/
|
|
||||||
void bip_set_port(uint16_t port)
|
|
||||||
{
|
|
||||||
BIP_Port = htons(port);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get the BACnet IPv4 UDP port number
|
|
||||||
* @return IPv4 UDP port number - in host byte order
|
|
||||||
*/
|
|
||||||
uint16_t bip_get_port(void)
|
|
||||||
{
|
|
||||||
return ntohs(BIP_Port);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get the IPv4 address for my interface. Used for sending src address.
|
|
||||||
* @param addr - BACnet datalink address
|
|
||||||
*/
|
|
||||||
void bip_get_my_address(BACNET_ADDRESS *addr)
|
|
||||||
{
|
|
||||||
unsigned int i = 0;
|
|
||||||
|
|
||||||
if (addr) {
|
|
||||||
addr->mac_len = BIP_ADDRESS_MAX; /* 6 */
|
|
||||||
memcpy(&addr->mac[0], &BIP_Address.s_addr, IP_ADDRESS_MAX); /* 4 */
|
|
||||||
memcpy(&addr->mac[IP_ADDRESS_MAX], &BIP_Port, sizeof(BIP_Port));
|
|
||||||
/* local only, no routing */
|
|
||||||
addr->net = 0;
|
|
||||||
/* no SLEN */
|
|
||||||
addr->len = 0;
|
|
||||||
for (i = 0; i < MAX_MAC_LEN; i++) {
|
|
||||||
/* no SADR */
|
|
||||||
addr->adr[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the IPv4 broadcast address for my interface.
|
|
||||||
*
|
|
||||||
* @param addr - BACnet datalink address
|
|
||||||
*/
|
|
||||||
|
|
||||||
void bip_get_broadcast_address(BACNET_ADDRESS *dest)
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
if (dest) {
|
|
||||||
dest->mac_len = BIP_ADDRESS_MAX;
|
|
||||||
memcpy(&dest->mac[0], &BIP_Broadcast_Addr.s_addr, IP_ADDRESS_MAX);
|
|
||||||
memcpy(&dest->mac[IP_ADDRESS_MAX], &BIP_Port, sizeof(BIP_Port));
|
|
||||||
dest->net = BACNET_BROADCAST_NETWORK;
|
|
||||||
dest->len = 0;
|
|
||||||
for (i = 0; i < MAX_MAC_LEN; i++) {
|
|
||||||
dest->adr[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Set the BACnet/IP address
|
|
||||||
* @param addr - network IPv4 address
|
|
||||||
* @return true if the address was set
|
|
||||||
*/
|
|
||||||
bool bip_set_addr(const BACNET_IP_ADDRESS *addr)
|
|
||||||
{
|
|
||||||
if (addr) {
|
|
||||||
memcpy(&BIP_Address.s_addr, &addr->address[0], IP_ADDRESS_MAX);
|
|
||||||
BIP_Port = htons(addr->port);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get the BACnet/IP address
|
|
||||||
* @param addr - network IPv4 address (in network byte order)
|
|
||||||
* @return true if the address was retrieved
|
|
||||||
*/
|
|
||||||
bool bip_get_addr(BACNET_IP_ADDRESS *addr)
|
|
||||||
{
|
|
||||||
if (addr) {
|
|
||||||
memcpy(&addr->address[0], &BIP_Address.s_addr, IP_ADDRESS_MAX);
|
|
||||||
addr->port = ntohs(BIP_Port);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Set the BACnet/IP address
|
|
||||||
* @param addr - network IPv4 address
|
|
||||||
* @return true if the address was set
|
|
||||||
*/
|
|
||||||
bool bip_set_broadcast_addr(const BACNET_IP_ADDRESS *addr)
|
|
||||||
{
|
|
||||||
if (addr) {
|
|
||||||
memcpy(&BIP_Broadcast_Addr.s_addr, &addr->address[0], IP_ADDRESS_MAX);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the BACnet/IP address
|
|
||||||
*
|
|
||||||
* @return BACnet/IP address
|
|
||||||
*/
|
|
||||||
bool bip_get_broadcast_addr(BACNET_IP_ADDRESS *addr)
|
|
||||||
{
|
|
||||||
if (addr) {
|
|
||||||
memcpy(&addr->address[0], &BIP_Broadcast_Addr.s_addr, IP_ADDRESS_MAX);
|
|
||||||
addr->port = ntohs(BIP_Port);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Set the BACnet/IP subnet mask CIDR prefix
|
|
||||||
* @return true if the subnet mask CIDR prefix is set
|
|
||||||
*/
|
|
||||||
bool bip_set_subnet_prefix(uint8_t prefix)
|
|
||||||
{
|
|
||||||
/* not something we do within this driver */
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get the BACnet/IP subnet mask CIDR prefix
|
|
||||||
* @return subnet mask CIDR prefix 1..32
|
|
||||||
*/
|
|
||||||
uint8_t bip_get_subnet_prefix(void)
|
|
||||||
{
|
|
||||||
uint32_t address = 0;
|
|
||||||
uint32_t broadcast = 0;
|
|
||||||
uint32_t mask = 0xFFFFFFFE;
|
|
||||||
uint8_t prefix = 0;
|
|
||||||
|
|
||||||
address = BIP_Address.s_addr;
|
|
||||||
broadcast = BIP_Broadcast_Addr.s_addr;
|
|
||||||
/* calculate the subnet prefix from the broadcast address */
|
|
||||||
for (prefix = 1; prefix <= 32; prefix++) {
|
|
||||||
if ((address | mask) == broadcast) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
mask = mask << 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return prefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The send function for BACnet/IP driver layer
|
|
||||||
*
|
|
||||||
* @param dest - Points to a BACNET_IP_ADDRESS structure containing the
|
|
||||||
* destination address.
|
|
||||||
* @param mtu - the bytes of data to send
|
|
||||||
* @param mtu_len - the number of bytes of data to send
|
|
||||||
*
|
|
||||||
* @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_mpdu(
|
|
||||||
const BACNET_IP_ADDRESS *dest, const uint8_t *mtu, uint16_t mtu_len)
|
|
||||||
{
|
|
||||||
struct sockaddr_in bip_dest = { 0 };
|
|
||||||
|
|
||||||
/* assumes that the driver has already been initialized */
|
|
||||||
if (BIP_Socket < 0) {
|
|
||||||
LOG_ERR("%s:%d - Socket not initialized!", THIS_FILE, __LINE__);
|
|
||||||
return BIP_Socket;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* load destination IP address */
|
|
||||||
bip_dest.sin_family = AF_INET;
|
|
||||||
memcpy(&bip_dest.sin_addr.s_addr, &dest->address[0], IP_ADDRESS_MAX);
|
|
||||||
bip_dest.sin_port = htons(dest->port);
|
|
||||||
|
|
||||||
/* Send the packet */
|
|
||||||
debug_print_ipv4(
|
|
||||||
"Sending MPDU->", &bip_dest.sin_addr, bip_dest.sin_port, mtu_len);
|
|
||||||
return zsock_sendto(BIP_Socket, (const char *)mtu, mtu_len, 0,
|
|
||||||
(struct sockaddr *)&bip_dest, sizeof(struct sockaddr));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* BACnet/IP Datalink Receive handler.
|
|
||||||
*
|
|
||||||
* @param src - returns the source address
|
|
||||||
* @param npdu - returns the NPDU buffer
|
|
||||||
* @param max_npdu -maximum size of the NPDU buffer
|
|
||||||
* @param timeout - number of milliseconds to wait for a packet
|
|
||||||
*
|
|
||||||
* @return Number of bytes received, or 0 if none or timeout.
|
|
||||||
*/
|
|
||||||
uint16_t bip_receive(
|
|
||||||
BACNET_ADDRESS *src, uint8_t *npdu, uint16_t max_npdu, unsigned timeout)
|
|
||||||
{
|
|
||||||
uint16_t npdu_len = 0; /* return value */
|
|
||||||
zsock_fd_set read_fds;
|
|
||||||
int max = 0;
|
|
||||||
struct zsock_timeval select_timeout;
|
|
||||||
struct sockaddr_in sin = { 0 };
|
|
||||||
BACNET_IP_ADDRESS addr = { 0 };
|
|
||||||
socklen_t sin_len = sizeof(sin);
|
|
||||||
int received_bytes = 0;
|
|
||||||
int offset = 0;
|
|
||||||
uint16_t i = 0;
|
|
||||||
int socket;
|
|
||||||
|
|
||||||
/* Make sure the socket is open */
|
|
||||||
if (BIP_Socket < 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
|
|
||||||
a select. */
|
|
||||||
if (timeout >= 1000) {
|
|
||||||
select_timeout.tv_sec = timeout / 1000;
|
|
||||||
select_timeout.tv_usec =
|
|
||||||
1000 * (timeout - select_timeout.tv_sec * 1000);
|
|
||||||
} else {
|
|
||||||
select_timeout.tv_sec = 0;
|
|
||||||
select_timeout.tv_usec = 1000 * timeout;
|
|
||||||
}
|
|
||||||
ZSOCK_FD_ZERO(&read_fds);
|
|
||||||
ZSOCK_FD_SET(BIP_Socket, &read_fds);
|
|
||||||
ZSOCK_FD_SET(BIP_Broadcast_Socket, &read_fds);
|
|
||||||
|
|
||||||
max = BIP_Socket > BIP_Broadcast_Socket ? BIP_Socket : BIP_Broadcast_Socket;
|
|
||||||
|
|
||||||
/* see if there is a packet for us */
|
|
||||||
if (zsock_select(max + 1, &read_fds, NULL, NULL, &select_timeout) > 0) {
|
|
||||||
socket =
|
|
||||||
FD_ISSET(BIP_Socket, &read_fds) ? BIP_Socket : BIP_Broadcast_Socket;
|
|
||||||
received_bytes = zsock_recvfrom(socket, (char *)&npdu[0], max_npdu, 0,
|
|
||||||
(struct sockaddr *)&sin, &sin_len);
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* See if there is a problem */
|
|
||||||
if (received_bytes < 0) {
|
|
||||||
LOG_WRN("%s:%d - RX zsock_recvfrom() error: %d", THIS_FILE, __LINE__,
|
|
||||||
received_bytes);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/* no problem, just no bytes */
|
|
||||||
if (received_bytes == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/* the signature of a BACnet/IP packet */
|
|
||||||
if (npdu[0] != BVLL_TYPE_BACNET_IP) {
|
|
||||||
LOG_WRN("%s:%d - RX bad packet", THIS_FILE, __LINE__);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Data link layer addressing between B/IPv4 nodes consists of a 32-bit
|
|
||||||
IPv4 address followed by a two-octet UDP port number (both of which
|
|
||||||
shall be transmitted with the most significant octet first). This
|
|
||||||
address shall be referred to as a B/IPv4 address.
|
|
||||||
*/
|
|
||||||
|
|
||||||
memcpy(&addr.address[0], &sin.sin_addr.s_addr, IP_ADDRESS_MAX);
|
|
||||||
addr.port = ntohs(sin.sin_port);
|
|
||||||
|
|
||||||
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);
|
|
||||||
if (offset > 0) {
|
|
||||||
npdu_len = received_bytes - offset;
|
|
||||||
debug_print_ipv4(
|
|
||||||
"Received NPDU->", &sin.sin_addr, sin.sin_port, npdu_len);
|
|
||||||
if (npdu_len <= max_npdu) {
|
|
||||||
/* shift the buffer to return a valid NPDU */
|
|
||||||
for (i = 0; i < npdu_len; i++) {
|
|
||||||
npdu[i] = npdu[offset + i];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
LOG_WRN("%s:%d - NPDU dropped!", THIS_FILE, __LINE__);
|
|
||||||
npdu_len = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return npdu_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The common send function for BACnet/IP application layer
|
|
||||||
*
|
|
||||||
* @param dest - Points to a #BACNET_ADDRESS structure containing the
|
|
||||||
* destination address.
|
|
||||||
* @param npdu_data - Points to a BACNET_NPDU_DATA structure containing the
|
|
||||||
* destination network layer control flags and data.
|
|
||||||
* @param mtu - the bytes of data to send
|
|
||||||
* @param mtu_len - the number of bytes of data to send
|
|
||||||
* @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,
|
|
||||||
BACNET_NPDU_DATA *npdu_data,
|
|
||||||
uint8_t *pdu,
|
|
||||||
unsigned pdu_len)
|
|
||||||
{
|
|
||||||
dest->net = BACNET_BROADCAST_NETWORK;
|
|
||||||
return bvlc_send_pdu(dest, npdu_data, pdu, pdu_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Gets the local IP address and local broadcast address from the system,
|
|
||||||
* and saves it into the BACnet/IP data structures.
|
|
||||||
*
|
|
||||||
* @param ifname [in] The named interface to use for the network layer.
|
|
||||||
* Eg, for Linux, ifname is eth0, ath0, arc0, and others.
|
|
||||||
*/
|
|
||||||
void bip_set_interface(const char *ifname)
|
|
||||||
{
|
|
||||||
struct net_if *iface = 0;
|
|
||||||
int index = -1;
|
|
||||||
uint8_t x = 0;
|
|
||||||
BACNET_IP_ADDRESS unicast = { 0 };
|
|
||||||
BACNET_IP_ADDRESS broadcast = { 0 };
|
|
||||||
|
|
||||||
/* Network byte order */
|
|
||||||
unicast.port = ntohs(BIP_Port);
|
|
||||||
broadcast.port = ntohs(BIP_Port);
|
|
||||||
LOG_INF("bip_set_interface()");
|
|
||||||
LOG_INF("UDP port: %d", unicast.port);
|
|
||||||
if (ifname) {
|
|
||||||
index = atoi(ifname);
|
|
||||||
/* if index is zero, discern between "0" and a parse error */
|
|
||||||
if (!index && strcmp(ifname, "0")) {
|
|
||||||
LOG_ERR("%s:%d - Argument must parse to an integer", THIS_FILE,
|
|
||||||
__LINE__);
|
|
||||||
} else {
|
|
||||||
iface = net_if_get_by_index(index);
|
|
||||||
if (iface) {
|
|
||||||
LOG_INF("Using iface %d", index);
|
|
||||||
} else {
|
|
||||||
LOG_ERR(
|
|
||||||
"%s:%d - No iface at index %d", THIS_FILE, __LINE__, index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (index == -1) {
|
|
||||||
LOG_WRN("%s:%d - No valid interface specified - using default ",
|
|
||||||
THIS_FILE, __LINE__);
|
|
||||||
iface = net_if_get_default();
|
|
||||||
}
|
|
||||||
if (iface) {
|
|
||||||
LOG_INF("Interface set.");
|
|
||||||
#if defined(CONFIG_BACDL_BIP_ADDRESS_INDEX)
|
|
||||||
LOG_INF("Config unicast address %d/%d",
|
|
||||||
CONFIG_BACDL_BIP_ADDRESS_INDEX, NET_IF_MAX_IPV4_ADDR);
|
|
||||||
index = CONFIG_BACDL_BIP_ADDRESS_INDEX;
|
|
||||||
#else
|
|
||||||
int i;
|
|
||||||
char hr_addr[NET_IPV4_ADDR_LEN];
|
|
||||||
index = 0;
|
|
||||||
for (i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) {
|
|
||||||
struct net_if_addr *if_addr = &iface->config.ip.ipv4->unicast[i];
|
|
||||||
|
|
||||||
if (!if_addr->is_used) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
index = i;
|
|
||||||
LOG_INF("IPv4 address: %s",
|
|
||||||
net_addr_ntop(AF_INET, &if_addr->address.in_addr, hr_addr,
|
|
||||||
NET_IPV4_ADDR_LEN));
|
|
||||||
LOG_INF("Subnet: %s",
|
|
||||||
net_addr_ntop(AF_INET, &iface->config.ip.ipv4->netmask, hr_addr,
|
|
||||||
NET_IPV4_ADDR_LEN));
|
|
||||||
LOG_INF("Router: %s",
|
|
||||||
net_addr_ntop(AF_INET, &iface->config.ip.ipv4->gw, hr_addr,
|
|
||||||
NET_IPV4_ADDR_LEN));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (index >= NET_IF_MAX_IPV4_ADDR) {
|
|
||||||
LOG_ERR("%s:%d - IPv4 address index of %d is out of range (0-%d)",
|
|
||||||
THIS_FILE, __LINE__, index, NET_IF_MAX_IPV4_ADDR - 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
LOG_INF("Using IPv4 address at index %d", index);
|
|
||||||
/* Build the broadcast address from the unicast and netmask */
|
|
||||||
struct net_if_addr *if_addr = &iface->config.ip.ipv4->unicast[index];
|
|
||||||
for (x = 0; x < IP_ADDRESS_MAX; x++) {
|
|
||||||
unicast.address[x] = if_addr->address.in_addr.s4_addr[x];
|
|
||||||
broadcast.address[x] = if_addr->address.in_addr.s4_addr[x] |
|
|
||||||
~iface->config.ip.ipv4->netmask.s4_addr[x];
|
|
||||||
}
|
|
||||||
bip_set_addr(&unicast);
|
|
||||||
bip_set_broadcast_addr(&broadcast);
|
|
||||||
LOG_INF("BACnet/IP Unicast: %u.%u.%u.%u:%d", unicast.address[0],
|
|
||||||
unicast.address[1], unicast.address[2], unicast.address[3],
|
|
||||||
unicast.port);
|
|
||||||
LOG_INF("BACnet/IP Broadcast: %u.%u.%u.%u", broadcast.address[0],
|
|
||||||
broadcast.address[1], broadcast.address[2], broadcast.address[3]);
|
|
||||||
} else {
|
|
||||||
LOG_ERR("%s:%d - Failed to set iface", THIS_FILE, __LINE__);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int createSocket(const struct sockaddr_in *sin)
|
|
||||||
{
|
|
||||||
int sock_fd = -1;
|
|
||||||
const int sockopt = 1;
|
|
||||||
int status = -1;
|
|
||||||
|
|
||||||
/* assumes that the driver has already been initialized */
|
|
||||||
sock_fd = zsock_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
|
||||||
if (sock_fd < 0) {
|
|
||||||
LOG_ERR("%s:%d - Failed to create socket", THIS_FILE, __LINE__);
|
|
||||||
return sock_fd;
|
|
||||||
} else {
|
|
||||||
LOG_DBG("Socket created");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allow us to use the same socket for sending and receiving */
|
|
||||||
/* This makes sure that the src port is correct when sending */
|
|
||||||
status = zsock_setsockopt(
|
|
||||||
sock_fd, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof(sockopt));
|
|
||||||
if (status < 0) {
|
|
||||||
zsock_close(sock_fd);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* bind the socket to the local port number and IP address */
|
|
||||||
status = zsock_bind(
|
|
||||||
sock_fd, (const struct sockaddr *)sin, sizeof(struct sockaddr));
|
|
||||||
if (status < 0) {
|
|
||||||
zsock_close(sock_fd);
|
|
||||||
LOG_ERR("%s:%d - zsock_bind() failure", THIS_FILE, __LINE__);
|
|
||||||
return status;
|
|
||||||
} else {
|
|
||||||
LOG_DBG("Socket bound");
|
|
||||||
}
|
|
||||||
|
|
||||||
return sock_fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Initialize the BACnet/IP services at the given interface.
|
|
||||||
* @ingroup DLBIP
|
|
||||||
* -# Gets the local IP address and local broadcast address from the system,
|
|
||||||
* and saves it into the BACnet/IP data structures.
|
|
||||||
* -# Opens a UDP socket
|
|
||||||
* -# Configures the socket for sending and receiving
|
|
||||||
* -# Configures the socket so it can send broadcasts
|
|
||||||
* -# Binds the socket to the local IP address at the specified port for
|
|
||||||
* BACnet/IP (by default, 0xBAC0 = 47808).
|
|
||||||
*
|
|
||||||
* @note For Zephyr, ifname is the index number of the interface as a string.
|
|
||||||
*
|
|
||||||
* @param ifname [in] The named interface to use for the network layer.
|
|
||||||
* If NULL, the default interface is assigned.
|
|
||||||
* @return True if the socket is successfully opened for BACnet/IP,
|
|
||||||
* else False if the socket functions fail.
|
|
||||||
*/
|
|
||||||
bool bip_init(char *ifname)
|
|
||||||
{
|
|
||||||
int sock_fd;
|
|
||||||
struct sockaddr_in sin = { 0 };
|
|
||||||
|
|
||||||
bip_set_interface(ifname);
|
|
||||||
|
|
||||||
if (BIP_Address.s_addr == 0) {
|
|
||||||
LOG_ERR("%s:%d - Failed to get an IP address on interface: %s\n",
|
|
||||||
THIS_FILE, __LINE__, ifname ? ifname : "[default]");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* bind the socket to the local port number and IP address */
|
|
||||||
sin.sin_family = AF_INET;
|
|
||||||
sin.sin_port = BIP_Port;
|
|
||||||
|
|
||||||
sin.sin_addr.s_addr = BIP_Address.s_addr;
|
|
||||||
sock_fd = createSocket(&sin);
|
|
||||||
BIP_Socket = sock_fd;
|
|
||||||
if (sock_fd < 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
sin.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
||||||
sock_fd = createSocket(&sin);
|
|
||||||
BIP_Broadcast_Socket = sock_fd;
|
|
||||||
if (sock_fd < 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bvlc_init();
|
|
||||||
|
|
||||||
LOG_DBG("bip_init() success");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Determine if this BACnet/IP datalink is valid
|
|
||||||
* @return true if the BACnet/IP datalink is valid
|
|
||||||
*/
|
|
||||||
bool bip_valid(void)
|
|
||||||
{
|
|
||||||
return (BIP_Socket != -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Cleanup and close out the BACnet/IP services by closing the socket.
|
|
||||||
* @ingroup DLBIP
|
|
||||||
*/
|
|
||||||
void bip_cleanup(void)
|
|
||||||
{
|
|
||||||
LOG_DBG("bip_cleanup()");
|
|
||||||
|
|
||||||
memset(&BIP_Address, 0, sizeof(BIP_Address));
|
|
||||||
memset(&BIP_Broadcast_Addr, 0, sizeof(BIP_Broadcast_Addr));
|
|
||||||
|
|
||||||
if (BIP_Socket != -1) {
|
|
||||||
zsock_close(BIP_Socket);
|
|
||||||
}
|
|
||||||
BIP_Socket = -1;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
@@ -1,578 +0,0 @@
|
|||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright (C) 2005-2020 Steve Karg
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-or-later WITH GCC-exception-2.0
|
|
||||||
*
|
|
||||||
*********************************************************************/
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <zephyr/device.h>
|
|
||||||
#include <zephyr/init.h>
|
|
||||||
#include <zephyr/kernel.h>
|
|
||||||
#include <zephyr/sys/printk.h>
|
|
||||||
#include <zephyr/net/net_ip.h>
|
|
||||||
#include <zephyr/net/socket.h>
|
|
||||||
#include <zephyr/net/socket_select.h>
|
|
||||||
/* BACnet Stack defines - first */
|
|
||||||
#include "bacnet/bacdef.h"
|
|
||||||
/* BACnet Stack API */
|
|
||||||
#include "bacnet/bacdcode.h"
|
|
||||||
#include "bacnet/bacint.h"
|
|
||||||
#include "bacnet/datalink/bip6.h"
|
|
||||||
#include "bacnet/basic/object/device.h"
|
|
||||||
#include "bacnet/basic/sys/debug.h"
|
|
||||||
#include "bacnet/basic/bbmd6/h_bbmd6.h"
|
|
||||||
|
|
||||||
/* Logging module registration is already done in ports/zephyr/main.c */
|
|
||||||
#include <zephyr/logging/log.h>
|
|
||||||
#include <zephyr/logging/log_ctrl.h>
|
|
||||||
|
|
||||||
LOG_MODULE_DECLARE(bacnet, CONFIG_BACNETSTACK_LOG_LEVEL);
|
|
||||||
|
|
||||||
#define THIS_FILE "bip6-init.c"
|
|
||||||
|
|
||||||
/* zephyr socket */
|
|
||||||
static int BIP6_Socket = -1;
|
|
||||||
static int BIP6_Socket_Scope_Id;
|
|
||||||
/* local address - filled by init functions */
|
|
||||||
static BACNET_IP6_ADDRESS BIP6_Addr;
|
|
||||||
static BACNET_IP6_ADDRESS BIP6_Broadcast_Addr;
|
|
||||||
|
|
||||||
/* Used by inet6_ntoa */
|
|
||||||
#if CONFIG_BACNETSTACK_LOG_LEVEL
|
|
||||||
static char ipv6_addr_str[42] = { 0 };
|
|
||||||
#else
|
|
||||||
static char ipv6_addr_str[] = "";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Return a string representation of an IPv6 address
|
|
||||||
* @param a - IPv6 address
|
|
||||||
* @return Pointer to global string
|
|
||||||
*/
|
|
||||||
static char *inet6_ntoa(const struct in6_addr *a)
|
|
||||||
{
|
|
||||||
#if CONFIG_BACNETSTACK_LOG_LEVEL
|
|
||||||
uint8_t x = 0;
|
|
||||||
uint8_t d = 0;
|
|
||||||
uint8_t non_zero_count = 0;
|
|
||||||
|
|
||||||
/* Avoid overwhelming the logging system */
|
|
||||||
while (log_buffered_cnt()) {
|
|
||||||
k_sleep(K_MSEC(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (x = 0; x < IP6_ADDRESS_MAX; x += 2) {
|
|
||||||
if (a->s6_addr[x] | a->s6_addr[x + 1]) {
|
|
||||||
non_zero_count++;
|
|
||||||
d += snprintf(
|
|
||||||
&ipv6_addr_str[d], sizeof(ipv6_addr_str), "%02X%02X",
|
|
||||||
a->s6_addr[x], a->s6_addr[x + 1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (x < 14) {
|
|
||||||
d += snprintf(&ipv6_addr_str[d], sizeof(ipv6_addr_str), ":");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!non_zero_count) {
|
|
||||||
snprintf(&ipv6_addr_str[0], sizeof(ipv6_addr_str), "undefined");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return &ipv6_addr_str[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
void bip6_set_interface(char *ifname)
|
|
||||||
{
|
|
||||||
struct net_if *interface = 0;
|
|
||||||
int index = -1;
|
|
||||||
int x = 0;
|
|
||||||
|
|
||||||
BACNET_IP6_ADDRESS unicast = { 0 };
|
|
||||||
BACNET_IP6_ADDRESS multicast = { 0 };
|
|
||||||
|
|
||||||
unicast.port = bip6_get_port();
|
|
||||||
multicast.port = unicast.port;
|
|
||||||
|
|
||||||
LOG_DBG("bip6_set_interface()");
|
|
||||||
LOG_INF("BIP6: UDP port: 0x%04X", (unsigned)unicast.port);
|
|
||||||
LOG_INF("BIP6: seeking interface: %s", ifname?ifname:"NULL");
|
|
||||||
if (ifname) {
|
|
||||||
index = atoi(ifname);
|
|
||||||
|
|
||||||
/* if index is zero, discern between "0" and a parse error */
|
|
||||||
if (!index && strcmp(ifname, "0")) {
|
|
||||||
LOG_ERR(
|
|
||||||
"%s:%d - Argument must parse to an integer", THIS_FILE,
|
|
||||||
__LINE__);
|
|
||||||
} else {
|
|
||||||
interface = net_if_get_by_index(index);
|
|
||||||
if (interface) {
|
|
||||||
LOG_INF("BIP6: Using interface %d", index);
|
|
||||||
} else {
|
|
||||||
LOG_ERR(
|
|
||||||
"%s:%d - No interface at index %d", THIS_FILE, __LINE__,
|
|
||||||
index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (index == -1) {
|
|
||||||
LOG_INF("BIP6: No valid interface specified. Using default ");
|
|
||||||
interface = net_if_get_default();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (interface) {
|
|
||||||
BIP6_Socket_Scope_Id = net_if_get_by_iface(interface);
|
|
||||||
LOG_INF("BIP6: Socket Scope ID = %d", BIP6_Socket_Scope_Id);
|
|
||||||
LOG_INF("BIP6: Interface set - Configured addresses:");
|
|
||||||
for (x = 0; x < NET_IF_MAX_IPV6_ADDR; x++) {
|
|
||||||
inet6_ntoa(&interface->config.ip.ipv6->unicast[x].address.in6_addr);
|
|
||||||
LOG_INF(" unicast[%d]: %s", x, ipv6_addr_str);
|
|
||||||
}
|
|
||||||
for (x = 0; x < NET_IF_MAX_IPV6_MADDR; x++) {
|
|
||||||
inet6_ntoa(&interface->config.ip.ipv6->mcast[x].address.in6_addr);
|
|
||||||
LOG_INF(" multicast[%d]: %s", x, ipv6_addr_str);
|
|
||||||
}
|
|
||||||
if (CONFIG_BACDL_BIP6_ADDRESS_INDEX >= NET_IF_MAX_IPV6_ADDR) {
|
|
||||||
LOG_ERR(
|
|
||||||
"%s:%d - IPv6 address index of %d is out of range (0-%d)",
|
|
||||||
THIS_FILE, __LINE__, CONFIG_BACDL_BIP6_ADDRESS_INDEX,
|
|
||||||
NET_IF_MAX_IPV6_ADDR - 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
LOG_INF("BIP6: Using configured index %d",
|
|
||||||
CONFIG_BACDL_BIP6_ADDRESS_INDEX);
|
|
||||||
memcpy(
|
|
||||||
&unicast.address,
|
|
||||||
&interface->config.ip.ipv6->unicast[CONFIG_BACDL_BIP6_ADDRESS_INDEX]
|
|
||||||
.address.in6_addr,
|
|
||||||
IP6_ADDRESS_MAX);
|
|
||||||
|
|
||||||
if (net_addr_pton(
|
|
||||||
AF_INET6, CONFIG_BACDL_BIP6_MCAST_ADDRESS,
|
|
||||||
&multicast.address)) {
|
|
||||||
LOG_ERR(
|
|
||||||
"%s:%d - Failed to parse IPv6 multicast address: %s", THIS_FILE,
|
|
||||||
__LINE__, CONFIG_BACDL_BIP6_MCAST_ADDRESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
bip6_set_addr(&unicast);
|
|
||||||
bip6_set_broadcast_addr(&multicast);
|
|
||||||
|
|
||||||
LOG_INF(
|
|
||||||
" Unicast: %s", inet6_ntoa((struct in6_addr *)&unicast.address));
|
|
||||||
LOG_INF(
|
|
||||||
" Multicast: %s",
|
|
||||||
inet6_ntoa((struct in6_addr *)&multicast.address));
|
|
||||||
} else {
|
|
||||||
LOG_ERR("%s:%d - Failed to set interface", THIS_FILE, __LINE__);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the BACnet IPv6 UDP port number
|
|
||||||
*
|
|
||||||
* @param port - IPv6 UDP port number
|
|
||||||
*/
|
|
||||||
void bip6_set_port(uint16_t port)
|
|
||||||
{
|
|
||||||
BIP6_Addr.port = port;
|
|
||||||
BIP6_Broadcast_Addr.port = port;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the BACnet IPv6 UDP port number
|
|
||||||
*
|
|
||||||
* @return IPv6 UDP port number
|
|
||||||
*/
|
|
||||||
uint16_t bip6_get_port(void)
|
|
||||||
{
|
|
||||||
return BIP6_Addr.port;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the BACnet broadcast address for my interface.
|
|
||||||
* Used as dest address in messages sent as BROADCAST
|
|
||||||
*
|
|
||||||
* @param addr - IPv6 source address
|
|
||||||
*/
|
|
||||||
void bip6_get_broadcast_address(BACNET_ADDRESS *addr)
|
|
||||||
{
|
|
||||||
if (addr) {
|
|
||||||
addr->net = BACNET_BROADCAST_NETWORK;
|
|
||||||
addr->mac_len = 0;
|
|
||||||
addr->len = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the IPv6 address for my interface. Used as src address in messages sent.
|
|
||||||
*
|
|
||||||
* @param addr - IPv6 source address
|
|
||||||
*/
|
|
||||||
void bip6_get_my_address(BACNET_ADDRESS *addr)
|
|
||||||
{
|
|
||||||
uint32_t device_id = 0;
|
|
||||||
|
|
||||||
if (addr) {
|
|
||||||
device_id = Device_Object_Instance_Number();
|
|
||||||
bvlc6_vmac_address_set(addr, device_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the BACnet/IP address
|
|
||||||
*
|
|
||||||
* @param addr - network IPv6 address
|
|
||||||
*/
|
|
||||||
bool bip6_set_addr(const BACNET_IP6_ADDRESS *addr)
|
|
||||||
{
|
|
||||||
return bvlc6_address_copy(&BIP6_Addr, addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the BACnet/IP address
|
|
||||||
*
|
|
||||||
* @return BACnet/IP address
|
|
||||||
*/
|
|
||||||
bool bip6_get_addr(BACNET_IP6_ADDRESS *addr)
|
|
||||||
{
|
|
||||||
return bvlc6_address_copy(addr, &BIP6_Addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the BACnet/IP address
|
|
||||||
*
|
|
||||||
* @param addr - network IPv6 address
|
|
||||||
*/
|
|
||||||
bool bip6_set_broadcast_addr(const BACNET_IP6_ADDRESS *addr)
|
|
||||||
{
|
|
||||||
return bvlc6_address_copy(&BIP6_Broadcast_Addr, addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the BACnet/IP address
|
|
||||||
*
|
|
||||||
* @return BACnet/IP address
|
|
||||||
*/
|
|
||||||
bool bip6_get_broadcast_addr(BACNET_IP6_ADDRESS *addr)
|
|
||||||
{
|
|
||||||
return bvlc6_address_copy(addr, &BIP6_Broadcast_Addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The send function for BACnet/IPv6 driver layer
|
|
||||||
*
|
|
||||||
* @param dest - Points to a BACNET_IP6_ADDRESS structure containing the
|
|
||||||
* destination address.
|
|
||||||
* @param mtu - the bytes of data to send
|
|
||||||
* @param mtu_len - the number of bytes of data to send
|
|
||||||
*
|
|
||||||
* @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)
|
|
||||||
{
|
|
||||||
struct sockaddr_in6 bvlc_dest = { 0 };
|
|
||||||
uint16_t addr16[8];
|
|
||||||
|
|
||||||
/* assumes that the driver has already been initialized */
|
|
||||||
if (BIP6_Socket < 0) {
|
|
||||||
LOG_ERR("%s:%d - Socket not initialized!", THIS_FILE, __LINE__);
|
|
||||||
return BIP6_Socket;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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]);
|
|
||||||
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]);
|
|
||||||
bvlc_dest.sin6_addr.s6_addr16[3] = htons(addr16[3]);
|
|
||||||
bvlc_dest.sin6_addr.s6_addr16[4] = htons(addr16[4]);
|
|
||||||
bvlc_dest.sin6_addr.s6_addr16[5] = htons(addr16[5]);
|
|
||||||
bvlc_dest.sin6_addr.s6_addr16[6] = htons(addr16[6]);
|
|
||||||
bvlc_dest.sin6_addr.s6_addr16[7] = htons(addr16[7]);
|
|
||||||
bvlc_dest.sin6_port = htons(dest->port);
|
|
||||||
bvlc_dest.sin6_scope_id = BIP6_Socket_Scope_Id;
|
|
||||||
inet6_ntoa(&bvlc_dest.sin6_addr);
|
|
||||||
LOG_DBG("BIP6: Sending MPDU to %s", ipv6_addr_str);
|
|
||||||
/* Send the packet */
|
|
||||||
return zsock_sendto(
|
|
||||||
BIP6_Socket, (const char *)mtu, mtu_len, 0,
|
|
||||||
(struct sockaddr *)&bvlc_dest, sizeof(bvlc_dest));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The common send function for BACnet/IPv6 application layer
|
|
||||||
*
|
|
||||||
* @param dest - Points to a #BACNET_ADDRESS structure containing the
|
|
||||||
* destination address.
|
|
||||||
* @param npdu_data - Points to a BACNET_NPDU_DATA structure containing the
|
|
||||||
* destination network layer control flags and data.
|
|
||||||
* @param pdu - the bytes of data to send
|
|
||||||
* @param pdu_len - the number of bytes of data to send
|
|
||||||
* @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,
|
|
||||||
BACNET_NPDU_DATA *npdu_data,
|
|
||||||
uint8_t *pdu,
|
|
||||||
unsigned pdu_len)
|
|
||||||
{
|
|
||||||
return bvlc6_send_pdu(dest, npdu_data, pdu, pdu_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Generate ASCII address string from BACnet/IPv6 address
|
|
||||||
* @param s - buffer to store the string
|
|
||||||
* @param n - size of the buffer
|
|
||||||
* @param addr - BACnet/IPv6 address
|
|
||||||
*/
|
|
||||||
static int bvlc6_snprintf_addr(
|
|
||||||
char *s, size_t n, const BACNET_IP6_ADDRESS *addr)
|
|
||||||
{
|
|
||||||
uint16_t addr16[8];
|
|
||||||
|
|
||||||
bvlc6_address_get(
|
|
||||||
addr, &addr16[0], &addr16[1], &addr16[2], &addr16[3], &addr16[4],
|
|
||||||
&addr16[5], &addr16[6], &addr16[7]);
|
|
||||||
|
|
||||||
return snprintf(s, n, "%04X:%04X:%04X:%04X:%04X:%04X:%04X:%04X",
|
|
||||||
addr16[0], addr16[1], addr16[2], addr16[3], addr16[4], addr16[5],
|
|
||||||
addr16[6], addr16[7]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* BACnet/IP Datalink Receive handler.
|
|
||||||
*
|
|
||||||
* @param src - returns the source address
|
|
||||||
* @param npdu - returns the NPDU buffer
|
|
||||||
* @param max_npdu -maximum size of the NPDU buffer
|
|
||||||
* @param timeout - number of milliseconds to wait for a packet
|
|
||||||
*
|
|
||||||
* @return Number of bytes received, or 0 if none or timeout.
|
|
||||||
*/
|
|
||||||
uint16_t bip6_receive(
|
|
||||||
BACNET_ADDRESS *src, uint8_t *npdu, uint16_t max_npdu, unsigned timeout)
|
|
||||||
{
|
|
||||||
uint16_t npdu_len = 0; /* return value */
|
|
||||||
zsock_fd_set read_fds;
|
|
||||||
int max = 0;
|
|
||||||
struct zsock_timeval select_timeout;
|
|
||||||
struct sockaddr_in6 sin = { 0 };
|
|
||||||
BACNET_IP6_ADDRESS addr = { 0 };
|
|
||||||
socklen_t sin_len = sizeof(sin);
|
|
||||||
int received_bytes = 0;
|
|
||||||
int offset = 0;
|
|
||||||
uint16_t i = 0;
|
|
||||||
|
|
||||||
/* Make sure the socket is open */
|
|
||||||
if (BIP6_Socket < 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
|
|
||||||
a select. */
|
|
||||||
if (timeout >= 1000) {
|
|
||||||
select_timeout.tv_sec = timeout / 1000;
|
|
||||||
select_timeout.tv_usec =
|
|
||||||
1000 * (timeout - select_timeout.tv_sec * 1000);
|
|
||||||
} else {
|
|
||||||
select_timeout.tv_sec = 0;
|
|
||||||
select_timeout.tv_usec = 1000 * timeout;
|
|
||||||
}
|
|
||||||
ZSOCK_FD_ZERO(&read_fds);
|
|
||||||
ZSOCK_FD_SET(BIP6_Socket, &read_fds);
|
|
||||||
max = BIP6_Socket;
|
|
||||||
/* see if there is a packet for us */
|
|
||||||
if (zsock_select(max + 1, &read_fds, NULL, NULL, &select_timeout) > 0) {
|
|
||||||
received_bytes = zsock_recvfrom(
|
|
||||||
BIP6_Socket, (char *)&npdu[0], max_npdu, 0, (struct sockaddr *)&sin,
|
|
||||||
&sin_len);
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* See if there is a problem */
|
|
||||||
if (received_bytes < 0) {
|
|
||||||
LOG_WRN(
|
|
||||||
"%s:%d - RX zsock_recvfrom() error: %d", THIS_FILE, __LINE__,
|
|
||||||
received_bytes);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/* no problem, just no bytes */
|
|
||||||
if (received_bytes == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/* the signature of a BACnet/IPv6 packet */
|
|
||||||
if (npdu[0] != BVLL_TYPE_BACNET_IP6) {
|
|
||||||
LOG_DBG("BIP6: not a BACnet packet. Dropped.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/* pass the packet into the BBMD handler */
|
|
||||||
inet6_ntoa(&sin.sin6_addr);
|
|
||||||
LOG_DBG("BIP6: Received MPDU from %s", ipv6_addr_str);
|
|
||||||
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]),
|
|
||||||
ntohs(sin.sin6_addr.s6_addr16[7]));
|
|
||||||
addr.port = ntohs(sin.sin6_port);
|
|
||||||
offset = bvlc6_handler(&addr, src, npdu, received_bytes);
|
|
||||||
if (offset > 0) {
|
|
||||||
npdu_len = received_bytes - offset;
|
|
||||||
if (npdu_len <= max_npdu) {
|
|
||||||
/* shift the buffer to return a valid NPDU */
|
|
||||||
for (i = 0; i < npdu_len; i++) {
|
|
||||||
npdu[i] = npdu[offset + i];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
LOG_WRN("%s:%d - NPDU dropped (too long)!", THIS_FILE, __LINE__);
|
|
||||||
npdu_len = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return npdu_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Cleanup and close out the BACnet/IP services by closing the socket.
|
|
||||||
* @ingroup DLBIP6
|
|
||||||
*/
|
|
||||||
void bip6_cleanup(void)
|
|
||||||
{
|
|
||||||
LOG_DBG("bip6_cleanup();");
|
|
||||||
bvlc6_cleanup();
|
|
||||||
if (BIP6_Socket != -1) {
|
|
||||||
zsock_close(BIP6_Socket);
|
|
||||||
}
|
|
||||||
BIP6_Socket = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Initialize the BACnet/IP services at the given interface.
|
|
||||||
* @ingroup DLBIP6
|
|
||||||
* -# Gets the local IP address and local broadcast address from the system,
|
|
||||||
* and saves it into the BACnet/IPv6 data structures.
|
|
||||||
* -# Opens a UDP socket
|
|
||||||
* -# Configures the socket for sending and receiving
|
|
||||||
* -# Configures the socket so it can send multicasts
|
|
||||||
* -# Binds the socket to the local IP address at the specified port for
|
|
||||||
* BACnet/IPv6 (by default, 0xBAC0 = 47808).
|
|
||||||
*
|
|
||||||
* @param ifname [in] The named interface to use for the network layer.
|
|
||||||
* If NULL, the "eth0" interface is assigned.
|
|
||||||
* @return True if the socket is successfully opened for BACnet/IP,
|
|
||||||
* else False if the socket functions fail.
|
|
||||||
*/
|
|
||||||
bool bip6_init(char *ifname)
|
|
||||||
{
|
|
||||||
int status = -1;
|
|
||||||
struct sockaddr_in6 server = { 0 };
|
|
||||||
struct in6_addr broadcast_address;
|
|
||||||
struct ipv6_mreq join_request;
|
|
||||||
const int sockopt = 1;
|
|
||||||
char addr6_str[40] = "";
|
|
||||||
|
|
||||||
LOG_DBG("bip6_init()");
|
|
||||||
if (BIP6_Addr.port == 0) {
|
|
||||||
bip6_set_port(0xBAC0U);
|
|
||||||
}
|
|
||||||
bip6_set_interface(ifname);
|
|
||||||
LOG_INF("BIP6: IPv6 UDP port: 0x%04X", (unsigned)BIP6_Addr.port);
|
|
||||||
bvlc6_snprintf_addr(addr6_str, sizeof(addr6_str), &BIP6_Addr);
|
|
||||||
LOG_INF("BIP6: IPv6 unicast addr: %s", addr6_str);
|
|
||||||
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);
|
|
||||||
LOG_INF("BIP6: IPv6 MULTICAST_SITE_LOCAL");
|
|
||||||
}
|
|
||||||
bvlc6_snprintf_addr(addr6_str, sizeof(addr6_str), &BIP6_Broadcast_Addr);
|
|
||||||
LOG_INF("BIP6: IPv6 multicast addr: %s", addr6_str);
|
|
||||||
|
|
||||||
/* assumes that the driver has already been initialized */
|
|
||||||
BIP6_Socket = zsock_socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
|
|
||||||
if (BIP6_Socket < 0) {
|
|
||||||
LOG_ERR("%s:%d - Failed to create socket", THIS_FILE, __LINE__);
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
LOG_INF("Socket created");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allow us to use the same socket for sending and receiving */
|
|
||||||
/* This makes sure that the src port is correct when sending */
|
|
||||||
status = zsock_setsockopt(
|
|
||||||
BIP6_Socket, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof(sockopt));
|
|
||||||
if (status < 0) {
|
|
||||||
LOG_ERR("BIP6: setsockopt(SO_REUSEADDR)");
|
|
||||||
}
|
|
||||||
/* allow us to send a broadcast */
|
|
||||||
status = zsock_setsockopt(
|
|
||||||
BIP6_Socket, SOL_SOCKET, SO_BROADCAST, &sockopt, sizeof(sockopt));
|
|
||||||
if (status < 0) {
|
|
||||||
/* ignored? For compatibility? Really? */
|
|
||||||
LOG_ERR("BIP6: setsockopt(SO_BROADCAST)");
|
|
||||||
}
|
|
||||||
/* subscribe to a multicast address */
|
|
||||||
memcpy(
|
|
||||||
&broadcast_address.s6_addr[0], &BIP6_Broadcast_Addr.address[0],
|
|
||||||
IP6_ADDRESS_MAX);
|
|
||||||
memcpy(
|
|
||||||
&join_request.ipv6mr_multiaddr, &broadcast_address,
|
|
||||||
sizeof(struct in6_addr));
|
|
||||||
/* Let system not choose the interface */
|
|
||||||
join_request.ipv6mr_ifindex = BIP6_Socket_Scope_Id;
|
|
||||||
status = setsockopt(
|
|
||||||
BIP6_Socket, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &join_request,
|
|
||||||
sizeof(join_request));
|
|
||||||
if (status < 0) {
|
|
||||||
LOG_ERR("BIP6: setsockopt(IPV6_ADD_MEMBERSHIP)");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
/* bind the socket to the local port number and IP address */
|
|
||||||
server.sin6_family = AF_INET6;
|
|
||||||
#if 0
|
|
||||||
uint16_t addr16[8];
|
|
||||||
bvlc6_address_get(&BIP6_Addr, &addr16[0], &addr16[1], &addr16[2],
|
|
||||||
&addr16[3], &addr16[4], &addr16[5], &addr16[6], &addr16[7]);
|
|
||||||
server.sin6_addr.s6_addr16[0] = htons(addr16[0]);
|
|
||||||
server.sin6_addr.s6_addr16[1] = htons(addr16[1]);
|
|
||||||
server.sin6_addr.s6_addr16[2] = htons(addr16[2]);
|
|
||||||
server.sin6_addr.s6_addr16[3] = htons(addr16[3]);
|
|
||||||
server.sin6_addr.s6_addr16[4] = htons(addr16[4]);
|
|
||||||
server.sin6_addr.s6_addr16[5] = htons(addr16[5]);
|
|
||||||
server.sin6_addr.s6_addr16[6] = htons(addr16[6]);
|
|
||||||
server.sin6_addr.s6_addr16[7] = htons(addr16[7]);
|
|
||||||
#else
|
|
||||||
server.sin6_addr = in6addr_any;
|
|
||||||
#endif
|
|
||||||
server.sin6_port = htons(BIP6_Addr.port);
|
|
||||||
LOG_INF("BIP6: Binding to port %d", BIP6_Addr.port);
|
|
||||||
status =
|
|
||||||
zsock_bind(BIP6_Socket, (const struct sockaddr *)&server, sizeof(server));
|
|
||||||
if (status < 0) {
|
|
||||||
zsock_close(BIP6_Socket);
|
|
||||||
BIP6_Socket = -1;
|
|
||||||
LOG_ERR("%s:%d - zsock_bind() failure", THIS_FILE, __LINE__);
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
LOG_INF("BIP6: Socket bound. Success!");
|
|
||||||
}
|
|
||||||
bvlc6_init();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Check if the BACnet/IPv6 socket is valid
|
|
||||||
* @return True if the socket is valid, else False
|
|
||||||
*/
|
|
||||||
bool bip6_valid(void)
|
|
||||||
{
|
|
||||||
return (BIP6_Socket != -1);
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright (C) 2020 Steve Karg
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-or-later WITH GCC-exception-2.0
|
|
||||||
*
|
|
||||||
*********************************************************************/
|
|
||||||
/* BACnet Stack defines - first */
|
|
||||||
#include "bacnet/bacdef.h"
|
|
||||||
/* BACnet Stack API */
|
|
||||||
#include "bacnet/datalink/bvlc.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Encode the BVLC header
|
|
||||||
*
|
|
||||||
* @param pdu - buffer to store the encoding
|
|
||||||
* @param pdu_size - size of the buffer to store encoding
|
|
||||||
* @param message_type - BVLL Messages
|
|
||||||
* @param length - number of bytes for this message type
|
|
||||||
*
|
|
||||||
* @return number of bytes encoded
|
|
||||||
*/
|
|
||||||
void bvlc_file_bdt_write(
|
|
||||||
void *data,
|
|
||||||
size_t len)
|
|
||||||
{
|
|
||||||
/* TODO: Write BDT data blob into persistent storage */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
size_t bvlc_file_bdt_read(
|
|
||||||
void *data,
|
|
||||||
size_t len)
|
|
||||||
{
|
|
||||||
size_t sz = -1;
|
|
||||||
|
|
||||||
/* TODO: Read BD data blob from persistent storage */
|
|
||||||
|
|
||||||
return sz;
|
|
||||||
}
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
* @author Steve Karg
|
|
||||||
* @date 2009
|
|
||||||
* @brief System time library header file.
|
|
||||||
*
|
|
||||||
* @section DESCRIPTION
|
|
||||||
*
|
|
||||||
* This library provides functions for getting and setting the system time.
|
|
||||||
*/
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
/* BACnet Stack defines - first */
|
|
||||||
#include "bacnet/bacdef.h"
|
|
||||||
/* BACnet Stack API */
|
|
||||||
#include "bacnet/datetime.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* HACK:
|
|
||||||
* - Zephyr does not declare timezone in any header file.
|
|
||||||
* - The gcc-arm-none-eabi-7-2018-q2-update/bin/arm-none-eabi/lib/thumb/v7e-m/
|
|
||||||
* libc_nano.a 'time' symbol does not resolve '_gettimeofday'
|
|
||||||
*
|
|
||||||
* TODO: figure out how to link in the real time() and timezone;
|
|
||||||
*/
|
|
||||||
long timezone;
|
|
||||||
|
|
||||||
time_t time(time_t *tloc)
|
|
||||||
{
|
|
||||||
time_t time = { 0 };
|
|
||||||
|
|
||||||
return time;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get the date, time, timezone, and UTC offset from system
|
|
||||||
* @param utc_time - the BACnet Date and Time structure to hold UTC time
|
|
||||||
* @param local_time - the BACnet Date and Time structure to hold local time
|
|
||||||
* @param utc_offset_minutes - number of minutes offset from UTC
|
|
||||||
* For example, -6*60 represents 6.00 hours behind UTC/GMT
|
|
||||||
* @param true if DST is enabled and active
|
|
||||||
* @return true if local time was retrieved
|
|
||||||
*/
|
|
||||||
bool datetime_local(
|
|
||||||
BACNET_DATE * bdate,
|
|
||||||
BACNET_TIME * btime,
|
|
||||||
int16_t * utc_offset_minutes,
|
|
||||||
bool * dst_active)
|
|
||||||
{
|
|
||||||
bool status = false;
|
|
||||||
struct tm tblock_st = { 0 };
|
|
||||||
struct tm *tblock = &tblock_st;
|
|
||||||
struct timeval tv;
|
|
||||||
|
|
||||||
if (gettimeofday(&tv, NULL) == 0)
|
|
||||||
{
|
|
||||||
tblock = (struct tm *)localtime((const time_t *)&tv.tv_sec);
|
|
||||||
}
|
|
||||||
if (tblock) {
|
|
||||||
status = true;
|
|
||||||
/** struct tm
|
|
||||||
* int tm_sec Seconds [0,60].
|
|
||||||
* int tm_min Minutes [0,59].
|
|
||||||
* int tm_hour Hour [0,23].
|
|
||||||
* int tm_mday Day of month [1,31].
|
|
||||||
* int tm_mon Month of year [0,11].
|
|
||||||
* int tm_year Years since 1900.
|
|
||||||
* int tm_wday Day of week [0,6] (Sunday =0).
|
|
||||||
* int tm_yday Day of year [0,365].
|
|
||||||
* int tm_isdst Daylight Savings flag.
|
|
||||||
*/
|
|
||||||
datetime_set_date(bdate, (uint16_t)tblock->tm_year + 1900,
|
|
||||||
(uint8_t)tblock->tm_mon + 1,
|
|
||||||
(uint8_t)tblock->tm_mday);
|
|
||||||
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));
|
|
||||||
if (dst_active) {
|
|
||||||
/* The value of tm_isdst is:
|
|
||||||
- positive if Daylight Saving Time is in effect,
|
|
||||||
- 0 if Daylight Saving Time is not in effect, and
|
|
||||||
- negative if the information is not available. */
|
|
||||||
if (tblock->tm_isdst > 0) {
|
|
||||||
*dst_active = true;
|
|
||||||
} else {
|
|
||||||
*dst_active = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* note: timezone is declared in <time.h> stdlib. */
|
|
||||||
if (utc_offset_minutes) {
|
|
||||||
/* timezone is set to the difference, in seconds,
|
|
||||||
between Coordinated Universal Time (UTC) and
|
|
||||||
local standard time */
|
|
||||||
*utc_offset_minutes = timezone / 60;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* initialize the date time
|
|
||||||
*/
|
|
||||||
void datetime_init(void)
|
|
||||||
{
|
|
||||||
/* nothing to do */
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2020 Legrand North America, Inc.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Standard includes */
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
/* Zephyr includes */
|
|
||||||
#include <zephyr/init.h>
|
|
||||||
#include <zephyr/kernel.h>
|
|
||||||
#include <zephyr/sys/printk.h>
|
|
||||||
#include <zephyr/sys/util.h>
|
|
||||||
#include <zephyr/kernel.h>
|
|
||||||
|
|
||||||
#define LOG_LEVEL CONFIG_BACNETSTACK_LOG_LEVEL
|
|
||||||
#include <zephyr/logging/log.h>
|
|
||||||
LOG_MODULE_REGISTER(bacnet);
|
|
||||||
|
|
||||||
/* To do: init()
|
|
||||||
|
|
||||||
static int init(struct device *unused)
|
|
||||||
{
|
|
||||||
ARG_UNUSED(unused);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
SYS_INIT(init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY);
|
|
||||||
|
|
||||||
*/
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
|
|
||||||
* Multimedia Timer contribution by Cameron Crothers, 2008
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*
|
|
||||||
*********************************************************************/
|
|
||||||
#include <zephyr/kernel.h>
|
|
||||||
/* BACnet Stack defines - first */
|
|
||||||
#include "bacnet/bacdef.h"
|
|
||||||
/* BACnet Stack API */
|
|
||||||
#include "bacnet/basic/sys/mstimer.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief returns the current millisecond count
|
|
||||||
* @return millisecond counter
|
|
||||||
*/
|
|
||||||
unsigned long mstimer_now(void)
|
|
||||||
{
|
|
||||||
return (unsigned long) k_uptime_get_32();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initialization for timer
|
|
||||||
*/
|
|
||||||
void mstimer_init(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright (C) 2004 Steve Karg
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-or-later WITH GCC-exception-2.0
|
|
||||||
*
|
|
||||||
*********************************************************************/
|
|
||||||
#ifndef RS485_H
|
|
||||||
#define RS485_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
/* BACnet Stack defines - first */
|
|
||||||
#include "bacnet/bacdef.h"
|
|
||||||
/* BACnet Stack API */
|
|
||||||
#include "bacnet/datalink/mstp.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
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_Initialize(
|
|
||||||
void);
|
|
||||||
|
|
||||||
BACNET_STACK_EXPORT
|
|
||||||
void RS485_Send_Frame(
|
|
||||||
volatile 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(
|
|
||||||
volatile struct mstp_port_struct_t *mstp_port); /* port specific data */
|
|
||||||
BACNET_STACK_EXPORT
|
|
||||||
uint32_t RS485_Get_Port_Baud_Rate(
|
|
||||||
volatile 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);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
#endif
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
# The default west manifest file for Cutter.
|
|
||||||
#
|
|
||||||
# The per-installation west configuration file, .west/config, sets the
|
|
||||||
# path to the project containing this file in the [manifest] section's
|
|
||||||
# "path" variable.
|
|
||||||
#
|
|
||||||
# This imports the latest upstream Zephyr manifest file.
|
|
||||||
#
|
|
||||||
# You can pass your manifest repositories to west init when creating a
|
|
||||||
# new Zephyr installation. See the west documentation for more
|
|
||||||
# information.
|
|
||||||
#
|
|
||||||
# Beginning with west 0.8, the following command-line options
|
|
||||||
# can be used to initialize with a repository lacking a west.yml
|
|
||||||
# file at the top level.
|
|
||||||
#
|
|
||||||
# west init
|
|
||||||
# -m <repository>
|
|
||||||
# --mr <branch_name>
|
|
||||||
# --mf <manifest_pathname>
|
|
||||||
# <workspace>
|
|
||||||
|
|
||||||
manifest:
|
|
||||||
version: 0.13
|
|
||||||
|
|
||||||
remotes:
|
|
||||||
- name: bacnet-stack
|
|
||||||
url-base: https://github.com/bacnet-stack
|
|
||||||
- name: zephyrproject-rtos
|
|
||||||
url-base: https://github.com/zephyrproject-rtos
|
|
||||||
|
|
||||||
defaults:
|
|
||||||
remote: bacnet-stack
|
|
||||||
|
|
||||||
self:
|
|
||||||
path: bacnet-stack
|
|
||||||
|
|
||||||
projects:
|
|
||||||
- name: zephyr
|
|
||||||
path: zephyr
|
|
||||||
revision: v3.6.0
|
|
||||||
remote: zephyrproject-rtos
|
|
||||||
west-commands: scripts/west-commands.yml
|
|
||||||
import:
|
|
||||||
name-allowlist:
|
|
||||||
- cmsis
|
|
||||||
- picolibc
|
|
||||||
- hal_stm32
|
|
||||||
- hal_microchip
|
|
||||||
- segger
|
|
||||||
- mcuboot
|
|
||||||
@@ -1,534 +0,0 @@
|
|||||||
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
|
|
||||||
|
|
||||||
# Detect the platform reliably
|
|
||||||
if(ZEPHYR_BASE)
|
|
||||||
if (NOT CONFIG_BACNETSTACK)
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
set(ZEPHYR YES)
|
|
||||||
else()
|
|
||||||
message(FATAL_ERROR "ZEPHYR_BASE needs to be defined for Zephyr builds")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
#
|
|
||||||
# options managed through Kconfig and use names CONFIG_*
|
|
||||||
#
|
|
||||||
message(STATUS "BACNETSTACK: using cmake ${CMAKE_VERSION}")
|
|
||||||
message(STATUS "BACNETSTACK: CMAKE_C_COMPILER_ID \"${CMAKE_C_COMPILER_ID}\"")
|
|
||||||
message(STATUS "BACNETSTACK: CMAKE_C_COMPILER_VERSION \"${CMAKE_C_COMPILER_VERSION}\"")
|
|
||||||
message(STATUS "BACNETSTACK: CMAKE_CXX_COMPILER_ID \"${CMAKE_CXX_COMPILER_ID}\"")
|
|
||||||
message(STATUS "BACNETSTACK: CMAKE_CXX_COMPILER_VERSION \"${CMAKE_CXX_COMPILER_VERSION}\"")
|
|
||||||
message(STATUS "BACNETSTACK: CMAKE_INSTALL_PREFIX \"${CMAKE_INSTALL_PREFIX}\"")
|
|
||||||
message(STATUS "BACNETSTACK: BACNET_VENDOR_NAME \"${CONFIG_BACNET_VENDOR_NAME}\"")
|
|
||||||
message(STATUS "BACNETSTACK: BACNET_VENDOR_IDENTIFIER \"${CONFIG_BACNET_VENDOR_IDENTIFIER}\"")
|
|
||||||
message(STATUS "BACNETSTACK: BACNET_PROTOCOL_REVISION \"${CONFIG_BACNET_PROTOCOL_REVISION}\"")
|
|
||||||
message(STATUS "BACNETSTACK: BACDL_BIP6 \"${CONFIG_BACDL_BIP6}\"")
|
|
||||||
message(STATUS "BACNETSTACK: BACDL_BIP \"${CONFIG_BACDL_BIP}\"")
|
|
||||||
message(STATUS "BACNETSTACK: BACDL_ARCNET \"${CONFIG_BACDL_ARCNET}\"")
|
|
||||||
message(STATUS "BACNETSTACK: BACDL_MSTP \"${CONFIG_BACDL_MSTP}\"")
|
|
||||||
message(STATUS "BACNETSTACK: BACDL_ETHERNET \"${CONFIG_BACDL_ETHERNET}\"")
|
|
||||||
message(STATUS "BACNETSTACK: BACDL_NONE \"${CONFIG_BACDL_NONE}\"")
|
|
||||||
message(STATUS "BACNETSTACK: BACAPP_ALL \"${CONFIG_BACAPP_ALL}\"")
|
|
||||||
message(STATUS "BACNETSTACK: BACAPP_MINIMAL \"${CONFIG_BACAPP_MINIMAL}\"")
|
|
||||||
message(STATUS "BACNETSTACK: BACAPP_TYPES_EXTRA \"${CONFIG_BACAPP_TYPES_EXTRA}\"")
|
|
||||||
message(STATUS "BACNETSTACK: BACNET_ADDRESS_CACHE_FILE \"${CONFIG_BACNET_ADDRESS_CACHE_FILE}\"")
|
|
||||||
message(STATUS "BACNETSTACK: MAX_TSM_TRANSACTIONS \"${CONFIG_BACNET_MAX_TSM_TRANSACTIONS}\"")
|
|
||||||
message(STATUS "BACNETSTACK: MAX_ADDRESS_CACHE \"${CONFIG_BACNET_MAX_ADDRESS_CACHE}\"")
|
|
||||||
message(STATUS "BACNETSTACK: MAX_CHARACTER_STRING_BYTES \"${CONFIG_BACNET_MAX_CHARACTER_STRING_BYTES}\"")
|
|
||||||
message(STATUS "BACNETSTACK: MAX_OCTET_STRING_BYTES \"${CONFIG_BACNET_MAX_OCTET_STRING_BYTES}\"")
|
|
||||||
|
|
||||||
#Do not allow in source builds
|
|
||||||
set(CMAKE_DISABLE_SOURCE_CHANGES ON)
|
|
||||||
set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
|
|
||||||
|
|
||||||
#
|
|
||||||
# sources
|
|
||||||
#
|
|
||||||
set(BACNETSTACK_SRC ../src)
|
|
||||||
|
|
||||||
set(BACNETSTACK_SRCS
|
|
||||||
${BACNETSTACK_SRC}/bacnet/abort.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/abort.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/access_rule.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/access_rule.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/alarm_ack.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/alarm_ack.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/apdu.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/arf.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/arf.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/assigned_access_rights.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/assigned_access_rights.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/authentication_factor.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/authentication_factor_format.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/authentication_factor_format.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/authentication_factor.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/awf.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/awf.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/bacaction.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/bacaction.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/bacaddr.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/bacaddr.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/bacapp.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/bacapp.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/bacdcode.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/bacdcode.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/bacdef.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/bacdest.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/bacdest.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/bacdevobjpropref.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/bacdevobjpropref.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/bacenum.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/bacerror.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/bacerror.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/bacint.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/bacint.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/bacprop.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/bacprop.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/bacpropstates.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/bacpropstates.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/bacreal.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/bacreal.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/bacstr.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/bacstr.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/bactext.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/bactext.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/bactimevalue.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/bactimevalue.h
|
|
||||||
$<$<BOOL:${CONFIG_BACDL_BIP}>:${BACNETSTACK_SRC}/bacnet/basic/bbmd/h_bbmd.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACDL_BIP}>:${BACNETSTACK_SRC}/bacnet/basic/bbmd/h_bbmd.h>
|
|
||||||
$<$<BOOL:${CONFIG_BACDL_BIP6}>:${BACNETSTACK_SRC}/bacnet/basic/bbmd6/h_bbmd6.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACDL_BIP6}>:${BACNETSTACK_SRC}/bacnet/basic/bbmd6/h_bbmd6.h>
|
|
||||||
$<$<BOOL:${CONFIG_BACDL_BIP6}>:${BACNETSTACK_SRC}/bacnet/basic/bbmd6/vmac.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACDL_BIP6}>:${BACNETSTACK_SRC}/bacnet/basic/bbmd6/vmac.h>
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/binding/address.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/binding/address.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/npdu/h_npdu.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/npdu/h_npdu.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/npdu/h_routed_npdu.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/npdu/h_routed_npdu.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/npdu/s_router.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/object/access_credential.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/object/access_door.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/object/access_point.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/object/access_rights.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/object/access_user.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/object/access_zone.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/object/ai.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/object/ao.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/object/av.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/object/bacfile.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/object/bi.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/object/bo.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/object/bv.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/object/calendar.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/object/channel.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/object/color_object.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/object/color_temperature.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/object/command.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/object/credential_data_input.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/object/csv.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/object/device.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/object/iv.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/object/lc.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/object/lo.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/object/lsp.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/object/ms-input.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/object/mso.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/object/msv.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/object/nc.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/object/netport.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/object/objects.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/object/osv.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/object/piv.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/object/schedule.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/object/time_value.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/object/trendlog.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_alarm_ack.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_apdu.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_apdu.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_arf_a.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_arf.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_awf.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_ccov.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_cov.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_cov.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_dcc.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_dcc.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_gas_a.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_get_alarm_sum.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_getevent_a.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_getevent.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_iam.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_iam.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_ihave.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_ihave.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_lso.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_noserv.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_noserv.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_rd.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_rd.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_rp_a.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_rp_a.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_rp.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_rp.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_rpm_a.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_rpm_a.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_rpm.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_rpm.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_rr_a.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_rr.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_ts.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_ucov.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_upt.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_whohas.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_whohas.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_whois.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_whois.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_wp.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_wp.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_wpm.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_wpm.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_abort.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_ack_alarm.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_arfs.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_awfs.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_cevent.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_cov.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_dcc.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_error.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_get_alarm_sum.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_get_event.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_getevent.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_iam.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_iam.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_ihave.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_ihave.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_list_element.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_list_element.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_lso.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_rd.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_readrange.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_rp.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_rpm.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_ts.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_uevent.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_upt.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_whohas.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_whohas.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_whois.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_whois.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_wp.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_wpm.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/services.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/sys/bigend.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/sys/bigend.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/sys/days.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/sys/days.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/sys/debug.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/sys/debug.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/sys/fifo.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/sys/fifo.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/sys/filename.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/sys/filename.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/sys/key.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/sys/keylist.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/sys/keylist.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/sys/linear.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/sys/linear.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/sys/mstimer.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/sys/mstimer.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/sys/ringbuf.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/sys/ringbuf.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/sys/sbuf.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/sys/sbuf.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/tsm/tsm.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/tsm/tsm.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/sys/bits.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/sys/bytes.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/config.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/cov.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/cov.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/credential_authentication_factor.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/credential_authentication_factor.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/datalink/arcnet.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/datalink/bacsec.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/datalink/bacsec.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/datalink/bip6.h
|
|
||||||
$<$<BOOL:${CONFIG_BACDL_BIP}>:${BACNETSTACK_SRC}/bacnet/datalink/bip.h>
|
|
||||||
$<$<BOOL:${CONFIG_BACDL_BIP6}>:${BACNETSTACK_SRC}/bacnet/datalink/bvlc6.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACDL_BIP6}>:${BACNETSTACK_SRC}/bacnet/datalink/bvlc6.h>
|
|
||||||
$<$<BOOL:${CONFIG_BACDL_BIP}>:${BACNETSTACK_SRC}/bacnet/datalink/bvlc.h>
|
|
||||||
$<$<BOOL:${CONFIG_BACDL_BIP}>:${BACNETSTACK_SRC}/bacnet/datalink/bvlc.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACDL_MSTP}>:${BACNETSTACK_SRC}/bacnet/datalink/crc.h>
|
|
||||||
$<$<BOOL:${CONFIG_BACDL_MSTP}>:${BACNETSTACK_SRC}/bacnet/datalink/crc.c>
|
|
||||||
${BACNETSTACK_SRC}/bacnet/datalink/datalink.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/datalink/datalink.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/datalink/dlmstp.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/datalink/ethernet.h
|
|
||||||
$<$<BOOL:${CONFIG_BACDL_MSTP}>:${BACNETSTACK_SRC}/bacnet/datalink/mstp.h>
|
|
||||||
${BACNETSTACK_SRC}/bacnet/datalink/mstpdef.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/datalink/mstp.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/datalink/mstptext.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/datalink/mstptext.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/datetime.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/datetime.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/dcc.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/dcc.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/event.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/get_alarm_sum.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/get_alarm_sum.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/getevent.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/getevent.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/hostnport.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/hostnport.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/iam.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/iam.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/ihave.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/ihave.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/indtext.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/indtext.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/lighting.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/lighting.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/list_element.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/list_element.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/lso.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/lso.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/memcopy.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/memcopy.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/npdu.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/npdu.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/property.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/property.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/proplist.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/proplist.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/ptransfer.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/ptransfer.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/rd.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/rd.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/readrange.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/readrange.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/reject.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/reject.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/rp.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/rp.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/rpm.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/rpm.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/timestamp.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/timestamp.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/timesync.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/timesync.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/version.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/whohas.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/whohas.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/whois.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/whois.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/wp.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/wp.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/wpm.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/wpm.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/weeklyschedule.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/weeklyschedule.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/dailyschedule.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/dailyschedule.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/calendar_entry.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/calendar_entry.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/special_event.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/special_event.h
|
|
||||||
)
|
|
||||||
|
|
||||||
set(BACNETSTACK_BASIC_SRCS
|
|
||||||
$<$<BOOL:${CONFIG_BACDL_BIP6}>:${BACNETSTACK_SRC}/bacnet/basic/bbmd6/h_bbmd6.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACDL_BIP6}>:${BACNETSTACK_SRC}/bacnet/basic/bbmd6/vmac.c>
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/npdu/s_router.c
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECTS_ACCESS}>:${BACNETSTACK_SRC}/bacnet/basic/object/access_credential.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECTS_ACCESS}>:${BACNETSTACK_SRC}/bacnet/basic/object/access_door.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECTS_ACCESS}>:${BACNETSTACK_SRC}/bacnet/basic/object/access_point.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECTS_ACCESS}>:${BACNETSTACK_SRC}/bacnet/basic/object/access_rights.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECTS_ACCESS}>:${BACNETSTACK_SRC}/bacnet/basic/object/access_user.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECTS_ACCESS}>:${BACNETSTACK_SRC}/bacnet/basic/object/access_zone.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECT_ACCUMULATOR}>:${BACNETSTACK_SRC}/bacnet/basic/object/acc.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECT_ANALOG_INPUT}>:${BACNETSTACK_SRC}/bacnet/basic/object/ai.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECT_ANALOG_OUTPUT}>:${BACNETSTACK_SRC}/bacnet/basic/object/ao.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECT_ANALOG_VALUE}>:${BACNETSTACK_SRC}/bacnet/basic/object/av.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECT_FILE}>:${BACNETSTACK_SRC}/bacnet/basic/object/bacfile.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECT_BINARY_INPUT}>:${BACNETSTACK_SRC}/bacnet/basic/object/bi.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECT_BINARY_OUTPUT}>:${BACNETSTACK_SRC}/bacnet/basic/object/bo.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECT_BINARY_VALUE}>:${BACNETSTACK_SRC}/bacnet/basic/object/bv.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECT_CALENDAR}>:${BACNETSTACK_SRC}/bacnet/basic/object/calendar.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECT_CHANNEL}>:${BACNETSTACK_SRC}/bacnet/basic/object/channel.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECT_COMMAND}>:${BACNETSTACK_SRC}/bacnet/basic/object/command.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECT_COLOR}>:${BACNETSTACK_SRC}/bacnet/basic/object/color_object.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECT_COLOR_TEMPERATURE}>:${BACNETSTACK_SRC}/bacnet/basic/object/color_temperature.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECTS_ACCESS}>:${BACNETSTACK_SRC}/bacnet/basic/object/credential_data_input.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECT_CHARACTERSTRING_VALUE}>:${BACNETSTACK_SRC}/bacnet/basic/object/csv.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECT_DEVICE_CLIENT}>:${BACNETSTACK_SRC}/bacnet/basic/object/client/device-client.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECT_DEVICE_SERVER}>:${BACNETSTACK_SRC}/bacnet/basic/object/device.c>
|
|
||||||
$<$<BOOL:${CONFIG_BAC_ROUTING}>:${BACNETSTACK_SRC}/bacnet/basic/object/gateway/gw_device.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECT_INTEGER_VALUE}>:${BACNETSTACK_SRC}/bacnet/basic/object/iv.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECT_LOAD_CONTROL}>:${BACNETSTACK_SRC}/bacnet/basic/object/lc.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECT_LIGHTING_OUTPUT}>:${BACNETSTACK_SRC}/bacnet/basic/object/lo.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECT_LIFE_SAFETY_POINT}>:${BACNETSTACK_SRC}/bacnet/basic/object/lsp.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECT_MULTISTATE_INPUT}>:${BACNETSTACK_SRC}/bacnet/basic/object/ms-input.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECT_MULTISTATE_OUTPUT}>:${BACNETSTACK_SRC}/bacnet/basic/object/mso.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECT_MULTISTATE_VALUE}>:${BACNETSTACK_SRC}/bacnet/basic/object/msv.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECT_NOTIFICATION_CLASS}>:${BACNETSTACK_SRC}/bacnet/basic/object/nc.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECT_NETWORK_PORT}>:${BACNETSTACK_SRC}/bacnet/basic/object/netport.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECTS}>:${BACNETSTACK_SRC}/bacnet/basic/object/objects.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECT_OCTET_STRING_VALUE}>:${BACNETSTACK_SRC}/bacnet/basic/object/osv.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECT_POSITIVE_INTEGER_VALUE}>:${BACNETSTACK_SRC}/bacnet/basic/object/piv.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECT_SCHEDULE}>:${BACNETSTACK_SRC}/bacnet/basic/object/schedule.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECT_STRUCTURED_VIEW}>:${BACNETSTACK_SRC}/bacnet/basic/object/structured_view.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECT_TIME_VALUE}>:${BACNETSTACK_SRC}/bacnet/basic/object/time_value.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECT_TRENDLOG}>:${BACNETSTACK_SRC}/bacnet/basic/object/trendlog.c>
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_alarm_ack.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_arf_a.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_arf.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_awf.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_ccov.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_gas_a.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_get_alarm_sum.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_getevent_a.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_getevent.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_list_element.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_list_element.h
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_lso.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_rr_a.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_rr.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_ts.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_ucov.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/h_upt.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_abort.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_ack_alarm.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_arfs.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_awfs.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_cevent.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_cov.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_dcc.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_error.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_get_alarm_sum.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_get_event.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_getevent.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_lso.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_rd.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_readrange.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_rp.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_rpm.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_ts.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_uevent.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_upt.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_wp.c
|
|
||||||
${BACNETSTACK_SRC}/bacnet/basic/service/s_wpm.c
|
|
||||||
)
|
|
||||||
|
|
||||||
#
|
|
||||||
# add ports
|
|
||||||
#
|
|
||||||
|
|
||||||
set(BACNETSTACK_PORT_DIRECTORY_PATH "")
|
|
||||||
|
|
||||||
message(STATUS "BACNETSTACK: building for Zephyr")
|
|
||||||
set(BACNETSTACK_PORT ${CMAKE_CURRENT_LIST_DIR}/../ports/zephyr)
|
|
||||||
|
|
||||||
list(
|
|
||||||
APPEND BACNETSTACK_SRCS
|
|
||||||
${BACNETSTACK_BASIC_SRCS}
|
|
||||||
${BACNETSTACK_PORT}/datetime-init.c
|
|
||||||
$<$<BOOL:${CONFIG_BACDL_BIP}>:${BACNETSTACK_PORT}/bip-init.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACDL_BIP6}>:${BACNETSTACK_PORT}/bip6-init.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACDL_BIP}>:${BACNETSTACK_PORT}/datalink/bvlc.c>
|
|
||||||
$<$<BOOL:${CONFIG_BACDL_ETHERNET}>:${BACNETSTACK_PORT}/ethernet.c>
|
|
||||||
${BACNETSTACK_PORT}/main.c
|
|
||||||
${BACNETSTACK_PORT}/mstimer-init.c
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
zephyr_include_directories(include)
|
|
||||||
add_subdirectory(subsys)
|
|
||||||
|
|
||||||
#
|
|
||||||
# library
|
|
||||||
#
|
|
||||||
|
|
||||||
zephyr_library()
|
|
||||||
|
|
||||||
zephyr_library_compile_definitions(
|
|
||||||
BACNET_STACK_STATIC_DEFINE
|
|
||||||
)
|
|
||||||
|
|
||||||
zephyr_library_sources(
|
|
||||||
${BACNETSTACK_SRCS}
|
|
||||||
)
|
|
||||||
|
|
||||||
zephyr_include_directories(
|
|
||||||
${BACNETSTACK_PORT}
|
|
||||||
${BACNETSTACK_SRC}
|
|
||||||
)
|
|
||||||
|
|
||||||
zephyr_compile_definitions(
|
|
||||||
BACNET_CONFIG_H=1 # Use ports/zephyr/bacnet-config.h
|
|
||||||
BACNET_VENDOR_ID=${CONFIG_BACNET_VENDOR_IDENTIFIER}
|
|
||||||
BACNET_VENDOR_NAME="${CONFIG_BACNET_VENDOR_NAME}"
|
|
||||||
BACNET_PROTOCOL_REVISION=${CONFIG_BACNET_PROTOCOL_REVISION}
|
|
||||||
BACNET_STACK_DEPRECATED_DISABLE=1
|
|
||||||
# datalink API
|
|
||||||
$<$<BOOL:${CONFIG_BACDL_NONE}>:BACDL_NONE>
|
|
||||||
$<$<BOOL:${CONFIG_BACDL_ALL}>:BACAPP_ALL>
|
|
||||||
$<$<BOOL:${CONFIG_BACDL_BIP}>:BACDL_BIP>
|
|
||||||
$<$<BOOL:${CONFIG_BACDL_BIP_PORT}>:BACDL_BIP_PORT=${CONFIG_BACDL_BIP_PORT}>
|
|
||||||
$<$<BOOL:${CONFIG_MAX_BBMD_ENTRIES}>:MAX_BBMD_ENTRIES=${CONFIG_MAX_BBMD_ENTRIES}>
|
|
||||||
$<$<BOOL:${CONFIG_MAX_FD_ENTRIES}>:MAX_FD_ENTRIES=${CONFIG_MAX_FD_ENTRIES}>
|
|
||||||
$<$<BOOL:${CONFIG_BACDL_BIP6}>:BACDL_BIP6>
|
|
||||||
$<$<BOOL:${CONFIG_BACDL_ARCNET}>:BACDL_ARCNET>
|
|
||||||
$<$<BOOL:${CONFIG_BACDL_MSTP}>:BACDL_MSTP>
|
|
||||||
$<$<BOOL:${CONFIG_BACDL_ETHERNET}>:BACDL_ETHERNET>
|
|
||||||
$<$<BOOL:${CONFIG_BACDL_CUSTOM}>:BACDL_CUSTOM>
|
|
||||||
|
|
||||||
# library features
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_BASIC_OBJECTS}>:BACNET_BASIC_OBJECTS>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_PROPERTY_LISTS}>:BACNET_PROPERTY_LISTS=1>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_PROPERTY_ARRAY_LISTS}>:BACNET_PROPERTY_ARRAY_LISTS=1>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_ROUTING}>:BACNET_ROUTING>
|
|
||||||
$<$<BOOL:${CONFIG_BACAPP_PRINT_ENABLED}>:BACAPP_PRINT_ENABLED=1>
|
|
||||||
$<$<BOOL:${CONFIG_BACAPP_SNPRINTF_ENABLED}>:BACAPP_SNPRINTF_ENABLED=1>
|
|
||||||
$<$<BOOL:${CONFIG_BACNET_ADDRESS_CACHE_FILE}>:BACNET_ADDRESS_CACHE_FILE=1>
|
|
||||||
MAX_TSM_TRANSACTIONS=${CONFIG_BACNET_MAX_TSM_TRANSACTIONS}
|
|
||||||
MAX_ADDRESS_CACHE=${CONFIG_BACNET_MAX_ADDRESS_CACHE}
|
|
||||||
MAX_CHARACTER_STRING_BYTES=${CONFIG_BACNET_MAX_CHARACTER_STRING_BYTES}
|
|
||||||
MAX_OCTET_STRING_BYTES=${CONFIG_BACNET_MAX_OCTET_STRING_BYTES}
|
|
||||||
# BACnet data types supported for WriteProperty: all = minimal + extra
|
|
||||||
$<$<BOOL:${CONFIG_BACAPP_ALL}>:BACAPP_ALL>
|
|
||||||
$<$<BOOL:${CONFIG_BACAPP_MINIMAL}>:BACAPP_MINIMAL>
|
|
||||||
$<$<BOOL:${CONFIG_BACAPP_TYPES_EXTRA}>:BACAPP_TYPES_EXTRA>
|
|
||||||
# BACnet data types supported for WriteProperty: any individual overrides all
|
|
||||||
$<$<BOOL:${CONFIG_BACAPP_NULL}>:BACAPP_NULL>
|
|
||||||
$<$<BOOL:${CONFIG_BACAPP_BOOLEAN}>:BACAPP_BOOLEAN>
|
|
||||||
$<$<BOOL:${CONFIG_BACAPP_UNSIGNED}>:BACAPP_UNSIGNED>
|
|
||||||
$<$<BOOL:${CONFIG_BACAPP_SIGNED}>:BACAPP_SIGNED>
|
|
||||||
$<$<BOOL:${CONFIG_BACAPP_REAL}>:BACAPP_REAL>
|
|
||||||
$<$<BOOL:${CONFIG_BACAPP_DOUBLE}>:BACAPP_DOUBLE>
|
|
||||||
$<$<BOOL:${CONFIG_BACAPP_OCTET_STRING}>:BACAPP_OCTET_STRING>
|
|
||||||
$<$<BOOL:${CONFIG_BACAPP_CHARACTER_STRING}>:BACAPP_CHARACTER_STRING>
|
|
||||||
$<$<BOOL:${CONFIG_BACAPP_BIT_STRING}>:BACAPP_BIT_STRING>
|
|
||||||
$<$<BOOL:${CONFIG_BACAPP_ENUMERATED}>:BACAPP_ENUMERATED>
|
|
||||||
$<$<BOOL:${CONFIG_BACAPP_DATE}>:BACAPP_DATE>
|
|
||||||
$<$<BOOL:${CONFIG_BACAPP_TIME}>:BACAPP_TIME>
|
|
||||||
$<$<BOOL:${CONFIG_BACAPP_OBJECT_ID}>:BACAPP_OBJECT_ID>
|
|
||||||
$<$<BOOL:${CONFIG_BACAPP_DATETIME}>:BACAPP_DATETIME>
|
|
||||||
$<$<BOOL:${CONFIG_BACAPP_DATERANGE}>:BACAPP_DATERANGE>
|
|
||||||
$<$<BOOL:${CONFIG_BACAPP_LIGHTING_COMMAND}>:BACAPP_LIGHTING_COMMAND>
|
|
||||||
$<$<BOOL:${CONFIG_BACAPP_XY_COLOR}>:BACAPP_XY_COLOR>
|
|
||||||
$<$<BOOL:${CONFIG_BACAPP_COLOR_COMMAND}>:BACAPP_COLOR_COMMAND>
|
|
||||||
$<$<BOOL:${CONFIG_BACAPP_WEEKLY_SCHEDULE}>:BACAPP_WEEKLY_SCHEDULE>
|
|
||||||
$<$<BOOL:${CONFIG_BACAPP_HOST_N_PORT}>:BACAPP_HOST_N_PORT>
|
|
||||||
$<$<BOOL:${CONFIG_BACAPP_DEVICE_OBJECT_PROPERTY_REFERENCE}>:BACAPP_DEVICE_OBJECT_PROPERTY_REFERENCE>
|
|
||||||
$<$<BOOL:${CONFIG_BACAPP_DEVICE_OBJECT_REFERENCE}>:BACAPP_DEVICE_OBJECT_REFERENCE>
|
|
||||||
$<$<BOOL:${CONFIG_BACAPP_OBJECT_PROPERTY_REFERENCE}>:BACAPP_OBJECT_PROPERTY_REFERENCE>
|
|
||||||
$<$<BOOL:${CONFIG_BACAPP_DESTINATION}>:BACAPP_DESTINATION>
|
|
||||||
$<$<BOOL:${CONFIG_BACAPP_CALENDAR_ENTRY}>:BACAPP_CALENDAR_ENTRY>
|
|
||||||
$<$<BOOL:${CONFIG_BACAPP_SPECIAL_EVENT}>:BACAPP_SPECIAL_EVENT>
|
|
||||||
$<$<BOOL:${CONFIG_BACAPP_BDT_ENTRY}>:BACAPP_BDT_ENTRY>
|
|
||||||
$<$<BOOL:${CONFIG_BACAPP_FDT_ENTRY}>:BACAPP_FDT_ENTRY>
|
|
||||||
$<$<BOOL:${CONFIG_BACAPP_ACTION_COMMAND}>:BACAPP_ACTION_COMMAND>
|
|
||||||
$<$<BOOL:${CONFIG_BACAPP_SCALE}>:BACAPP_SCALE>
|
|
||||||
$<$<BOOL:${CONFIG_BACAPP_SHED_LEVEL}>:BACAPP_SHED_LEVEL>
|
|
||||||
)
|
|
||||||
-629
@@ -1,629 +0,0 @@
|
|||||||
# Feature configuration options for BACnet-Stack
|
|
||||||
|
|
||||||
# Copyright (c) 2020 Legrand North America, LLC.
|
|
||||||
# SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
menuconfig BACNETSTACK
|
|
||||||
bool "BACnet-Stack Support"
|
|
||||||
select REQUIRES_FULL_LIBC
|
|
||||||
help
|
|
||||||
This option enables the BACnet-Stack BACnet library.
|
|
||||||
|
|
||||||
if BACNETSTACK
|
|
||||||
|
|
||||||
config BACNETSTACK_LOG_LEVEL
|
|
||||||
int "Log level for BACnet Stack"
|
|
||||||
default 1
|
|
||||||
help
|
|
||||||
BACnet Stack log level where 0=none, 1=error, 2=warning, 3=info, 4=debug
|
|
||||||
|
|
||||||
module = BACNETSTACK
|
|
||||||
module-str = Log level for BACnet
|
|
||||||
module-help = Enable BACnet library to output debug messages
|
|
||||||
source "$(ZEPHYR_BASE)/subsys/logging/Kconfig.template.log_config"
|
|
||||||
|
|
||||||
config BACNET_VENDOR_NAME
|
|
||||||
string "BACnet Vendor Name"
|
|
||||||
default "BACnet Stack at SourceForge"
|
|
||||||
help
|
|
||||||
BACnet Vendor Name string
|
|
||||||
|
|
||||||
config BACNET_VENDOR_IDENTIFIER
|
|
||||||
int "BACnet Vendor Identifier"
|
|
||||||
default 260
|
|
||||||
help
|
|
||||||
BACnet Vendir Identifier
|
|
||||||
|
|
||||||
config BACNET_PROTOCOL_REVISION
|
|
||||||
int "BACnet Stack protocol-revision number"
|
|
||||||
default 24
|
|
||||||
help
|
|
||||||
BACnet Stack protocol-revision number
|
|
||||||
|
|
||||||
config BAC_ROUTING
|
|
||||||
bool "BACnet Routing"
|
|
||||||
help
|
|
||||||
Enable BACnet routing
|
|
||||||
|
|
||||||
config BACNET_PROPERTY_LISTS
|
|
||||||
bool "BACnet Property Lists"
|
|
||||||
help
|
|
||||||
Enable BACnet Property Lists
|
|
||||||
|
|
||||||
config BACNET_PROPERTY_ARRAY_LISTS
|
|
||||||
bool "BACnetARRAY Property Lists"
|
|
||||||
default true
|
|
||||||
help
|
|
||||||
Enable BACnetARRAY Property Lists
|
|
||||||
|
|
||||||
config BACDL_ETHERNET
|
|
||||||
bool "BACnet Ethernet datalink"
|
|
||||||
help
|
|
||||||
Enable BACnet Ethernet datalink
|
|
||||||
|
|
||||||
config BACDL_MSTP
|
|
||||||
bool "BACnet MSTP datalink"
|
|
||||||
help
|
|
||||||
Enable BACnet MSTP datalink
|
|
||||||
|
|
||||||
config BACDL_ARCNET
|
|
||||||
bool "BACnet ARCNET datalink"
|
|
||||||
help
|
|
||||||
Enable BACnet ARCNET datalink
|
|
||||||
|
|
||||||
config BACDL_BIP
|
|
||||||
bool "BACnet BIP datalink"
|
|
||||||
select NETWORKING
|
|
||||||
select NET_SOCKETS
|
|
||||||
select NET_UDP
|
|
||||||
select NET_IPV4
|
|
||||||
help
|
|
||||||
Enable BACnet BIP datalink
|
|
||||||
|
|
||||||
config BACDL_BIP6
|
|
||||||
bool "BACnet BIP6"
|
|
||||||
help
|
|
||||||
Enable BACnet BIP6
|
|
||||||
|
|
||||||
config BACDL_NONE
|
|
||||||
bool "BACnet without datalink"
|
|
||||||
help
|
|
||||||
Enable BACnet without datalink
|
|
||||||
|
|
||||||
config BACDL_CUSTOM
|
|
||||||
bool "BACnet with custom datalink enabled"
|
|
||||||
help
|
|
||||||
Enable BACnet with custom datalink enabled
|
|
||||||
|
|
||||||
config BACDL_ALL
|
|
||||||
bool "BACnet with all datalinks enabled"
|
|
||||||
help
|
|
||||||
Enable BACnet with all datalinks enabled
|
|
||||||
|
|
||||||
config BACAPP_ALL
|
|
||||||
bool "BACnet data types supported for WriteProperty: all = minimal + extra"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
BACnet data types supported for WriteProperty: all = minimal + extra
|
|
||||||
|
|
||||||
config BACAPP_MINIMAL
|
|
||||||
bool "BACnet data types supported for WriteProperty: minimal"
|
|
||||||
default true
|
|
||||||
help
|
|
||||||
BACnet data types supported for WriteProperty include:
|
|
||||||
NULL, BOOLEAN, UNSIGNED, SIGNED, REAL, CHARACTER_STRING,
|
|
||||||
OCTET_STRING, BIT_STRING, ENUMERATED, DATE, TIME, OBJECT_ID
|
|
||||||
|
|
||||||
config BACAPP_TYPES_EXTRA
|
|
||||||
bool "BACnet data types supported for WriteProperty: extra"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
BACnet data types supported for WriteProperty include:
|
|
||||||
DOUBLE, TIMESTAMP, DATETIME, DATERANGE,
|
|
||||||
LIGHTING_COMMAND, XY_COLOR, COLOR_COMMAND, WEEKLY_SCHEDULE,
|
|
||||||
CALENDAR_ENTRY, SPECIAL_EVENT, HOST_N_PORT,
|
|
||||||
DEVICE_OBJECT_PROPERTY_REFERENCE, DEVICE_OBJECT_REFERENCE,
|
|
||||||
OBJECT_PROPERTY_REFERENCE, DESTINATION, BDT_ENTRY, FDT_ENTRY,
|
|
||||||
ACTION_COMMAND, SCALE, SHED_LEVEL
|
|
||||||
|
|
||||||
config BACAPP_NULL
|
|
||||||
bool "BACnet data types supported for WriteProperty: NULL"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
BACnet data types supported for WriteProperty: NULL
|
|
||||||
|
|
||||||
config BACAPP_BOOLEAN
|
|
||||||
bool "BACnet data types supported for WriteProperty: BOOLEAN"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
BACnet data types supported for WriteProperty: BOOLEAN
|
|
||||||
|
|
||||||
config BACAPP_UNSIGNED
|
|
||||||
bool "BACnet data types supported for WriteProperty: UNSIGNED"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
BACnet data types supported for WriteProperty: UNSIGNED
|
|
||||||
|
|
||||||
config BACAPP_SIGNED
|
|
||||||
bool "BACnet data types supported for WriteProperty: SIGNED"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
BACnet data types supported for WriteProperty: SIGNED
|
|
||||||
|
|
||||||
config BACAPP_REAL
|
|
||||||
bool "BACnet data types supported for WriteProperty: REAL"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
BACnet data types supported for WriteProperty: REAL
|
|
||||||
|
|
||||||
config BACAPP_DOUBLE
|
|
||||||
bool "BACnet data types supported for WriteProperty: DOUBLE"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
BACnet data types supported for WriteProperty: DOUBLE
|
|
||||||
|
|
||||||
config BACAPP_OCTET_STRING
|
|
||||||
bool "BACnet data types supported for WriteProperty: OCTET_STRING"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
BACnet data types supported for WriteProperty: OCTET_STRING
|
|
||||||
|
|
||||||
config BACAPP_CHARACTER_STRING
|
|
||||||
bool "BACnet data types supported for WriteProperty: CHARACTER_STRING"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
BACnet data types supported for WriteProperty: CHARACTER_STRING
|
|
||||||
|
|
||||||
config BACAPP_BIT_STRING
|
|
||||||
bool "BACnet data types supported for WriteProperty: BIT_STRING"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
BACnet data types supported for WriteProperty: BIT_STRING
|
|
||||||
|
|
||||||
config BACAPP_ENUMERATED
|
|
||||||
bool "BACnet data types supported for WriteProperty: ENUMERATED"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
BACnet data types supported for WriteProperty: ENUMERATED
|
|
||||||
|
|
||||||
config BACAPP_DATE
|
|
||||||
bool "BACnet data types supported for WriteProperty: DATE"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
BACnet data types supported for WriteProperty: DATE
|
|
||||||
|
|
||||||
config BACAPP_TIME
|
|
||||||
bool "BACnet data types supported for WriteProperty: TIME"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
BACnet data types supported for WriteProperty: TIME
|
|
||||||
|
|
||||||
config BACAPP_OBJECT_ID
|
|
||||||
bool "BACnet data types supported for WriteProperty: OBJECT_ID"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
BACnet data types supported for WriteProperty: OBJECT_ID
|
|
||||||
|
|
||||||
config BACAPP_DATETIME
|
|
||||||
bool "BACnet data types supported for WriteProperty: DATETIME"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
BACnet data types supported for WriteProperty: DATETIME
|
|
||||||
|
|
||||||
config BACAPP_DATERANGE
|
|
||||||
bool "BACnet data types supported for WriteProperty: DATERANGE"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
BACnet data types supported for WriteProperty: DATERANGE
|
|
||||||
|
|
||||||
config BACAPP_LIGHTING_COMMAND
|
|
||||||
bool "BACnet data types supported for WriteProperty: LIGHTING_COMMAND"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
BACnet data types supported for WriteProperty: LIGHTING_COMMAND
|
|
||||||
|
|
||||||
config BACAPP_XY_COLOR
|
|
||||||
bool "BACnet data types supported for WriteProperty: XY_COLOR"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
BACnet data types supported for WriteProperty: XY_COLOR
|
|
||||||
|
|
||||||
config BACAPP_COLOR_COMMAND
|
|
||||||
bool "BACnet data types supported for WriteProperty: COLOR_COMMAND"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
BACnet data types supported for WriteProperty: COLOR_COMMAND
|
|
||||||
|
|
||||||
config BACAPP_WEEKLY_SCHEDULE
|
|
||||||
bool "BACnet data types supported for WriteProperty: WEEKLY_SCHEDULE"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
BACnet data types supported for WriteProperty: WEEKLY_SCHEDULE
|
|
||||||
|
|
||||||
config BACAPP_CALENDAR_ENTRY
|
|
||||||
bool "BACnet data types supported for WriteProperty: CALENDAR_ENTRY"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
BACnet data types supported for WriteProperty: CALENDAR_ENTRY
|
|
||||||
|
|
||||||
config BACAPP_SPECIAL_EVENT
|
|
||||||
bool "BACnet data types supported for WriteProperty: SPECIAL_EVENT"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
BACnet data types supported for WriteProperty: SPECIAL_EVENT
|
|
||||||
|
|
||||||
config BACAPP_HOST_N_PORT
|
|
||||||
bool "BACnet data types supported for WriteProperty: HOST_N_PORT"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
BACnet data types supported for WriteProperty: HOST_N_PORT
|
|
||||||
|
|
||||||
config BACAPP_DEVICE_OBJECT_PROPERTY_REFERENCE
|
|
||||||
bool "BACnet data types supported for WriteProperty: DEVICE_OBJECT_PROPERTY_REFERENCE"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
BACnet data types supported for WriteProperty: DEVICE_OBJECT_PROPERTY_REFERENCE
|
|
||||||
|
|
||||||
config BACAPP_DEVICE_OBJECT_REFERENCE
|
|
||||||
bool "BACnet data types supported for WriteProperty: DEVICE_OBJECT_REFERENCE"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
BACnet data types supported for WriteProperty: DEVICE_OBJECT_REFERENCE
|
|
||||||
|
|
||||||
config BACAPP_OBJECT_PROPERTY_REFERENCE
|
|
||||||
bool "BACnet data types supported for WriteProperty: OBJECT_PROPERTY_REFERENCE"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
BACnet data types supported for WriteProperty: OBJECT_PROPERTY_REFERENCE
|
|
||||||
|
|
||||||
config BACAPP_DESTINATION
|
|
||||||
bool "BACnet data types supported for WriteProperty: DESTINATION"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
BACnet data types supported for WriteProperty: DESTINATION
|
|
||||||
|
|
||||||
config BACAPP_BDT_ENTRY
|
|
||||||
bool "BACnet data types supported for WriteProperty: BDT_ENTRY"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
BACnet data types supported for WriteProperty: BDT_ENTRY
|
|
||||||
|
|
||||||
config BACAPP_FDT_ENTRY
|
|
||||||
bool "BACnet data types supported for WriteProperty: FDT_ENTRY"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
BACnet data types supported for WriteProperty: FDT_ENTRY
|
|
||||||
|
|
||||||
config BACAPP_ACTION_COMMAND
|
|
||||||
bool "BACnet data types supported for WriteProperty: BACAPP_ACTION_COMMAND"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
BACnet data types supported for WriteProperty: BACAPP_ACTION_COMMAND
|
|
||||||
|
|
||||||
config BACAPP_SCALE
|
|
||||||
bool "BACnet data types supported for WriteProperty: BACAPP_SCALE"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
BACnet data types supported for WriteProperty: BACAPP_SCALE
|
|
||||||
|
|
||||||
config BACAPP_SHED_LEVEL
|
|
||||||
bool "BACnet data types supported for WriteProperty: BACAPP_SHED_LEVEL"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
BACnet data types supported for WriteProperty: BACAPP_SHED_LEVEL
|
|
||||||
|
|
||||||
config BACAPP_PRINT_ENABLED
|
|
||||||
bool "BACnet app print"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
Enable BACnet app print
|
|
||||||
|
|
||||||
config BACAPP_SNPRINTF_ENABLED
|
|
||||||
bool "BACnet app snprintf"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
Enable BACnet app snprintf
|
|
||||||
|
|
||||||
config BACDL_BIP_PORT
|
|
||||||
int "BACnet IPv4 UDP port"
|
|
||||||
default 47808
|
|
||||||
depends on BACDL_BIP
|
|
||||||
help
|
|
||||||
UDP port to listen on (default=47808)
|
|
||||||
|
|
||||||
config MAX_BBMD_ENTRIES
|
|
||||||
int "Maximum number of Broadcast Device Table entries"
|
|
||||||
default 5
|
|
||||||
depends on BACDL_BIP
|
|
||||||
help
|
|
||||||
Maximum number of Broadcast Device Table entries
|
|
||||||
|
|
||||||
config MAX_FD_ENTRIES
|
|
||||||
int "Maximum number of Foreign Device Table entries"
|
|
||||||
default 5
|
|
||||||
depends on BACDL_BIP
|
|
||||||
help
|
|
||||||
Maximum number of Foreign Device Table entries
|
|
||||||
|
|
||||||
config BACDL_BIP_ADDRESS_INDEX
|
|
||||||
int "Address index"
|
|
||||||
depends on BACDL_BIP
|
|
||||||
default 0
|
|
||||||
help
|
|
||||||
Select IPv4 address
|
|
||||||
|
|
||||||
config BACDL_BIP6_ADDRESS_INDEX
|
|
||||||
int "Unicast address index"
|
|
||||||
depends on BACDL_BIP6
|
|
||||||
default 0
|
|
||||||
help
|
|
||||||
Select IPv6 unicast address
|
|
||||||
|
|
||||||
config BACDL_BIP6_MCAST_ADDRESS
|
|
||||||
string "IPv6 multicast destination"
|
|
||||||
default "FF02::BAC0"
|
|
||||||
depends on BACDL_BIP6
|
|
||||||
help
|
|
||||||
IPv6 multicast group address for BACNET.
|
|
||||||
|
|
||||||
config BACDL_BIP6_PORT
|
|
||||||
int "BACnet IPv6 UDP port"
|
|
||||||
default 47808
|
|
||||||
depends on BACDL_BIP6
|
|
||||||
help
|
|
||||||
UDP port to listen on (default=47808)
|
|
||||||
|
|
||||||
config BACNET_MAX_TSM_TRANSACTIONS
|
|
||||||
int "Number of initiated confirmed-message transactions"
|
|
||||||
default 1
|
|
||||||
help
|
|
||||||
Number of initiated confirmed-message transactions
|
|
||||||
|
|
||||||
config BACNET_MAX_ADDRESS_CACHE
|
|
||||||
int "Number of address entries for I-Am bindings"
|
|
||||||
default 1
|
|
||||||
help
|
|
||||||
Number of address entries for I-Am bindings
|
|
||||||
|
|
||||||
config BACNET_MAX_CHARACTER_STRING_BYTES
|
|
||||||
int "Maximum number of bytes in a BACnet character string"
|
|
||||||
default 64
|
|
||||||
help
|
|
||||||
Maximum number of bytes in a BACnet character string
|
|
||||||
|
|
||||||
config BACNET_MAX_OCTET_STRING_BYTES
|
|
||||||
int "Maximum number of bytes in a BACnet octet string"
|
|
||||||
default 64
|
|
||||||
help
|
|
||||||
Maximum number of bytes in a BACnet octet string
|
|
||||||
|
|
||||||
config BACNET_STORAGE_BASE_NAME
|
|
||||||
string "BACnet storage base name for settings subsystem"
|
|
||||||
default "bacnet"
|
|
||||||
help
|
|
||||||
BACnet storage base name for settings subsystem
|
|
||||||
|
|
||||||
config BACNET_ADDRESS_CACHE_FILE
|
|
||||||
bool "BACnet Address Cache file functionality"
|
|
||||||
help
|
|
||||||
BACnet Address Cache file functionality
|
|
||||||
|
|
||||||
config BACNET_USE_SECTION_ITERABLE_OBJECT_TABLE
|
|
||||||
bool "Use the Section Iterable for the Object Table"
|
|
||||||
default true
|
|
||||||
help
|
|
||||||
Use the Section Iterable for the Object Table
|
|
||||||
|
|
||||||
config BACNET_BASIC_OBJECTS_ACCESS
|
|
||||||
bool "Use the BACnet basic access control objects"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
Use the BACnet basic access control objects
|
|
||||||
|
|
||||||
config BACNET_BASIC_OBJECT_ACCUMULATOR
|
|
||||||
bool "Use the BACnet basic accumulator object"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
Use the BACnet basic accumulator object
|
|
||||||
|
|
||||||
config BACNET_BASIC_OBJECT_ANALOG_INPUT
|
|
||||||
bool "Use the BACnet basic analog input object"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
Use the BACnet basic analog input object
|
|
||||||
|
|
||||||
config BACNET_BASIC_OBJECT_ANALOG_OUTPUT
|
|
||||||
bool "Use the BACnet basic analog output object"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
Use the BACnet basic analog output object
|
|
||||||
|
|
||||||
config BACNET_BASIC_OBJECT_ANALOG_VALUE
|
|
||||||
bool "Use the BACnet basic analog value object"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
Use the BACnet basic analog value object
|
|
||||||
|
|
||||||
config BACNET_BASIC_OBJECT_FILE
|
|
||||||
bool "Use the BACnet basic file object"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
Use the BACnet basic file object
|
|
||||||
|
|
||||||
config BACNET_BASIC_OBJECT_BINARY_INPUT
|
|
||||||
bool "Use the BACnet basic binary input object"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
Use the BACnet basic binary input object
|
|
||||||
|
|
||||||
config BACNET_BASIC_OBJECT_BINARY_OUTPUT
|
|
||||||
bool "Use the BACnet basic binary output object"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
Use the BACnet basic binary output object
|
|
||||||
|
|
||||||
config BACNET_BASIC_OBJECT_BINARY_VALUE
|
|
||||||
bool "Use the BACnet basic binary value object"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
Use the BACnet basic binary value object
|
|
||||||
|
|
||||||
config BACNET_BASIC_OBJECT_CALENDAR
|
|
||||||
bool "Use the BACnet basic calendar object"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
Use the BACnet basic calendar object
|
|
||||||
|
|
||||||
config BACNET_BASIC_OBJECT_CHANNEL
|
|
||||||
bool "Use the BACnet basic channel object"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
Use the BACnet basic channel object
|
|
||||||
|
|
||||||
config BACNET_BASIC_OBJECT_COMMAND
|
|
||||||
bool "Use the BACnet basic command object"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
Use the BACnet basic command object
|
|
||||||
|
|
||||||
config BACNET_BASIC_OBJECT_COLOR
|
|
||||||
bool "Use the BACnet basic color object"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
Use the BACnet basic color object
|
|
||||||
|
|
||||||
config BACNET_BASIC_OBJECT_COLOR_TEMPERATURE
|
|
||||||
bool "Use the BACnet basic color temperature object"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
Use the BACnet basic color temperature object
|
|
||||||
|
|
||||||
config BACNET_BASIC_OBJECT_CHARACTERSTRING_VALUE
|
|
||||||
bool "Use the BACnet basic character-string value object"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
Use the BACnet basic character-string value object
|
|
||||||
|
|
||||||
config BACNET_BASIC_OBJECT_DEVICE_SERVER
|
|
||||||
bool "Use the BACnet basic device-server object"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
Use the BACnet basic device-server object
|
|
||||||
|
|
||||||
config BACNET_BASIC_OBJECT_DEVICE_CLIENT
|
|
||||||
bool "Use the BACnet basic device-client object"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
Use the BACnet basic device-client object
|
|
||||||
|
|
||||||
config BACNET_BASIC_OBJECT_INTEGER_VALUE
|
|
||||||
bool "Use the BACnet basic integer value object"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
Use the BACnet basic integer value object
|
|
||||||
|
|
||||||
config BACNET_BASIC_OBJECT_LOAD_CONTROL
|
|
||||||
bool "Use the BACnet basic load control object"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
Use the BACnet basic load control object
|
|
||||||
|
|
||||||
config BACNET_BASIC_OBJECT_LIGHTING_OUTPUT
|
|
||||||
bool "Use the BACnet basic lighting output object"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
Use the BACnet basic lighting output object
|
|
||||||
|
|
||||||
config BACNET_BASIC_OBJECT_LIFE_SAFETY_POINT
|
|
||||||
bool "Use the BACnet basic life-safety point object"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
Use the BACnet basic life-safety point object
|
|
||||||
|
|
||||||
config BACNET_BASIC_OBJECT_MULTISTATE_INPUT
|
|
||||||
bool "Use the BACnet basic multistate input object"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
Use the BACnet basic multistate input object
|
|
||||||
|
|
||||||
config BACNET_BASIC_OBJECT_MULTISTATE_OUTPUT
|
|
||||||
bool "Use the BACnet basic multistate output object"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
Use the BACnet basic multistate output object
|
|
||||||
|
|
||||||
config BACNET_BASIC_OBJECT_MULTISTATE_VALUE
|
|
||||||
bool "Use the BACnet basic multistate value object"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
Use the BACnet basic multistate value object
|
|
||||||
|
|
||||||
config BACNET_BASIC_OBJECT_NOTIFICATION_CLASS
|
|
||||||
bool "Use the BACnet basic notification class object"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
Use the BACnet basic notification class object
|
|
||||||
|
|
||||||
config BACNET_BASIC_OBJECT_NETWORK_PORT
|
|
||||||
bool "Use the BACnet basic network port object"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
Use the BACnet basic network port object
|
|
||||||
|
|
||||||
config BACNET_BASIC_OBJECT_OCTET_STRING_VALUE
|
|
||||||
bool "Use the BACnet basic octet-string value object"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
Use the BACnet basic octet-string value object
|
|
||||||
|
|
||||||
config BACNET_BASIC_OBJECT_POSITIVE_INTEGER_VALUE
|
|
||||||
bool "Use the BACnet basic positive-integer value object"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
Use the BACnet basic positive-integer value object
|
|
||||||
|
|
||||||
config BACNET_BASIC_OBJECT_SCHEDULE
|
|
||||||
bool "Use the BACnet basic schedule object"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
Use the BACnet basic schedule object
|
|
||||||
|
|
||||||
config BACNET_BASIC_OBJECT_STRUCTURED_VIEW
|
|
||||||
bool "Use the BACnet basic structured view object"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
Use the BACnet basic structured view object
|
|
||||||
|
|
||||||
config BACNET_BASIC_OBJECT_TIME_VALUE
|
|
||||||
bool "Use the BACnet basic time value object"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
Use the BACnet basic time value object
|
|
||||||
|
|
||||||
config BACNET_BASIC_OBJECT_TRENDLOG
|
|
||||||
bool "Use the BACnet basic trendlog object"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
Use the BACnet basic trendlog object
|
|
||||||
|
|
||||||
# MINIMAL CONFIG_NET_RX_STACK_SIZE
|
|
||||||
config NET_TX_STACK_SIZE
|
|
||||||
int
|
|
||||||
default 8192 if BACDL_BIP
|
|
||||||
|
|
||||||
# MINIMAL CONFIG_NET_RX_STACK_SIZE
|
|
||||||
config NET_RX_STACK_SIZE
|
|
||||||
int
|
|
||||||
default 8192 if BACDL_BIP
|
|
||||||
|
|
||||||
config NET_IF_UNICAST_IPV4_ADDR_COUNT
|
|
||||||
int
|
|
||||||
default 4 if BACDL_BIP
|
|
||||||
|
|
||||||
config NET_IF_LOG_LEVEL_DGB
|
|
||||||
bool
|
|
||||||
default y if BACDL_BIP
|
|
||||||
|
|
||||||
rsource "subsys/Kconfig"
|
|
||||||
|
|
||||||
endif # BACNETSTACK
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
* @brief BACnet Basic Stack initialization and basic task handler
|
|
||||||
* @author Steve Karg <skarg@users.sourceforge.net>
|
|
||||||
* @date April 2024
|
|
||||||
* @copyright SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
#ifndef BACNET_BASIC_H
|
|
||||||
#define BACNET_BASIC_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
typedef void (*bacnet_basic_callback)(void *context);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
void bacnet_basic_init(void);
|
|
||||||
void bacnet_basic_init_callback_set(bacnet_basic_callback callback,
|
|
||||||
void *context);
|
|
||||||
|
|
||||||
void bacnet_basic_task(void);
|
|
||||||
void bacnet_basic_task_callback_set(bacnet_basic_callback callback,
|
|
||||||
void *context);
|
|
||||||
|
|
||||||
unsigned long bacnet_basic_uptime_seconds(void);
|
|
||||||
unsigned long bacnet_basic_packet_count(void);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
#endif
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
* @brief The BACnet datalink tasks for handling the device specific
|
|
||||||
* data link network port layer
|
|
||||||
* @author Steve Karg <skarg@users.sourceforge.net>
|
|
||||||
* @date April 2024
|
|
||||||
* @copyright SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
#ifndef BACNET_PORT_H
|
|
||||||
#define BACNET_PORT_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
/* BACnet Stack defines - first */
|
|
||||||
#include "bacnet/bacdef.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
bool bacnet_port_init(void);
|
|
||||||
void bacnet_port_task(void);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
#endif
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
* @brief API for the BACnet datalink tasks for handling the device specific
|
|
||||||
* data link network port layer
|
|
||||||
* @author Steve Karg <skarg@users.sourceforge.net>
|
|
||||||
* @date April 2024
|
|
||||||
* @copyright SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
#ifndef BACNET_PORT_IPV4_H
|
|
||||||
#define BACNET_PORT_IPV4_H
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
/* BACnet Stack defines - first */
|
|
||||||
#include "bacnet/bacdef.h"
|
|
||||||
#include "bacnet/datalink/bvlc.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
void bacnet_port_ipv4_foreign_device_init(
|
|
||||||
const uint16_t ttl_seconds,
|
|
||||||
const BACNET_IP_ADDRESS *bbmd_address);
|
|
||||||
void bacnet_port_ipv4_task(uint16_t elapsed_seconds);
|
|
||||||
bool bacnet_port_ipv4_init(void);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
#endif
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
* @brief The BACnet/IPv6 datalink tasks for handling the device specific
|
|
||||||
* data link network port layer
|
|
||||||
* @author Steve Karg <skarg@users.sourceforge.net>
|
|
||||||
* @date April 2024
|
|
||||||
* @copyright SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
#ifndef BACNET_PORT_IPV6_H
|
|
||||||
#define BACNET_PORT_IPV6_H
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
/* BACnet Stack defines - first */
|
|
||||||
#include "bacnet/bacdef.h"
|
|
||||||
#include "bacnet/datalink/bvlc6.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
void bacnet_port_ipv6_foreign_device_init(
|
|
||||||
const uint16_t ttl_seconds, const BACNET_IP6_ADDRESS *bbmd_address);
|
|
||||||
void bacnet_port_ipv6_task(uint16_t elapsed_seconds);
|
|
||||||
bool bacnet_port_ipv6_init(void);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
#endif
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
* @brief API for Get/Set of BACnet application encoded settings handlers
|
|
||||||
* @author Steve Karg <skarg@users.sourceforge.net>
|
|
||||||
* @date May 2024
|
|
||||||
* @copyright SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
#ifndef BACNET_SETTINGS_H
|
|
||||||
#define BACNET_SETTINGS_H
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "bacnet/bacdef.h"
|
|
||||||
#include "bacnet/bacapp.h"
|
|
||||||
#include "bacnet/bacstr.h"
|
|
||||||
#include "bacnet/bacint.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
int bacnet_settings_value_get(uint16_t object_type, uint32_t object_instance,
|
|
||||||
uint32_t property_id, uint32_t array_index,
|
|
||||||
BACNET_APPLICATION_DATA_VALUE *value);
|
|
||||||
bool bacnet_settings_value_set(uint16_t object_type, uint32_t object_instance,
|
|
||||||
uint32_t property_id, uint32_t array_index,
|
|
||||||
BACNET_APPLICATION_DATA_VALUE *value);
|
|
||||||
|
|
||||||
int bacnet_settings_real_get(uint16_t object_type, uint32_t object_instance,
|
|
||||||
uint32_t property_id, uint32_t array_index,
|
|
||||||
float default_value, float *value);
|
|
||||||
bool bacnet_settings_real_set(uint16_t object_type, uint32_t object_instance,
|
|
||||||
uint32_t property_id, uint32_t array_index,
|
|
||||||
float value);
|
|
||||||
|
|
||||||
int bacnet_settings_unsigned_get(uint16_t object_type, uint32_t object_instance,
|
|
||||||
uint32_t property_id, uint32_t array_index,
|
|
||||||
BACNET_UNSIGNED_INTEGER default_value,
|
|
||||||
BACNET_UNSIGNED_INTEGER *value);
|
|
||||||
bool bacnet_settings_unsigned_set(uint16_t object_type,
|
|
||||||
uint32_t object_instance,
|
|
||||||
uint32_t property_id, uint32_t array_index,
|
|
||||||
BACNET_UNSIGNED_INTEGER value);
|
|
||||||
|
|
||||||
int bacnet_settings_signed_get(uint16_t object_type, uint32_t object_instance,
|
|
||||||
uint32_t property_id, uint32_t array_index,
|
|
||||||
int32_t default_value, int32_t *value);
|
|
||||||
bool bacnet_settings_signed_set(uint16_t object_type, uint32_t object_instance,
|
|
||||||
uint32_t property_id, uint32_t array_index,
|
|
||||||
int32_t value);
|
|
||||||
|
|
||||||
int bacnet_settings_characterstring_get(uint16_t object_type,
|
|
||||||
uint32_t object_instance,
|
|
||||||
uint32_t property_id,
|
|
||||||
uint32_t array_index,
|
|
||||||
const char *default_value,
|
|
||||||
BACNET_CHARACTER_STRING *value);
|
|
||||||
|
|
||||||
bool bacnet_settings_characterstring_ansi_set(uint16_t object_type,
|
|
||||||
uint32_t object_instance,
|
|
||||||
uint32_t property_id,
|
|
||||||
uint32_t array_index,
|
|
||||||
const char *cstring);
|
|
||||||
|
|
||||||
int bacnet_settings_string_get(uint16_t object_type, uint32_t object_instance,
|
|
||||||
uint32_t property_id, uint32_t array_index,
|
|
||||||
const char *default_value, char *value,
|
|
||||||
size_t value_size);
|
|
||||||
|
|
||||||
bool bacnet_settings_string_set(uint16_t object_type, uint32_t object_instance,
|
|
||||||
uint32_t property_id, uint32_t array_index,
|
|
||||||
const char *value);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
#endif
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
* @brief API for the BACnet storage tasks for handling the device specific
|
|
||||||
* non-volatile object data
|
|
||||||
* @author Steve Karg <skarg@users.sourceforge.net>
|
|
||||||
* @date May 2024
|
|
||||||
* @copyright SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
#ifndef BACNET_STORAGE_H
|
|
||||||
#define BACNET_STORAGE_H
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <zephyr/settings/settings.h>
|
|
||||||
|
|
||||||
#define BACNET_STORAGE_VALUE_SIZE_MAX SETTINGS_MAX_VAL_LEN
|
|
||||||
#define BACNET_STORAGE_KEY_SIZE_MAX SETTINGS_MAX_NAME_LEN
|
|
||||||
#define BACNET_STORAGE_ARRAY_INDEX_NONE UINT32_MAX
|
|
||||||
|
|
||||||
typedef struct bacnet_storage_key_t {
|
|
||||||
uint16_t object_type;
|
|
||||||
uint32_t object_instance;
|
|
||||||
uint32_t property_id;
|
|
||||||
uint32_t array_index;
|
|
||||||
} BACNET_STORAGE_KEY;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
void bacnet_storage_init(void);
|
|
||||||
|
|
||||||
void bacnet_storage_key_init(BACNET_STORAGE_KEY *key, uint16_t object_type,
|
|
||||||
uint32_t object_instance, uint32_t property_id,
|
|
||||||
uint32_t array_index);
|
|
||||||
int bacnet_storage_key_encode(char *buffer, size_t buffer_size,
|
|
||||||
BACNET_STORAGE_KEY *key);
|
|
||||||
int bacnet_storage_set(BACNET_STORAGE_KEY *key, const void *data,
|
|
||||||
size_t data_size);
|
|
||||||
int bacnet_storage_get(BACNET_STORAGE_KEY *key, void *data, size_t data_size);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
#endif
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
#
|
|
||||||
# Copyright (c) 2020 Legrand North America, LLC.
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
name: bacnet
|
|
||||||
build:
|
|
||||||
cmake: zephyr
|
|
||||||
kconfig: zephyr/Kconfig
|
|
||||||
samples:
|
|
||||||
- zephyr/samples
|
|
||||||
tests:
|
|
||||||
- zephyr/tests
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
# SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.13.1)
|
|
||||||
|
|
||||||
get_filename_component(MY_PROJECT_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
|
||||||
|
|
||||||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
|
||||||
project(${MY_PROJECT_NAME})
|
|
||||||
|
|
||||||
target_sources(app PRIVATE src/main.c)
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
.. _hello_bacnet_stack:
|
|
||||||
|
|
||||||
Hello BACnet-Stack
|
|
||||||
##################
|
|
||||||
|
|
||||||
Overview
|
|
||||||
********
|
|
||||||
|
|
||||||
A simple sample that can be used with any :ref:`supported board <boards>` and
|
|
||||||
prints "Hello BACnet-Stack" to the console.
|
|
||||||
|
|
||||||
Building and Running
|
|
||||||
********************
|
|
||||||
|
|
||||||
This application can be built and executed on QEMU as follows:
|
|
||||||
|
|
||||||
.. zephyr-app-commands::
|
|
||||||
:zephyr-app: samples/hello_bacnet_stack
|
|
||||||
:host-os: unix
|
|
||||||
:board: qemu_x86
|
|
||||||
:goals: run
|
|
||||||
:compact:
|
|
||||||
|
|
||||||
To build for another board, change "qemu_x86" above to that board's name.
|
|
||||||
|
|
||||||
Sample Output
|
|
||||||
=============
|
|
||||||
|
|
||||||
.. code-block:: console
|
|
||||||
|
|
||||||
Hello BACnet-Stack! x86
|
|
||||||
|
|
||||||
Exit QEMU by pressing :kbd:`CTRL+A` :kbd:`x`.
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
# nothing here
|
|
||||||
CONFIG_BACNETSTACK=y
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
sample:
|
|
||||||
description: Hello BACnet-Stack sample, the simplest BACnet-Stack
|
|
||||||
application
|
|
||||||
name: hello BACnet-Stack
|
|
||||||
common:
|
|
||||||
tags: introduction
|
|
||||||
harness: console
|
|
||||||
harness_config:
|
|
||||||
type: one_line
|
|
||||||
regex:
|
|
||||||
- "Hello BACnet-Stack! (.*)"
|
|
||||||
tests:
|
|
||||||
bacnet-stack.sample.basic.hello_bacnet_stack:
|
|
||||||
platform_allow: native_posix
|
|
||||||
tags: introduction
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2020 Legrand North America, LLC.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <zephyr/kernel.h>
|
|
||||||
#include <zephyr/sys/printk.h>
|
|
||||||
|
|
||||||
void main(void)
|
|
||||||
{
|
|
||||||
printk("Hello BACnet-Stack! %s\n", CONFIG_BOARD);
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
# SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.13.1)
|
|
||||||
|
|
||||||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
|
||||||
project(b-ss)
|
|
||||||
|
|
||||||
target_sources(app PRIVATE src/main.c)
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
.. _b-ss_sample:
|
|
||||||
|
|
||||||
BACnet Profile B-SS Sample
|
|
||||||
##########################
|
|
||||||
|
|
||||||
Overview
|
|
||||||
********
|
|
||||||
|
|
||||||
This is a simple application demonstrating configuration of a
|
|
||||||
BACnet B-SS (simple sensor) device profile.
|
|
||||||
|
|
||||||
Requirements
|
|
||||||
************
|
|
||||||
|
|
||||||
* A board with Ethernet support, for instance: mimxrt1064_evk
|
|
||||||
|
|
||||||
Building and Running
|
|
||||||
********************
|
|
||||||
|
|
||||||
This sample can be found under :bacnet_file:`samples/profiles/b-ss` in
|
|
||||||
the BACnet tree.
|
|
||||||
|
|
||||||
The sample can be built for several platforms.
|
|
||||||
|
|
||||||
|
|
||||||
QEMU testing
|
|
||||||
************
|
|
||||||
|
|
||||||
The main logic of work can be found at the link
|
|
||||||
https://docs.zephyrproject.org/3.0.0/guides/networking/qemu_setup.html
|
|
||||||
|
|
||||||
Steps to testing
|
|
||||||
1 Load and make net-tools:
|
|
||||||
git clone https://github.com/zephyrproject-rtos/net-tools
|
|
||||||
cd net-tools
|
|
||||||
make
|
|
||||||
2 Run net-tools loops in two termitals:
|
|
||||||
first: cd ~/net-tools && ./loop-socat.sh
|
|
||||||
second: cd ~/net-tools && sudo ./loop-slip-tap.sh
|
|
||||||
3 Configure prj.conf
|
|
||||||
The net-tools creates and uses network 192.0.2.0/24 as `tap0` interface.
|
|
||||||
Need change prj.conf:
|
|
||||||
CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.0.2.1"
|
|
||||||
CONFIG_NET_CONFIG_PEER_IPV4_ADDR="192.0.2.2"
|
|
||||||
4 Set BACNET_IFACE to tap0:
|
|
||||||
export BACNET_IFACE=tap0
|
|
||||||
5 Compile and run b-ss profile:
|
|
||||||
west build -b qemu_x86 -p always -t run bacnet-stack/zephyr/samples/profiles/b-ss/
|
|
||||||
6 Run bacnet-stack app tools as a test tool, like readprop:
|
|
||||||
bacnet-stack/apps/readprop/bacrp --mac 192.0.2.1:47808 55 17 1 77
|
|
||||||
here:
|
|
||||||
17 - OBJECT_SCHEDULE
|
|
||||||
1 - schedule index
|
|
||||||
77 - PROP_OBJECT_NAME
|
|
||||||
expected result - string:
|
|
||||||
"SCHEDULE 1"
|
|
||||||
@@ -1,131 +0,0 @@
|
|||||||
# General config
|
|
||||||
#CONFIG_ASSERT=y
|
|
||||||
#CONFIG_ASSERT_LEVEL=2
|
|
||||||
#CONFIG_ASSERT_VERBOSE=y
|
|
||||||
|
|
||||||
# Compiler library config
|
|
||||||
#CONFIG_PICOLIBC=y
|
|
||||||
#CONFIG_PICOLIBC_USE_MODULE=y
|
|
||||||
#CONFIG_REQUIRES_FULL_LIBC=y
|
|
||||||
#CONFIG_MINIMAL_LIBC=y
|
|
||||||
|
|
||||||
# system
|
|
||||||
# some heap is needed for the shell
|
|
||||||
CONFIG_HEAP_MEM_POOL_SIZE=2048
|
|
||||||
CONFIG_KERNEL_MEM_POOL=y
|
|
||||||
CONFIG_MAIN_THREAD_PRIORITY=7
|
|
||||||
#CONFIG_PICOLIBC=y
|
|
||||||
CONFIG_ISR_STACK_SIZE=8192
|
|
||||||
CONFIG_MAIN_STACK_SIZE=8192
|
|
||||||
CONFIG_IDLE_STACK_SIZE=2048
|
|
||||||
CONFIG_INIT_STACKS=y
|
|
||||||
|
|
||||||
# BACnet Library
|
|
||||||
CONFIG_BACNETSTACK=y
|
|
||||||
CONFIG_BACNETSTACK_BACNET_BASIC=y
|
|
||||||
# BACnet Library - options
|
|
||||||
CONFIG_BACNET_MAX_CHARACTER_STRING_BYTES=128
|
|
||||||
CONFIG_BACAPP_MINIMAL=y
|
|
||||||
CONFIG_BACAPP_HOST_N_PORT=y
|
|
||||||
CONFIG_BACNET_PROPERTY_ARRAY_LISTS=y
|
|
||||||
# BACnet Library - objects
|
|
||||||
CONFIG_BACNET_BASIC_OBJECT_NETWORK_PORT=y
|
|
||||||
CONFIG_BACNET_BASIC_OBJECT_ANALOG_INPUT=y
|
|
||||||
# BACnet Library - shell
|
|
||||||
CONFIG_BACNET_BASIC_DEVICE_SHELL=y
|
|
||||||
# BACnet settings subsystem
|
|
||||||
#CONFIG_BACNETSTACK_BACNET_SETTINGS=y
|
|
||||||
#CONFIG_BACNET_SETTINGS=y
|
|
||||||
#CONFIG_BACNET_SETTINGS_SHELL=y
|
|
||||||
|
|
||||||
# BIP Options
|
|
||||||
CONFIG_BACDL_BIP=y
|
|
||||||
CONFIG_BACDL_BIP_PORT=47808
|
|
||||||
CONFIG_BACDL_BIP_ADDRESS_INDEX=0
|
|
||||||
CONFIG_NET_IPV4=y
|
|
||||||
CONFIG_NET_DHCPV4=y
|
|
||||||
CONFIG_NET_IPV4_AUTO=y
|
|
||||||
#CONFIG_NET_CONFIG_SETTINGS=y
|
|
||||||
#CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.168.1.80"
|
|
||||||
#CONFIG_NET_CONFIG_MY_IPV4_NETMASK="255.255.255.0"
|
|
||||||
#CONFIG_NET_CONFIG_MY_IPV4_GW="192.168.1.1"
|
|
||||||
#CONFIG_NET_CONFIG_PEER_IPV4_ADDR="192.168.1.1"
|
|
||||||
CONFIG_NET_IF_UNICAST_IPV4_ADDR_COUNT=4
|
|
||||||
|
|
||||||
# BIP6 Options
|
|
||||||
#CONFIG_BACDL_BIP6=y
|
|
||||||
#CONFIG_BACDL_BIP6_PORT=47808
|
|
||||||
#CONFIG_BACDL_BIP6_ADDRESS_INDEX=0
|
|
||||||
#CONFIG_BACDL_BIP6_MCAST_ADDRESS="FE80::0020"
|
|
||||||
#CONFIG_NET_IPV6=y
|
|
||||||
#CONFIG_NET_IPV6_MLD=y
|
|
||||||
#CONFIG_NET_CONFIG_MY_IPV6_ADDR="FE80::0010"
|
|
||||||
#CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=4
|
|
||||||
#CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT=4
|
|
||||||
|
|
||||||
# networking
|
|
||||||
CONFIG_NETWORKING=y
|
|
||||||
#CONFIG_NET_ARP=y
|
|
||||||
#CONFIG_NET_TCP=y
|
|
||||||
CONFIG_NET_UDP=y
|
|
||||||
CONFIG_NET_SHELL=y
|
|
||||||
CONFIG_NET_SOCKETS=y
|
|
||||||
|
|
||||||
#CONFIG_DNS_RESOLVER=y
|
|
||||||
#CONFIG_SLIP_STATISTICS=n
|
|
||||||
|
|
||||||
CONFIG_NET_TX_STACK_SIZE=8192
|
|
||||||
CONFIG_NET_RX_STACK_SIZE=8192
|
|
||||||
|
|
||||||
# Enable Shell, Console, and Logging features
|
|
||||||
CONFIG_CONSOLE=y
|
|
||||||
CONFIG_PRINTK=y
|
|
||||||
CONFIG_SHELL=y
|
|
||||||
CONFIG_KERNEL_SHELL=y
|
|
||||||
CONFIG_THREAD_MONITOR=y
|
|
||||||
#CONFIG_BOOT_BANNER=n
|
|
||||||
CONFIG_THREAD_NAME=y
|
|
||||||
CONFIG_DEVICE_SHELL=y
|
|
||||||
#CONFIG_POSIX_CLOCK=y
|
|
||||||
#CONFIG_DATE_SHELL=y
|
|
||||||
CONFIG_LOG=y
|
|
||||||
#CONFIG_LOG_STRDUP_BUF_COUNT=4
|
|
||||||
#CONFIG_LOG_STRDUP_MAX_STRING=96
|
|
||||||
#CONFIG_NET_CONN_LOG_LEVEL_DEFAULT=n
|
|
||||||
#CONFIG_NET_CONN_LOG_LEVEL_DBG=y
|
|
||||||
#CONFIG_NET_IF_LOG_LEVEL_DEFAULT=n
|
|
||||||
CONFIG_NET_IF_LOG_LEVEL_DBG=y
|
|
||||||
CONFIG_NET_LOG=y
|
|
||||||
CONFIG_BACNETSTACK_LOG_LEVEL_DBG=y
|
|
||||||
|
|
||||||
# enable the thread, stack, and runtime stats
|
|
||||||
#CONFIG_THREAD_ANALYZER=y
|
|
||||||
#CONFIG_THREAD_STACK_INFO=y
|
|
||||||
#CONFIG_THREAD_RUNTIME_STATS=y
|
|
||||||
#CONFIG_THREAD_RUNTIME_STATS_USE_TIMING_FUNCTIONS=n
|
|
||||||
#CONFIG_SCHED_THREAD_USAGE=y
|
|
||||||
#CONFIG_SCHED_THREAD_USAGE_ANALYSIS=y
|
|
||||||
#CONFIG_STATS=y
|
|
||||||
#CONFIG_STATS_SHELL=y
|
|
||||||
|
|
||||||
#
|
|
||||||
# Storage
|
|
||||||
#
|
|
||||||
#CONFIG_FLASH=y
|
|
||||||
#CONFIG_FLASH_MAP=y
|
|
||||||
#CONFIG_FLASH_PAGE_LAYOUT=y
|
|
||||||
# native_posix uses a simulated flash
|
|
||||||
#CONFIG_FLASH_SIMULATOR=y
|
|
||||||
#CONFIG_DISK_ACCESS=y.
|
|
||||||
#CONFIG_FILE_SYSTEM=y
|
|
||||||
#CONFIG_FILE_SYSTEM_LITTLEFS=y
|
|
||||||
#CONFIG_FILE_SYSTEM_SHELL=y
|
|
||||||
#CONFIG_NVS=y
|
|
||||||
#CONFIG_SETTINGS=y
|
|
||||||
#CONFIG_SETTINGS_NVS=y
|
|
||||||
#CONFIG_SETTINGS_RUNTIME=y
|
|
||||||
#CONFIG_SETTINGS_FILE=y
|
|
||||||
#CONFIG_SETTINGS_SHELL=y
|
|
||||||
|
|
||||||
CONFIG_TEST_RANDOM_GENERATOR=y
|
|
||||||
CONFIG_TIMER_RANDOM_GENERATOR=y
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
sample:
|
|
||||||
name: BACnet Profile B-SS Sample
|
|
||||||
|
|
||||||
tests:
|
|
||||||
bacnet-stack.sample.profile.b-ss:
|
|
||||||
tags: bacnet
|
|
||||||
platform_allow: qemu_x86 native_posix native_posix_64 native_sim
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2020 Legrand North America, Inc.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <zephyr/kernel.h>
|
|
||||||
#include <zephyr/random/random.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
/* BACnet Stack defines - first */
|
|
||||||
#include "bacnet/bacdef.h"
|
|
||||||
/* BACnet Stack core API */
|
|
||||||
#include "bacnet/version.h"
|
|
||||||
#include "bacnet/basic/sys/mstimer.h"
|
|
||||||
/* BACnet Stack basic device API - see bacnet_basic/device.c for details */
|
|
||||||
#include "bacnet/basic/object/device.h"
|
|
||||||
/* BACnet Stack basic objects - also enable in prj.conf */
|
|
||||||
#include "bacnet/basic/object/ai.h"
|
|
||||||
#if (BACNET_PROTOCOL_REVISION >= 17)
|
|
||||||
#include "bacnet/basic/object/netport.h"
|
|
||||||
#endif
|
|
||||||
#include "bacnet_basic/bacnet_basic.h"
|
|
||||||
|
|
||||||
/* Logging module registration is already done in ports/zephyr/main.c */
|
|
||||||
#include <zephyr/logging/log.h>
|
|
||||||
LOG_MODULE_DECLARE(bacnet, CONFIG_BACNETSTACK_LOG_LEVEL);
|
|
||||||
|
|
||||||
static const uint32_t Device_Instance = 260123;
|
|
||||||
static const uint32_t Sensor_Instance = 1;
|
|
||||||
/* timer for Sensor Update Interval */
|
|
||||||
static struct mstimer Sensor_Update_Timer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief BACnet Project Initialization Handler
|
|
||||||
* @param context [in] The context to pass to the callback function
|
|
||||||
* @note This is called from the BACnet task
|
|
||||||
*/
|
|
||||||
static void BACnet_Smart_Sensor_Init_Handler(void *context)
|
|
||||||
{
|
|
||||||
(void)context;
|
|
||||||
LOG_INF("BACnet Stack Initialized");
|
|
||||||
/* initialize objects for this basic sample */
|
|
||||||
Device_Init(NULL);
|
|
||||||
Device_Set_Object_Instance_Number(Device_Instance);
|
|
||||||
Analog_Input_Create(Sensor_Instance);
|
|
||||||
Analog_Input_Name_Set(Sensor_Instance, "Sensor");
|
|
||||||
Analog_Input_Present_Value_Set(Sensor_Instance, 25.0f);
|
|
||||||
LOG_INF("BACnet Device ID: %u", Device_Object_Instance_Number());
|
|
||||||
/* start the seconds cyclic timer */
|
|
||||||
mstimer_set(&Sensor_Update_Timer, 1000);
|
|
||||||
srand(sys_rand32_get());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief BACnet Project Task Handler
|
|
||||||
* @param context [in] The context to pass to the callback function
|
|
||||||
* @note This is called from the BACnet task
|
|
||||||
*/
|
|
||||||
static void BACnet_Smart_Sensor_Task_Handler(void *context)
|
|
||||||
{
|
|
||||||
float temperature = 0.0f, change = 0.0f;
|
|
||||||
|
|
||||||
(void)context;
|
|
||||||
if (mstimer_expired(&Sensor_Update_Timer)) {
|
|
||||||
mstimer_reset(&Sensor_Update_Timer);
|
|
||||||
/* simulate a sensor reading, and update the BACnet object values */
|
|
||||||
if (Analog_Input_Out_Of_Service(Sensor_Instance)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
temperature = Analog_Input_Present_Value(Sensor_Instance);
|
|
||||||
change = -1.0f+2.0f*((float)rand())/RAND_MAX;
|
|
||||||
temperature += change;
|
|
||||||
Analog_Input_Present_Value_Set(Sensor_Instance, temperature);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
LOG_INF("\n*** BACnet Profile B-SS Sample ***\n");
|
|
||||||
LOG_INF("BACnet Stack Version " BACNET_VERSION_TEXT);
|
|
||||||
LOG_INF("BACnet Stack Max APDU: %d", MAX_APDU);
|
|
||||||
bacnet_basic_init_callback_set(BACnet_Smart_Sensor_Init_Handler, NULL);
|
|
||||||
bacnet_basic_task_callback_set(BACnet_Smart_Sensor_Task_Handler, NULL);
|
|
||||||
/* work happens in server module */
|
|
||||||
for (;;) {
|
|
||||||
k_sleep(K_MSEC(1000));
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
# Copyright (c) 2020 Legrand North America, LLC.
|
|
||||||
# SPDX-License-Identifier: MIT
|
|
||||||
zephyr_sources(bacnet_shell.c)
|
|
||||||
|
|
||||||
add_subdirectory_ifdef(CONFIG_BACNETSTACK_BACNET_SETTINGS bacnet_settings)
|
|
||||||
add_subdirectory_ifdef(CONFIG_BACNETSTACK_BACNET_BASIC bacnet_basic)
|
|
||||||
add_subdirectory_ifdef(CONFIG_BACNETSTACK_BACNET_SERVER server)
|
|
||||||
add_subdirectory_ifdef(CONFIG_BACNETSTACK_BACNET_OBJECT object)
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
# Copyright (c) 2020 Legrand North America, LLC.
|
|
||||||
# SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
# Kconfig - Subsystem configuration options
|
|
||||||
|
|
||||||
comment "BACnet Subsystems"
|
|
||||||
|
|
||||||
rsource "bacnet_settings/Kconfig"
|
|
||||||
rsource "bacnet_basic/Kconfig"
|
|
||||||
rsource "object/Kconfig"
|
|
||||||
rsource "server/Kconfig"
|
|
||||||
|
|
||||||
config BACNET_SHELL
|
|
||||||
bool "BACnet Shell"
|
|
||||||
default n
|
|
||||||
select SHELL
|
|
||||||
select CONSOLE
|
|
||||||
select KERNEL_SHELL
|
|
||||||
select THREAD_MONITOR
|
|
||||||
select THREAD_NAME
|
|
||||||
select DEVICE_SHELL
|
|
||||||
select LOG
|
|
||||||
help
|
|
||||||
Enable BACnet Shell support
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
# CMake for BACnet settings library
|
|
||||||
#
|
|
||||||
# @author Steve Karg <skarg@users.sourceforge.net>
|
|
||||||
# @date May 2024
|
|
||||||
# @copyright SPDX-License-Identifier: MIT
|
|
||||||
zephyr_library(bacnet_basic)
|
|
||||||
|
|
||||||
zephyr_library_include_directories(include)
|
|
||||||
|
|
||||||
zephyr_library_sources(
|
|
||||||
bacnet_port.c
|
|
||||||
bacnet_port_ipv4.c
|
|
||||||
bacnet_port_ipv6.c
|
|
||||||
bacnet_basic.c
|
|
||||||
device.c
|
|
||||||
server.c
|
|
||||||
)
|
|
||||||
|
|
||||||
zephyr_library_sources_ifdef(CONFIG_BACNET_BASIC_DEVICE_SHELL
|
|
||||||
bacnet_shell_objects.c
|
|
||||||
bacnet_shell_packets.c
|
|
||||||
bacnet_shell_uptime.c
|
|
||||||
)
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
# Kconfig - Subsystem configuration options
|
|
||||||
#
|
|
||||||
# @author Steve Karg <skarg@users.sourceforge.net>
|
|
||||||
# @date May 2024
|
|
||||||
# @copyright SPDX-License-Identifier: MIT
|
|
||||||
menuconfig BACNETSTACK_BACNET_BASIC
|
|
||||||
bool "BACNETSTACK_BACNET_BASIC"
|
|
||||||
default n
|
|
||||||
help
|
|
||||||
This option enables a basic BACnet Device object and tasking
|
|
||||||
|
|
||||||
if BACNETSTACK_BACNET_BASIC
|
|
||||||
|
|
||||||
module = BACNETSTACK_BACNET_BASIC
|
|
||||||
module-str = bacnet_basic
|
|
||||||
|
|
||||||
config BACNET_BASIC_DEVICE_OBJECT_NAME
|
|
||||||
string "BACnet device object default name"
|
|
||||||
default "Basic Server"
|
|
||||||
help
|
|
||||||
BACnet device object default name
|
|
||||||
|
|
||||||
config BACNET_BASIC_DEVICE_OBJECT_VERSION
|
|
||||||
string "BACnet device object default application version string"
|
|
||||||
default "1.0.0"
|
|
||||||
help
|
|
||||||
BACnet device object default application version string
|
|
||||||
|
|
||||||
config BACNET_BASIC_DEVICE_DESCRIPTION
|
|
||||||
string "BACnet device object default description string"
|
|
||||||
default "BACnet Basic Server"
|
|
||||||
help
|
|
||||||
BACnet device object default description string
|
|
||||||
|
|
||||||
config BACNET_BASIC_DEVICE_MODEL_NAME
|
|
||||||
string "BACnet device object default model name string"
|
|
||||||
default "Basic Server"
|
|
||||||
help
|
|
||||||
BACnet device object default model name string
|
|
||||||
|
|
||||||
config BACNET_BASIC_DEVICE_SHELL
|
|
||||||
bool "BACnet Basic Device subsystem shell"
|
|
||||||
depends on BACNETSTACK
|
|
||||||
default y if SHELL
|
|
||||||
|
|
||||||
endif # BACNETSTACK_BACNET_SETTINGS
|
|
||||||
@@ -1,195 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
* @brief BACnet Stack initialization and task handler
|
|
||||||
* @author Steve Karg <skarg@users.sourceforge.net>
|
|
||||||
* @date March 2024
|
|
||||||
* @copyright SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
/* BACnet Stack defines - first */
|
|
||||||
#include "bacnet/bacdef.h"
|
|
||||||
/* BACnet Stack core API */
|
|
||||||
#include "bacnet/npdu.h"
|
|
||||||
#include "bacnet/dcc.h"
|
|
||||||
#include "bacnet/iam.h"
|
|
||||||
/* BACnet Stack basic services */
|
|
||||||
#include "bacnet/basic/sys/mstimer.h"
|
|
||||||
#include "bacnet/basic/services.h"
|
|
||||||
#include "bacnet/basic/tsm/tsm.h"
|
|
||||||
#include "bacnet/datalink/datalink.h"
|
|
||||||
/* BACnet Stack basic objects */
|
|
||||||
#include "bacnet/basic/object/device.h"
|
|
||||||
/* objects */
|
|
||||||
#if (BACNET_PROTOCOL_REVISION >= 17)
|
|
||||||
#include "bacnet/basic/object/netport.h"
|
|
||||||
#endif
|
|
||||||
#include "bacnet/basic/object/device.h"
|
|
||||||
/* me */
|
|
||||||
#include "bacnet_basic/bacnet_basic.h"
|
|
||||||
|
|
||||||
/* 1s timer for basic non-critical timed tasks */
|
|
||||||
static struct mstimer BACnet_Task_Timer;
|
|
||||||
/* task timer for object functionality */
|
|
||||||
static struct mstimer BACnet_Object_Timer;
|
|
||||||
/* uptimer for BACnet task */
|
|
||||||
static unsigned long BACnet_Uptime_Seconds;
|
|
||||||
/* packet counter for BACnet task */
|
|
||||||
static unsigned long BACnet_Packet_Count;
|
|
||||||
/* local Device ID to track changes */
|
|
||||||
static uint32_t Device_ID = 0xFFFFFFFF;
|
|
||||||
/* callbacks for custom features in BACnet thread */
|
|
||||||
static bacnet_basic_callback BACnet_Init_Callback;
|
|
||||||
static void *BACnet_Init_Context;
|
|
||||||
static bacnet_basic_callback BACnet_Task_Callback;
|
|
||||||
static void *BACnet_Task_Context;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Set the callback for the BACnet initialization
|
|
||||||
* @param callback [in] The callback function called after initialization
|
|
||||||
* @param context [in] The context to pass to the callback function
|
|
||||||
*/
|
|
||||||
void bacnet_basic_init_callback_set(bacnet_basic_callback callback,
|
|
||||||
void *context)
|
|
||||||
{
|
|
||||||
BACnet_Init_Callback = callback;
|
|
||||||
BACnet_Init_Context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief BACnet Task Callback Handler
|
|
||||||
*/
|
|
||||||
static void bacnet_init_callback_handler(void)
|
|
||||||
{
|
|
||||||
if (BACnet_Init_Callback) {
|
|
||||||
BACnet_Init_Callback(BACnet_Init_Context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Set the callback for the BACnet Task
|
|
||||||
* @param callback [in] The callback function to call during the task
|
|
||||||
* @param context [in] The context to pass to the callback function
|
|
||||||
*/
|
|
||||||
void bacnet_basic_task_callback_set(bacnet_basic_callback callback,
|
|
||||||
void *context)
|
|
||||||
{
|
|
||||||
BACnet_Task_Callback = callback;
|
|
||||||
BACnet_Task_Context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief BACnet Task Callback Handler
|
|
||||||
*/
|
|
||||||
static void bacnet_task_callback_handler(void)
|
|
||||||
{
|
|
||||||
if (BACnet_Task_Callback) {
|
|
||||||
BACnet_Task_Callback(BACnet_Task_Context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get the BACnet device uptime in seconds
|
|
||||||
* @return The number of seconds the BACnet device has been running
|
|
||||||
*/
|
|
||||||
unsigned long bacnet_basic_uptime_seconds(void)
|
|
||||||
{
|
|
||||||
return BACnet_Uptime_Seconds;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get the BACnet device uptime in seconds
|
|
||||||
* @return The number of seconds the BACnet device has been running
|
|
||||||
*/
|
|
||||||
unsigned long bacnet_basic_packet_count(void)
|
|
||||||
{
|
|
||||||
return BACnet_Packet_Count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initialize the BACnet device object, the service handlers, and timers
|
|
||||||
*/
|
|
||||||
void bacnet_basic_init(void)
|
|
||||||
{
|
|
||||||
/* set up our confirmed service unrecognized service handler - required! */
|
|
||||||
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
|
||||||
/* we need to handle who-is to support dynamic device binding */
|
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_HAS, handler_who_has);
|
|
||||||
/* Set the handlers for any confirmed services that we support. */
|
|
||||||
/* We must implement read property - it's required! */
|
|
||||||
apdu_set_confirmed_handler(
|
|
||||||
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
|
|
||||||
apdu_set_confirmed_handler(
|
|
||||||
SERVICE_CONFIRMED_READ_PROP_MULTIPLE, handler_read_property_multiple);
|
|
||||||
apdu_set_confirmed_handler(
|
|
||||||
SERVICE_CONFIRMED_WRITE_PROPERTY, handler_write_property);
|
|
||||||
apdu_set_confirmed_handler(
|
|
||||||
SERVICE_CONFIRMED_WRITE_PROP_MULTIPLE, handler_write_property_multiple);
|
|
||||||
apdu_set_confirmed_handler(
|
|
||||||
SERVICE_CONFIRMED_SUBSCRIBE_COV, handler_cov_subscribe);
|
|
||||||
/* handle communication so we can shutup when asked, or restart */
|
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
|
|
||||||
handler_device_communication_control);
|
|
||||||
apdu_set_confirmed_handler(
|
|
||||||
SERVICE_CONFIRMED_REINITIALIZE_DEVICE, handler_reinitialize_device);
|
|
||||||
/* start the 1 second timer for non-critical cyclic tasks */
|
|
||||||
mstimer_set(&BACnet_Task_Timer, 1000L);
|
|
||||||
/* start the timer for more time sensitive object specific cyclic tasks */
|
|
||||||
mstimer_set(&BACnet_Object_Timer, 100UL);
|
|
||||||
/* initialize user data in this thread */
|
|
||||||
bacnet_init_callback_handler();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* local buffer for incoming PDUs to process */
|
|
||||||
static uint8_t PDUBuffer[MAX_MPDU];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief non-blocking BACnet task
|
|
||||||
*/
|
|
||||||
void bacnet_basic_task(void)
|
|
||||||
{
|
|
||||||
bool hello_world = false;
|
|
||||||
uint16_t pdu_len = 0;
|
|
||||||
BACNET_ADDRESS src = { 0 };
|
|
||||||
uint32_t elapsed_milliseconds = 0;
|
|
||||||
uint32_t elapsed_seconds = 0;
|
|
||||||
|
|
||||||
/* hello, World! */
|
|
||||||
if (Device_ID != Device_Object_Instance_Number()) {
|
|
||||||
Device_ID = Device_Object_Instance_Number();
|
|
||||||
hello_world = true;
|
|
||||||
}
|
|
||||||
if (hello_world) {
|
|
||||||
Send_I_Am(&Handler_Transmit_Buffer[0]);
|
|
||||||
}
|
|
||||||
/* handle non-time-critical cyclic tasks */
|
|
||||||
if (mstimer_expired(&BACnet_Task_Timer)) {
|
|
||||||
/* 1 second tasks */
|
|
||||||
mstimer_reset(&BACnet_Task_Timer);
|
|
||||||
/* presume that the elapsed time is the interval time */
|
|
||||||
elapsed_milliseconds = mstimer_interval(&BACnet_Task_Timer);
|
|
||||||
elapsed_seconds = elapsed_milliseconds/1000;
|
|
||||||
BACnet_Uptime_Seconds += elapsed_seconds;
|
|
||||||
dcc_timer_seconds(elapsed_seconds);
|
|
||||||
datalink_maintenance_timer(elapsed_seconds);
|
|
||||||
handler_cov_timer_seconds(elapsed_seconds);
|
|
||||||
}
|
|
||||||
while (!handler_cov_fsm()) {
|
|
||||||
/* waiting for COV processing to be IDLE */
|
|
||||||
}
|
|
||||||
/* object specific cyclic tasks */
|
|
||||||
if (mstimer_expired(&BACnet_Object_Timer)) {
|
|
||||||
mstimer_reset(&BACnet_Object_Timer);
|
|
||||||
elapsed_milliseconds = mstimer_interval(&BACnet_Object_Timer);
|
|
||||||
Device_Timer(elapsed_milliseconds);
|
|
||||||
}
|
|
||||||
/* handle the messaging */
|
|
||||||
pdu_len = datalink_receive(&src, &PDUBuffer[0], sizeof(PDUBuffer), 0);
|
|
||||||
if (pdu_len) {
|
|
||||||
npdu_handler(&src, &PDUBuffer[0], pdu_len);
|
|
||||||
BACnet_Packet_Count++;
|
|
||||||
}
|
|
||||||
/* call user task in this thread */
|
|
||||||
bacnet_task_callback_handler();
|
|
||||||
}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
* @brief The BACnet/IPv4 datalink tasks for handling the device specific
|
|
||||||
* data link layer
|
|
||||||
* @author Steve Karg <skarg@users.sourceforge.net>
|
|
||||||
* @date April 2024
|
|
||||||
* @copyright SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
/* BACnet definitions */
|
|
||||||
#include "bacnet/bacdef.h"
|
|
||||||
/* BACnet library API */
|
|
||||||
#include "bacnet/basic/sys/mstimer.h"
|
|
||||||
#include "bacnet/datalink/datalink.h"
|
|
||||||
#include "bacnet/basic/object/netport.h"
|
|
||||||
#if defined(BACDL_BIP)
|
|
||||||
#include "bacnet_basic/bacnet_port_ipv4.h"
|
|
||||||
#elif defined(BACDL_BIP6)
|
|
||||||
#include "bacnet_basic/bacnet_port_ipv6.h"
|
|
||||||
#endif
|
|
||||||
/* me! */
|
|
||||||
#include "bacnet_basic/bacnet_port.h"
|
|
||||||
|
|
||||||
/* timer used to renew Foreign Device Registration */
|
|
||||||
static struct mstimer BACnet_Task_Timer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Periodic tasks for the BACnet datalink layer
|
|
||||||
*/
|
|
||||||
void bacnet_port_task(void)
|
|
||||||
{
|
|
||||||
uint32_t elapsed_milliseconds = 0;
|
|
||||||
uint32_t elapsed_seconds = 0;
|
|
||||||
|
|
||||||
if (mstimer_expired(&BACnet_Task_Timer)) {
|
|
||||||
/* 1 second tasks */
|
|
||||||
mstimer_reset(&BACnet_Task_Timer);
|
|
||||||
/* presume that the elapsed time is the interval time */
|
|
||||||
elapsed_milliseconds = mstimer_interval(&BACnet_Task_Timer);
|
|
||||||
elapsed_seconds = elapsed_milliseconds / 1000;
|
|
||||||
#if defined(BACDL_BIP)
|
|
||||||
bacnet_port_ipv4_task(elapsed_seconds);
|
|
||||||
#elif defined(BACDL_BIP6)
|
|
||||||
bacnet_port_ipv6_task(elapsed_seconds);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initialize the datalink network port
|
|
||||||
*/
|
|
||||||
bool bacnet_port_init(void)
|
|
||||||
{
|
|
||||||
bool status = false;
|
|
||||||
/* start the 1 second timer for non-critical cyclic tasks */
|
|
||||||
mstimer_set(&BACnet_Task_Timer, 1000L);
|
|
||||||
#if defined(BACDL_BIP)
|
|
||||||
status = bacnet_port_ipv4_init();
|
|
||||||
#elif defined(BACDL_BIP6)
|
|
||||||
status = bacnet_port_ipv6_init();
|
|
||||||
#endif
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
* @brief The BACnet/IPv4 datalink tasks for handling the device specific
|
|
||||||
* data link layer
|
|
||||||
* @author Steve Karg <skarg@users.sourceforge.net>
|
|
||||||
* @date April 2024
|
|
||||||
* @copyright SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
#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/basic/bbmd/h_bbmd.h"
|
|
||||||
#include "bacnet/datalink/bip.h"
|
|
||||||
#include "bacnet/datalink/bvlc.h"
|
|
||||||
#include "bacnet/datalink/datalink.h"
|
|
||||||
/* me! */
|
|
||||||
#include "bacnet_basic/bacnet_port_ipv4.h"
|
|
||||||
|
|
||||||
#if defined(BACDL_BIP)
|
|
||||||
|
|
||||||
/* timer used to renew Foreign Device Registration */
|
|
||||||
static uint16_t BBMD_Timer_Seconds;
|
|
||||||
static uint16_t BBMD_TTL_Seconds = 60000;
|
|
||||||
static BACNET_IP_ADDRESS BBMD_Address;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initialize the datalink network port
|
|
||||||
* @param ttl_seconds [in] The time-to-live in seconds for the Foreign Device Registration
|
|
||||||
* @param bbmd_address [in] The address of the BBMD
|
|
||||||
*/
|
|
||||||
void bacnet_port_ipv4_foreign_device_init(
|
|
||||||
const uint16_t ttl_seconds,
|
|
||||||
const BACNET_IP_ADDRESS *bbmd_address)
|
|
||||||
{
|
|
||||||
BBMD_TTL_Seconds = ttl_seconds;
|
|
||||||
if (bbmd_address) {
|
|
||||||
memcpy(&BBMD_Address, bbmd_address, sizeof(BACNET_IP_ADDRESS));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Renew the Foreign Device Registration
|
|
||||||
*/
|
|
||||||
void bacnet_port_ipv4_task(uint16_t elapsed_seconds)
|
|
||||||
{
|
|
||||||
if (BBMD_Timer_Seconds) {
|
|
||||||
if (BBMD_Timer_Seconds <= elapsed_seconds) {
|
|
||||||
BBMD_Timer_Seconds = 0;
|
|
||||||
} else {
|
|
||||||
BBMD_Timer_Seconds -= elapsed_seconds;
|
|
||||||
}
|
|
||||||
if (BBMD_Timer_Seconds == 0) {
|
|
||||||
if (BBMD_Address.port > 0) {
|
|
||||||
(void)bvlc_register_with_bbmd(&BBMD_Address,
|
|
||||||
BBMD_TTL_Seconds);
|
|
||||||
}
|
|
||||||
BBMD_Timer_Seconds = (uint16_t)BBMD_TTL_Seconds;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize the network port object.
|
|
||||||
*/
|
|
||||||
bool bacnet_port_ipv4_init(void)
|
|
||||||
{
|
|
||||||
const uint32_t instance = 1;
|
|
||||||
BACNET_IP_ADDRESS addr = { 0 };
|
|
||||||
uint8_t prefix = 0;
|
|
||||||
|
|
||||||
if (!bip_init(NULL)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Network_Port_Object_Instance_Number_Set(0, instance);
|
|
||||||
Network_Port_Name_Set(instance, "BACnet/IP Port");
|
|
||||||
Network_Port_Type_Set(instance, PORT_TYPE_BIP);
|
|
||||||
bip_get_addr(&addr);
|
|
||||||
prefix = bip_get_subnet_prefix();
|
|
||||||
Network_Port_BIP_Port_Set(instance, addr.port);
|
|
||||||
Network_Port_IP_Address_Set(instance, addr.address[0], addr.address[1],
|
|
||||||
addr.address[2], addr.address[3]);
|
|
||||||
Network_Port_IP_Subnet_Prefix_Set(instance, prefix);
|
|
||||||
Network_Port_Link_Speed_Set(instance, 0.0);
|
|
||||||
/* common NP data */
|
|
||||||
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);
|
|
||||||
/* 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
|
|
||||||
@@ -1,104 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
* @brief The BACnet datalink tasks for handling the device specific
|
|
||||||
* data link layer
|
|
||||||
* @author Steve Karg <skarg@users.sourceforge.net>
|
|
||||||
* @date April 2024
|
|
||||||
* @copyright SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
#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/basic/bbmd6/h_bbmd6.h"
|
|
||||||
#include "bacnet/datalink/bip6.h"
|
|
||||||
#include "bacnet/datalink/bvlc6.h"
|
|
||||||
#include "bacnet/datalink/datalink.h"
|
|
||||||
/* me! */
|
|
||||||
#include "bacnet_basic/bacnet_port_ipv6.h"
|
|
||||||
|
|
||||||
#if defined(BACDL_BIP6)
|
|
||||||
|
|
||||||
/* timer used to renew Foreign Device Registration */
|
|
||||||
static uint16_t BBMD_Timer_Seconds;
|
|
||||||
static uint16_t BBMD_TTL_Seconds = 60000;
|
|
||||||
static BACNET_IP6_ADDRESS BBMD_Address;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initialize the datalink network port
|
|
||||||
* @param ttl_seconds [in] The time-to-live in seconds for the Foreign Device Registration
|
|
||||||
* @param bbmd_address [in] The address of the BBMD
|
|
||||||
*/
|
|
||||||
void bacnet_port_ipv6_foreign_device_init(
|
|
||||||
const uint16_t ttl_seconds, const BACNET_IP6_ADDRESS *bbmd_address)
|
|
||||||
{
|
|
||||||
BBMD_TTL_Seconds = ttl_seconds;
|
|
||||||
if (bbmd_address) {
|
|
||||||
memcpy(&BBMD_Address, bbmd_address, sizeof(BACNET_IP6_ADDRESS));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Renew the Foreign Device Registration
|
|
||||||
*/
|
|
||||||
void bacnet_port_ipv6_task(uint16_t elapsed_seconds)
|
|
||||||
{
|
|
||||||
if (BBMD_Timer_Seconds) {
|
|
||||||
if (BBMD_Timer_Seconds <= elapsed_seconds) {
|
|
||||||
BBMD_Timer_Seconds = 0;
|
|
||||||
} else {
|
|
||||||
BBMD_Timer_Seconds -= elapsed_seconds;
|
|
||||||
}
|
|
||||||
if (BBMD_Timer_Seconds == 0) {
|
|
||||||
if (BBMD_Address.port > 0) {
|
|
||||||
(void)bvlc6_register_with_bbmd(&BBMD_Address,
|
|
||||||
BBMD_TTL_Seconds);
|
|
||||||
}
|
|
||||||
BBMD_Timer_Seconds = BBMD_TTL_Seconds;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize the network port object.
|
|
||||||
* @return true if successful
|
|
||||||
*/
|
|
||||||
bool bacnet_port_ipv6_init(void)
|
|
||||||
{
|
|
||||||
uint32_t instance = 1;
|
|
||||||
uint8_t prefix = 0;
|
|
||||||
BACNET_ADDRESS addr = { 0 };
|
|
||||||
BACNET_IP6_ADDRESS addr6 = { 0 };
|
|
||||||
|
|
||||||
if (!bip6_init(NULL)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Network_Port_Object_Instance_Number_Set(0, instance);
|
|
||||||
Network_Port_Name_Set(instance, "BACnet/IPv6 Port");
|
|
||||||
Network_Port_Type_Set(instance, PORT_TYPE_BIP6);
|
|
||||||
Network_Port_BIP6_Port_Set(instance, bip6_get_port());
|
|
||||||
bip6_get_my_address(&addr);
|
|
||||||
Network_Port_MAC_Address_Set(instance, &addr.mac[0], addr.mac_len);
|
|
||||||
bip6_get_addr(&addr6);
|
|
||||||
Network_Port_IPv6_Address_Set(instance, &addr6.address[0]);
|
|
||||||
bip6_get_broadcast_addr(&addr6);
|
|
||||||
Network_Port_IPv6_Multicast_Address_Set(instance, &addr6.address[0]);
|
|
||||||
Network_Port_IPv6_Subnet_Prefix_Set(instance, prefix);
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
* @brief BACnet shell commands for debugging and testing
|
|
||||||
* @author Steve Karg <skarg@users.sourceforge.net>
|
|
||||||
* @date May 2024
|
|
||||||
* @copyright SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <zephyr/shell/shell.h>
|
|
||||||
/* BACnet definitions */
|
|
||||||
#include "bacnet/bacdef.h"
|
|
||||||
#include "bacnet/bacdcode.h"
|
|
||||||
#include "bacnet/bactext.h"
|
|
||||||
#include "bacnet/bacapp.h"
|
|
||||||
/* BACnet objects API */
|
|
||||||
#include "bacnet/basic/object/device.h"
|
|
||||||
/* Basic BACnet */
|
|
||||||
#include "bacnet_basic/bacnet_basic.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief List all BACnet objects in this device
|
|
||||||
* @param sh Shell
|
|
||||||
* @param argc Number of arguments
|
|
||||||
* @param argv Argument list
|
|
||||||
* @return 0 on success, negative on failure
|
|
||||||
*/
|
|
||||||
static int cmd_objects(const struct shell *sh, size_t argc, char **argv)
|
|
||||||
{
|
|
||||||
int count;
|
|
||||||
BACNET_OBJECT_TYPE object_type;
|
|
||||||
uint32_t instance;
|
|
||||||
uint32_t array_index;
|
|
||||||
bool found;
|
|
||||||
|
|
||||||
(void)argc;
|
|
||||||
(void)argv;
|
|
||||||
shell_print(sh, "List of BACnet Objects: [{");
|
|
||||||
count = Device_Object_List_Count();
|
|
||||||
for (array_index = 1; array_index <= count; array_index++) {
|
|
||||||
found = Device_Object_List_Identifier(array_index, &object_type,
|
|
||||||
&instance);
|
|
||||||
if (found) {
|
|
||||||
shell_print(sh, " \"%s-%u\"%c",
|
|
||||||
bactext_object_type_name(object_type),
|
|
||||||
instance,
|
|
||||||
(array_index == count) ? ' ' : ',');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
shell_print(sh, "}] -- %d objects found", count);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
SHELL_SUBCMD_ADD((bacnet), objects, NULL, "list of BACnet objects", cmd_objects,
|
|
||||||
1, 0);
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
* @brief The BACnet shell commands for debugging and testing
|
|
||||||
* @author Steve Karg <skarg@users.sourceforge.net>
|
|
||||||
* @date May 2024
|
|
||||||
* @copyright SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <zephyr/shell/shell.h>
|
|
||||||
/* BACnet definitions */
|
|
||||||
#include "bacnet/bacdef.h"
|
|
||||||
#include "bacnet/bacdcode.h"
|
|
||||||
#include "bacnet/bactext.h"
|
|
||||||
#include "bacnet/bacapp.h"
|
|
||||||
/* Basic BACnet */
|
|
||||||
#include "bacnet_basic/bacnet_basic.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Print BACnet packet statistics
|
|
||||||
* @param sh Shell
|
|
||||||
* @param argc Number of arguments
|
|
||||||
* @param argv Argument list
|
|
||||||
* @return 0 on success, negative on failure
|
|
||||||
*/
|
|
||||||
static int cmd_packets(const struct shell *sh, size_t argc, char **argv)
|
|
||||||
{
|
|
||||||
(void)argc;
|
|
||||||
(void)argv;
|
|
||||||
shell_print(sh, "BACnet thread packets received: %ld",
|
|
||||||
bacnet_basic_packet_count());
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
SHELL_SUBCMD_ADD((bacnet), packets, NULL, "BACnet task packet stats", cmd_packets,
|
|
||||||
1, 0);
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
* @brief The BACnet shell commands for debugging and testing
|
|
||||||
* @author Steve Karg <skarg@users.sourceforge.net>
|
|
||||||
* @date May 2024
|
|
||||||
* @copyright SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <zephyr/shell/shell.h>
|
|
||||||
/* BACnet definitions */
|
|
||||||
#include "bacnet/bacdef.h"
|
|
||||||
#include "bacnet/bacdcode.h"
|
|
||||||
#include "bacnet/bactext.h"
|
|
||||||
#include "bacnet/bacapp.h"
|
|
||||||
/* Basic BACnet */
|
|
||||||
#include "bacnet_basic/bacnet_basic.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Print BACnet uptime statistics
|
|
||||||
* @param sh Shell
|
|
||||||
* @param argc Number of arguments
|
|
||||||
* @param argv Argument list
|
|
||||||
* @return 0 on success, negative on failure
|
|
||||||
*/
|
|
||||||
static int cmd_uptime(const struct shell *sh, size_t argc, char **argv)
|
|
||||||
{
|
|
||||||
(void)argc;
|
|
||||||
(void)argv;
|
|
||||||
shell_print(sh, "BACnet thread uptime: %ld seconds",
|
|
||||||
bacnet_basic_uptime_seconds());
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
SHELL_SUBCMD_ADD((bacnet), uptime, NULL, "BACnet task uptime", cmd_uptime,
|
|
||||||
1, 0);
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,91 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
* @brief BACnet Stack server initialization and task handler
|
|
||||||
* @author Steve Karg <skarg@users.sourceforge.net>
|
|
||||||
* @date March 2024
|
|
||||||
* @copyright SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdalign.h> /*TODO: Not std until C11! */
|
|
||||||
#include <zephyr/device.h>
|
|
||||||
#include <zephyr/init.h>
|
|
||||||
#include <zephyr/kernel.h>
|
|
||||||
#include <zephyr/sys/printk.h>
|
|
||||||
#include <zephyr/random/random.h>
|
|
||||||
#include <bacnet_settings/bacnet_storage.h>
|
|
||||||
#include "bacnet/datalink/datalink.h"
|
|
||||||
#include "bacnet_basic/bacnet_basic.h"
|
|
||||||
#include "bacnet_basic/bacnet_port.h"
|
|
||||||
#if defined(CONFIG_BACNETSTACK_BACNET_SETTINGS)
|
|
||||||
#include "bacnet_settings/bacnet_storage.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* note: stack is minimally 2x to 3x of MAX_APDU */
|
|
||||||
#ifndef CONFIG_BACNETSTACK_BACNET_SERVER_STACK_SIZE
|
|
||||||
#define CONFIG_BACNETSTACK_BACNET_SERVER_STACK_SIZE 4096
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef CONFIG_BACNETSTACK_BACNET_SERVER_PRIO
|
|
||||||
#define CONFIG_BACNETSTACK_BACNET_SERVER_PRIO 10
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef CONFIG_BACNETSTACK_BACNET_SERVER_APP_PRIORITY
|
|
||||||
#define CONFIG_BACNETSTACK_BACNET_SERVER_APP_PRIORITY 90
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef CONFIG_BACNETSTACK_LOG_LEVEL
|
|
||||||
#define CONFIG_BACNETSTACK_LOG_LEVEL LOG_LEVEL_INF
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Logging module registration is already done in ports/zephyr/main.c */
|
|
||||||
#include <zephyr/logging/log.h>
|
|
||||||
LOG_MODULE_DECLARE(bacnet, CONFIG_BACNETSTACK_LOG_LEVEL);
|
|
||||||
|
|
||||||
static struct k_thread server_thread_data;
|
|
||||||
static K_THREAD_STACK_DEFINE(server_thread_stack,
|
|
||||||
CONFIG_BACNETSTACK_BACNET_SERVER_STACK_SIZE);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief BACnet Server Thread
|
|
||||||
*/
|
|
||||||
static void server_thread(void)
|
|
||||||
{
|
|
||||||
LOG_INF("BACnet Server: started");
|
|
||||||
|
|
||||||
#if defined(CONFIG_BACNETSTACK_BACNET_SETTINGS)
|
|
||||||
bacnet_storage_init();
|
|
||||||
#endif
|
|
||||||
bacnet_basic_init();
|
|
||||||
for (;;) {
|
|
||||||
if (bacnet_port_init()) {
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
LOG_ERR("BACnet Server: port initialization failed");
|
|
||||||
k_sleep(K_MSEC(1000));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LOG_INF("BACnet Server: initialized");
|
|
||||||
for (;;) {
|
|
||||||
k_sleep(K_MSEC(10));
|
|
||||||
bacnet_basic_task();
|
|
||||||
bacnet_port_task();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief BACnet Server Thread initialization
|
|
||||||
*/
|
|
||||||
static int server_init(void)
|
|
||||||
{
|
|
||||||
k_thread_create(&server_thread_data, server_thread_stack,
|
|
||||||
K_THREAD_STACK_SIZEOF(server_thread_stack),
|
|
||||||
(k_thread_entry_t)server_thread, NULL, NULL, NULL,
|
|
||||||
K_PRIO_PREEMPT(CONFIG_BACNETSTACK_BACNET_SERVER_PRIO), 0,
|
|
||||||
K_NO_WAIT);
|
|
||||||
k_thread_name_set(&server_thread_data, "bacnet_server");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
SYS_INIT(server_init, APPLICATION,
|
|
||||||
CONFIG_BACNETSTACK_BACNET_SERVER_APP_PRIORITY);
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
# CMake for BACnet settings library
|
|
||||||
#
|
|
||||||
# @author Steve Karg <skarg@users.sourceforge.net>
|
|
||||||
# @date May 2024
|
|
||||||
# @copyright SPDX-License-Identifier: MIT
|
|
||||||
zephyr_library(bacnet_settings)
|
|
||||||
|
|
||||||
zephyr_library_include_directories(include)
|
|
||||||
|
|
||||||
zephyr_library_sources(
|
|
||||||
bacnet_storage.c
|
|
||||||
bacnet_settings.c
|
|
||||||
)
|
|
||||||
|
|
||||||
zephyr_library_sources_ifdef(CONFIG_BACNET_SETTINGS_SHELL
|
|
||||||
bacnet_shell.c
|
|
||||||
)
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
# Kconfig - Subsystem configuration options
|
|
||||||
#
|
|
||||||
# @author Steve Karg <skarg@users.sourceforge.net>
|
|
||||||
# @date May 2024
|
|
||||||
# @copyright SPDX-License-Identifier: MIT
|
|
||||||
menuconfig BACNETSTACK_BACNET_SETTINGS
|
|
||||||
bool "BACNETSTACK_BACNET_SETTINGS"
|
|
||||||
default y if BACNETSTACK && SETTINGS
|
|
||||||
help
|
|
||||||
This option enables BACnet Settings services
|
|
||||||
|
|
||||||
if BACNETSTACK_BACNET_SETTINGS
|
|
||||||
|
|
||||||
module = BACNETSTACK_BACNET_SETTINGS
|
|
||||||
module-str = bac_settings
|
|
||||||
|
|
||||||
config BACNET_SETTINGS_BASE_NAME
|
|
||||||
string "BACnet object path base name for every setting"
|
|
||||||
default ".bacnet"
|
|
||||||
help
|
|
||||||
BACnet object path base name for every setting"
|
|
||||||
|
|
||||||
config BACNET_SETTINGS_SHELL
|
|
||||||
bool "BACnet settings subsystem shell"
|
|
||||||
depends on BACNETSTACK
|
|
||||||
default y if SHELL && SETTINGS
|
|
||||||
|
|
||||||
endif # BACNETSTACK_BACNET_SETTINGS
|
|
||||||
@@ -1,379 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
* @brief Handle Get/Set of BACnet application encoded settings
|
|
||||||
* @date May 2024
|
|
||||||
* @author Steve Karg <skarg@users.sourceforge.net>
|
|
||||||
* @copyright SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <zephyr/sys/byteorder.h>
|
|
||||||
#include <bacnet_settings/bacnet_storage.h>
|
|
||||||
#include <bacnet_settings/bacnet_settings.h>
|
|
||||||
#include "bacnet/bacdef.h"
|
|
||||||
#include "bacnet/bacapp.h"
|
|
||||||
#include "bacnet/bacdcode.h"
|
|
||||||
#include "bacnet/bacstr.h"
|
|
||||||
#include "bacnet/bacint.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get a BACnet SIGNED INTEGER value from non-volatile storage
|
|
||||||
* @param object_type [in] The BACnet object type
|
|
||||||
* @param object_instance [in] The BACnet object instance
|
|
||||||
* @param property_id [in] The BACnet property id
|
|
||||||
* @param array_index [in] The BACnet array index
|
|
||||||
* @param default_value [in] The default value if not found
|
|
||||||
* @return stored data length on success 0..N, negative on failure.
|
|
||||||
*/
|
|
||||||
int bacnet_settings_value_get(uint16_t object_type, uint32_t object_instance,
|
|
||||||
uint32_t property_id, uint32_t array_index,
|
|
||||||
BACNET_APPLICATION_DATA_VALUE *value)
|
|
||||||
{
|
|
||||||
uint8_t name[BACNET_STORAGE_VALUE_SIZE_MAX + 1] = { 0 };
|
|
||||||
BACNET_STORAGE_KEY key = { 0 };
|
|
||||||
int stored_len, len;
|
|
||||||
|
|
||||||
bacnet_storage_key_init(&key, object_type, object_instance, property_id,
|
|
||||||
array_index);
|
|
||||||
stored_len = bacnet_storage_get(&key, name, sizeof(name));
|
|
||||||
if (stored_len > 0) {
|
|
||||||
len = bacapp_decode_application_data(name, stored_len, value);
|
|
||||||
if (len <= 0) {
|
|
||||||
if (value) {
|
|
||||||
value->tag = MAX_BACNET_APPLICATION_TAG;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return stored_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Store a BACnet SIGNED INTEGER value in non-volatile storage
|
|
||||||
* @param object_type [in] The BACnet object type
|
|
||||||
* @param object_instance [in] The BACnet object instance
|
|
||||||
* @param property_id [in] The BACnet property id
|
|
||||||
* @param array_index [in] The BACnet array index
|
|
||||||
* @param value [in] The value to store
|
|
||||||
* @return true on success, false on failure.
|
|
||||||
*/
|
|
||||||
bool bacnet_settings_value_set(uint16_t object_type, uint32_t object_instance,
|
|
||||||
uint32_t property_id, uint32_t array_index,
|
|
||||||
BACNET_APPLICATION_DATA_VALUE *value)
|
|
||||||
{
|
|
||||||
uint8_t name[BACNET_STORAGE_VALUE_SIZE_MAX] = { 0 };
|
|
||||||
BACNET_STORAGE_KEY key = { 0 };
|
|
||||||
int rc, len;
|
|
||||||
|
|
||||||
bacnet_storage_key_init(&key, object_type, object_instance, property_id,
|
|
||||||
array_index);
|
|
||||||
len = bacapp_encode_application_data(NULL, value);
|
|
||||||
if (len <= 0) {
|
|
||||||
return false;
|
|
||||||
} else if (len > sizeof(name)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
len = bacapp_encode_application_data(name, value);
|
|
||||||
rc = bacnet_storage_set(&key, name, len);
|
|
||||||
|
|
||||||
return rc == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get a BACnet REAL value from non-volatile storage
|
|
||||||
* @param object_type [in] The BACnet object type
|
|
||||||
* @param object_instance [in] The BACnet object instance
|
|
||||||
* @param property_id [in] The BACnet property id
|
|
||||||
* @param array_index [in] The BACnet array index
|
|
||||||
* @param default_value [in] The default value if not found
|
|
||||||
* @return stored data length on success 0..N, negative on failure.
|
|
||||||
*/
|
|
||||||
int bacnet_settings_real_get(uint16_t object_type, uint32_t object_instance,
|
|
||||||
uint32_t property_id, uint32_t array_index,
|
|
||||||
float default_value, float *value)
|
|
||||||
{
|
|
||||||
int stored_len;
|
|
||||||
BACNET_APPLICATION_DATA_VALUE bvalue = { 0 };
|
|
||||||
|
|
||||||
stored_len =
|
|
||||||
bacnet_settings_value_get(object_type, object_instance,
|
|
||||||
property_id, array_index, &bvalue);
|
|
||||||
if ((stored_len >= 0) && (bvalue.tag == BACNET_APPLICATION_TAG_REAL)) {
|
|
||||||
if (value) {
|
|
||||||
*value = bvalue.type.Real;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (value) {
|
|
||||||
*value = default_value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return stored_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Store a BACnet REAL value in non-volatile storage
|
|
||||||
* @param object_type [in] The BACnet object type
|
|
||||||
* @param object_instance [in] The BACnet object instance
|
|
||||||
* @param property_id [in] The BACnet property id
|
|
||||||
* @param array_index [in] The BACnet array index
|
|
||||||
* @param value [in] The value to store
|
|
||||||
* @return true on success, false on failure.
|
|
||||||
*/
|
|
||||||
bool bacnet_settings_real_set(uint16_t object_type, uint32_t object_instance,
|
|
||||||
uint32_t property_id, uint32_t array_index,
|
|
||||||
float value)
|
|
||||||
{
|
|
||||||
BACNET_APPLICATION_DATA_VALUE bvalue = { 0 };
|
|
||||||
|
|
||||||
bvalue.context_specific = false;
|
|
||||||
bvalue.tag = BACNET_APPLICATION_TAG_REAL;
|
|
||||||
bvalue.type.Real = value;
|
|
||||||
|
|
||||||
return bacnet_settings_value_set(object_type, object_instance,
|
|
||||||
property_id, array_index, &bvalue);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get a BACnet UNSIGNED value from non-volatile storage
|
|
||||||
* @param object_type [in] The BACnet object type
|
|
||||||
* @param object_instance [in] The BACnet object instance
|
|
||||||
* @param property_id [in] The BACnet property id
|
|
||||||
* @param default_value [in] The default value if not found
|
|
||||||
* @return stored data length on success 0..N, negative on failure.
|
|
||||||
*/
|
|
||||||
int bacnet_settings_unsigned_get(uint16_t object_type, uint32_t object_instance,
|
|
||||||
uint32_t property_id, uint32_t array_index,
|
|
||||||
BACNET_UNSIGNED_INTEGER default_value,
|
|
||||||
BACNET_UNSIGNED_INTEGER *value)
|
|
||||||
{
|
|
||||||
uint8_t name[BACNET_STORAGE_VALUE_SIZE_MAX + 1] = { 0 };
|
|
||||||
BACNET_STORAGE_KEY key = { 0 };
|
|
||||||
int stored_len, len;
|
|
||||||
|
|
||||||
bacnet_storage_key_init(&key, object_type, object_instance, property_id,
|
|
||||||
array_index);
|
|
||||||
stored_len = bacnet_storage_get(&key, name, sizeof(name));
|
|
||||||
if (stored_len > 0) {
|
|
||||||
len = bacnet_unsigned_application_decode(name, stored_len,
|
|
||||||
value);
|
|
||||||
if (len <= 0) {
|
|
||||||
if (value) {
|
|
||||||
*value = default_value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (value) {
|
|
||||||
*value = default_value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return stored_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Store a BACnet UNSIGNED value in non-volatile storage
|
|
||||||
* @param object_type [in] The BACnet object type
|
|
||||||
* @param object_instance [in] The BACnet object instance
|
|
||||||
* @param property_id [in] The BACnet property id
|
|
||||||
* @param value [int] The value to store
|
|
||||||
* @return true on success, false on failure.
|
|
||||||
*/
|
|
||||||
bool bacnet_settings_unsigned_set(uint16_t object_type,
|
|
||||||
uint32_t object_instance,
|
|
||||||
uint32_t property_id, uint32_t array_index,
|
|
||||||
BACNET_UNSIGNED_INTEGER value)
|
|
||||||
{
|
|
||||||
BACNET_APPLICATION_DATA_VALUE bvalue = { 0 };
|
|
||||||
|
|
||||||
bvalue.context_specific = false;
|
|
||||||
bvalue.tag = BACNET_APPLICATION_TAG_UNSIGNED_INT;
|
|
||||||
bvalue.type.Unsigned_Int = value;
|
|
||||||
|
|
||||||
return bacnet_settings_value_set(object_type, object_instance,
|
|
||||||
property_id, array_index, &bvalue);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get a BACnet SIGNED INTEGER value from non-volatile storage
|
|
||||||
* @param object_type [in] The BACnet object type
|
|
||||||
* @param object_instance [in] The BACnet object instance
|
|
||||||
* @param property_id [in] The BACnet property id
|
|
||||||
* @param array_index [in] The BACnet array index
|
|
||||||
* @param default_value [in] The default value if not found
|
|
||||||
* @return stored data length on success 0..N, negative on failure.
|
|
||||||
*/
|
|
||||||
int bacnet_settings_signed_get(uint16_t object_type, uint32_t object_instance,
|
|
||||||
uint32_t property_id, uint32_t array_index,
|
|
||||||
int32_t default_value, int32_t *value)
|
|
||||||
{
|
|
||||||
uint8_t name[BACNET_STORAGE_VALUE_SIZE_MAX + 1] = { 0 };
|
|
||||||
BACNET_STORAGE_KEY key = { 0 };
|
|
||||||
int stored_len, len;
|
|
||||||
|
|
||||||
bacnet_storage_key_init(&key, object_type, object_instance, property_id,
|
|
||||||
array_index);
|
|
||||||
stored_len = bacnet_storage_get(&key, name, sizeof(name));
|
|
||||||
if (stored_len > 0) {
|
|
||||||
len = bacnet_signed_application_decode(name, stored_len, value);
|
|
||||||
if (len <= 0) {
|
|
||||||
if (value) {
|
|
||||||
*value = default_value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (value) {
|
|
||||||
*value = default_value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return stored_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Store a BACnet SIGNED INTEGER value in non-volatile storage
|
|
||||||
* @param object_type [in] The BACnet object type
|
|
||||||
* @param object_instance [in] The BACnet object instance
|
|
||||||
* @param property_id [in] The BACnet property id
|
|
||||||
* @param array_index [in] The BACnet array index
|
|
||||||
* @param value [in] The value to store
|
|
||||||
* @return true on success, false on failure.
|
|
||||||
*/
|
|
||||||
bool bacnet_settings_signed_set(uint16_t object_type, uint32_t object_instance,
|
|
||||||
uint32_t property_id, uint32_t array_index,
|
|
||||||
int32_t value)
|
|
||||||
{
|
|
||||||
BACNET_APPLICATION_DATA_VALUE bvalue = { 0 };
|
|
||||||
|
|
||||||
bvalue.context_specific = false;
|
|
||||||
bvalue.tag = BACNET_APPLICATION_TAG_SIGNED_INT;
|
|
||||||
bvalue.type.Signed_Int = value;
|
|
||||||
|
|
||||||
return bacnet_settings_value_set(object_type, object_instance,
|
|
||||||
property_id, array_index, &bvalue);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get a BACnet CHARACTER_STRING value from non-volatile storage
|
|
||||||
* @param object_type [in] The BACnet object type
|
|
||||||
* @param object_instance [in] The BACnet object instance
|
|
||||||
* @param property_id [in] The BACnet property id
|
|
||||||
* @param default_value [in] The default value if not found
|
|
||||||
* @param value [out] The character string value
|
|
||||||
* @return stored data length on success 0..N, negative on failure.
|
|
||||||
*/
|
|
||||||
int bacnet_settings_characterstring_get(uint16_t object_type,
|
|
||||||
uint32_t object_instance,
|
|
||||||
uint32_t property_id,
|
|
||||||
uint32_t array_index,
|
|
||||||
const char *default_value,
|
|
||||||
BACNET_CHARACTER_STRING *value)
|
|
||||||
{
|
|
||||||
uint8_t name[BACNET_STORAGE_VALUE_SIZE_MAX + 1] = { 0 };
|
|
||||||
BACNET_STORAGE_KEY key = { 0 };
|
|
||||||
int stored_len, len;
|
|
||||||
|
|
||||||
bacnet_storage_key_init(&key, object_type, object_instance, property_id,
|
|
||||||
array_index);
|
|
||||||
stored_len = bacnet_storage_get(&key, name, sizeof(name));
|
|
||||||
if (stored_len > 0) {
|
|
||||||
len = bacnet_character_string_application_decode(
|
|
||||||
name, stored_len, value);
|
|
||||||
if (len <= 0) {
|
|
||||||
characterstring_init_ansi(value, default_value);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
characterstring_init_ansi(value, default_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return stored_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Store a BACnet CHARACTER_STRING value to non-volatile storage
|
|
||||||
* @param object_type [in] The BACnet object type
|
|
||||||
* @param object_instance [in] The BACnet object instance
|
|
||||||
* @param property_id [in] The BACnet property id
|
|
||||||
* @param default_value [in] The default value if not found
|
|
||||||
* @param value [out] The character string value
|
|
||||||
* @return true on success, false on failure.
|
|
||||||
*/
|
|
||||||
bool bacnet_settings_characterstring_ansi_set(uint16_t object_type,
|
|
||||||
uint32_t object_instance,
|
|
||||||
uint32_t property_id,
|
|
||||||
uint32_t array_index,
|
|
||||||
const char *cstring)
|
|
||||||
{
|
|
||||||
BACNET_APPLICATION_DATA_VALUE bvalue = { 0 };
|
|
||||||
bool status;
|
|
||||||
|
|
||||||
bvalue.context_specific = false;
|
|
||||||
bvalue.tag = BACNET_APPLICATION_TAG_CHARACTER_STRING;
|
|
||||||
status = characterstring_init_ansi(&bvalue.type.Character_String,
|
|
||||||
cstring);
|
|
||||||
if (!status) {
|
|
||||||
status = bacnet_settings_value_set(object_type, object_instance,
|
|
||||||
property_id, array_index,
|
|
||||||
&bvalue);
|
|
||||||
}
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get a C-string value from non-volatile storage
|
|
||||||
* @param object_type [in] The BACnet object type
|
|
||||||
* @param object_instance [in] The BACnet object instance
|
|
||||||
* @param property_id [in] The BACnet property id
|
|
||||||
* @param default_value [in] The default value if not found
|
|
||||||
* @param value [out] The string value
|
|
||||||
* @param value_size [in] The size of the string value
|
|
||||||
* @return stored data length on success 0..N, negative on failure.
|
|
||||||
*/
|
|
||||||
int bacnet_settings_string_get(uint16_t object_type, uint32_t object_instance,
|
|
||||||
uint32_t property_id, uint32_t array_index,
|
|
||||||
const char *default_value, char *value,
|
|
||||||
size_t value_size)
|
|
||||||
{
|
|
||||||
BACNET_STORAGE_KEY key = { 0 };
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
bacnet_storage_key_init(&key, object_type, object_instance, property_id,
|
|
||||||
array_index);
|
|
||||||
rc = bacnet_storage_get(&key, value, value_size);
|
|
||||||
if (rc <= 0) {
|
|
||||||
if (default_value) {
|
|
||||||
strncpy(value, default_value, value_size);
|
|
||||||
rc = strlen(default_value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get a C-string value from non-volatile storage
|
|
||||||
* @param object_type [in] The BACnet object type
|
|
||||||
* @param object_instance [in] The BACnet object instance
|
|
||||||
* @param property_id [in] The BACnet property id
|
|
||||||
* @param default_value [in] The default value if not found
|
|
||||||
* @param value [in] The character string value
|
|
||||||
* @return true on success, false on failure.
|
|
||||||
*/
|
|
||||||
bool bacnet_settings_string_set(uint16_t object_type, uint32_t object_instance,
|
|
||||||
uint32_t property_id, uint32_t array_index,
|
|
||||||
const char *value)
|
|
||||||
{
|
|
||||||
BACNET_STORAGE_KEY key = { 0 };
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
if (!value) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bacnet_storage_key_init(&key, object_type, object_instance, property_id,
|
|
||||||
array_index);
|
|
||||||
rc = bacnet_storage_set(&key, (const char *)value, strlen(value) + 1);
|
|
||||||
|
|
||||||
return rc == 0;
|
|
||||||
}
|
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
* @brief The BACnet shell commands for debugging and testing
|
|
||||||
* @author Steve Karg <skarg@users.sourceforge.net>
|
|
||||||
* @date May 2024
|
|
||||||
* @copyright SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <zephyr/shell/shell.h>
|
|
||||||
#include <bacnet_settings/bacnet_storage.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get or set a string using BACnet storage subsystem
|
|
||||||
* @param sh Shell
|
|
||||||
* @param argc Number of arguments
|
|
||||||
* @param argv Argument list
|
|
||||||
* @return 0 on success, negative on failure
|
|
||||||
*/
|
|
||||||
static int cmd_key(BACNET_STORAGE_KEY *key, const struct shell *sh, size_t argc,
|
|
||||||
char **argv)
|
|
||||||
{
|
|
||||||
uint16_t object_type;
|
|
||||||
uint32_t object_instance;
|
|
||||||
uint32_t property_id = 77;
|
|
||||||
uint32_t array_index = BACNET_STORAGE_ARRAY_INDEX_NONE;
|
|
||||||
long value = 0;
|
|
||||||
|
|
||||||
if (argc < 3) {
|
|
||||||
shell_error(
|
|
||||||
sh,
|
|
||||||
"Usage: %s <object-type> <instance> <property> [value]",
|
|
||||||
argv[0]);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
value = strtoul(argv[1], NULL, 0);
|
|
||||||
if ((value < 0) || (value >= UINT16_MAX)) {
|
|
||||||
shell_error(sh, "Invalid object-type: %s. Must be 0-65535.",
|
|
||||||
argv[1]);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
object_type = (uint16_t)value;
|
|
||||||
value = strtoul(argv[2], NULL, 0);
|
|
||||||
if (value > 4194303) {
|
|
||||||
shell_error(sh,
|
|
||||||
"Invalid object-instance: %s. Must be 0-4194303.",
|
|
||||||
argv[2]);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
object_instance = (uint32_t)value;
|
|
||||||
value = strtoul(argv[3], NULL, 0);
|
|
||||||
if (value > UINT32_MAX) {
|
|
||||||
shell_error(sh, "Invalid property: %s. Must be 0-4294967295.",
|
|
||||||
argv[3]);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
property_id = (uint32_t)value;
|
|
||||||
/* setup the storage key */
|
|
||||||
bacnet_storage_key_init(key, object_type, object_instance, property_id,
|
|
||||||
array_index);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get or set a string using BACnet storage subsystem
|
|
||||||
* @param sh Shell
|
|
||||||
* @param argc Number of arguments
|
|
||||||
* @param argv Argument list
|
|
||||||
* @return 0 on success, negative on failure
|
|
||||||
*/
|
|
||||||
static int cmd_string(const struct shell *sh, size_t argc, char **argv)
|
|
||||||
{
|
|
||||||
char key_name[BACNET_STORAGE_KEY_SIZE_MAX + 1] = { 0 };
|
|
||||||
uint8_t data[BACNET_STORAGE_VALUE_SIZE_MAX + 1] = { 0 };
|
|
||||||
BACNET_STORAGE_KEY key = { 0 };
|
|
||||||
size_t arg_len = 0;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
rc = cmd_key(&key, sh, argc, argv);
|
|
||||||
if (rc < 0) {
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
/* convert the key to a string for the shell */
|
|
||||||
(void)bacnet_storage_key_encode(key_name, sizeof(key_name), &key);
|
|
||||||
if (argc > 4) {
|
|
||||||
arg_len = strlen(argv[4]);
|
|
||||||
rc = bacnet_storage_set(&key, argv[4], arg_len);
|
|
||||||
if (rc == 0) {
|
|
||||||
shell_print(sh, "Set %s = %s", key_name, argv[4]);
|
|
||||||
} else {
|
|
||||||
shell_error(sh, "Unable to set %s = %s", key_name,
|
|
||||||
argv[4]);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
rc = bacnet_storage_get(&key, data, sizeof(data));
|
|
||||||
if (rc < 0) {
|
|
||||||
shell_error(sh, "Unable to get %s", key_name);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
shell_print(sh, "Get %s = %s", key_name, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
SHELL_STATIC_SUBCMD_SET_CREATE(sub_bacnet_settings_cmds,
|
|
||||||
SHELL_CMD(string, NULL,
|
|
||||||
"get or set BACnet storage string",
|
|
||||||
cmd_string),
|
|
||||||
SHELL_SUBCMD_SET_END);
|
|
||||||
|
|
||||||
SHELL_SUBCMD_ADD((bacnet), settings, &sub_bacnet_settings_cmds,
|
|
||||||
"BACnet settings commands", NULL, 1, 0);
|
|
||||||
@@ -1,266 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
* @brief The BACnet storage tasks for handling the device specific object data
|
|
||||||
* @author Steve Karg <skarg@users.sourceforge.net>
|
|
||||||
* @date April 2024
|
|
||||||
* @copyright SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <zephyr/settings/settings.h>
|
|
||||||
#if defined(CONFIG_SETTINGS_FILE) && defined(CONFIG_FILE_SYSTEM_LITTLEFS)
|
|
||||||
#include <zephyr/fs/fs.h>
|
|
||||||
#include <zephyr/fs/littlefs.h>
|
|
||||||
#elif defined(CONFIG_SETTINGS_FILE) && defined(CONFIG_FILE_SYSTEM_EXT2)
|
|
||||||
#include <zephyr/fs/fs.h>
|
|
||||||
#include <zephyr/fs/ext2.h>
|
|
||||||
#endif
|
|
||||||
/* me! */
|
|
||||||
#include "bacnet_settings/bacnet_storage.h"
|
|
||||||
|
|
||||||
#ifdef CONFIG_BACNET_SETTINGS_BASE_NAME
|
|
||||||
#define BACNET_STORAGE_BASE_NAME CONFIG_BACNET_SETTINGS_BASE_NAME
|
|
||||||
#else
|
|
||||||
#define BACNET_STORAGE_BASE_NAME ".bacnet"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Logging module registration is already done in bacnet/ports/zephyr/main.c */
|
|
||||||
#include <zephyr/logging/log.h>
|
|
||||||
LOG_MODULE_DECLARE(bacnet, CONFIG_BACNETSTACK_LOG_LEVEL);
|
|
||||||
#define FAIL_MSG "fail (err %d)"
|
|
||||||
|
|
||||||
#define STORAGE_PARTITION storage_partition
|
|
||||||
#define STORAGE_PARTITION_ID FIXED_PARTITION_ID(STORAGE_PARTITION)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initialize the non-volatile data
|
|
||||||
*/
|
|
||||||
void bacnet_storage_init(void)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
#if defined(CONFIG_SETTINGS_FILE) && defined(CONFIG_FILE_SYSTEM_LITTLEFS)
|
|
||||||
FS_LITTLEFS_DECLARE_DEFAULT_CONFIG(cstorage);
|
|
||||||
|
|
||||||
/* mounting info */
|
|
||||||
static struct fs_mount_t littlefs_mnt = {
|
|
||||||
.type = FS_LITTLEFS,
|
|
||||||
.fs_data = &cstorage,
|
|
||||||
.storage_dev = (void *)STORAGE_PARTITION_ID,
|
|
||||||
.mnt_point = "/ff"
|
|
||||||
};
|
|
||||||
|
|
||||||
rc = fs_mount(&littlefs_mnt);
|
|
||||||
if (rc != 0) {
|
|
||||||
LOG_INF("mounting littlefs error: [%d]", rc);
|
|
||||||
} else {
|
|
||||||
rc = fs_unlink(CONFIG_SETTINGS_FILE_PATH);
|
|
||||||
if ((rc != 0) && (rc != -ENOENT)) {
|
|
||||||
H("can't delete config file%d", rc);
|
|
||||||
} else {
|
|
||||||
LOG_INF("FS initialized: OK");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
rc = settings_subsys_init();
|
|
||||||
if (rc) {
|
|
||||||
LOG_INF("settings subsys initialization: fail (err %d)", rc);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_INF("settings subsys initialization: OK.");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initialize a BACnet key object with optional array
|
|
||||||
* @param key BACnet key (type, instance, property, array index)
|
|
||||||
* @param object_type BACnet object type
|
|
||||||
* @param object_instance BACnet object instance
|
|
||||||
* @param property_id BACnet property id
|
|
||||||
* @param array_index BACnet array index
|
|
||||||
*/
|
|
||||||
void bacnet_storage_key_init(BACNET_STORAGE_KEY *key, uint16_t object_type,
|
|
||||||
uint32_t object_instance, uint32_t property_id,
|
|
||||||
uint32_t array_index)
|
|
||||||
{
|
|
||||||
if (key) {
|
|
||||||
key->object_type = object_type;
|
|
||||||
key->object_instance = object_instance;
|
|
||||||
key->property_id = property_id;
|
|
||||||
key->array_index = array_index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Create a storage key string for a BACnet object property
|
|
||||||
* @param buffer buffer to store key string
|
|
||||||
* @param buffer_size size of key buffer
|
|
||||||
* @param key BACnet key (type, instance, property, array index)
|
|
||||||
* @return length of the string
|
|
||||||
*/
|
|
||||||
int bacnet_storage_key_encode(char *buffer, size_t buffer_size,
|
|
||||||
BACNET_STORAGE_KEY *key)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
const char base_name[] = CONFIG_BACNET_STORAGE_BASE_NAME;
|
|
||||||
|
|
||||||
if (buffer) {
|
|
||||||
memset(buffer, 0, buffer_size);
|
|
||||||
}
|
|
||||||
if (key->array_index == BACNET_STORAGE_ARRAY_INDEX_NONE) {
|
|
||||||
rc = snprintf(buffer, buffer_size, "%s%c%u%c%lu%c%lu",
|
|
||||||
base_name, SETTINGS_NAME_SEPARATOR,
|
|
||||||
(unsigned short)key->object_type,
|
|
||||||
SETTINGS_NAME_SEPARATOR,
|
|
||||||
(unsigned long)key->object_instance,
|
|
||||||
SETTINGS_NAME_SEPARATOR,
|
|
||||||
(unsigned long)key->property_id);
|
|
||||||
} else {
|
|
||||||
rc = snprintf(buffer, buffer_size, "%s%c%u%c%lu%c%lu%c%lu",
|
|
||||||
base_name, SETTINGS_NAME_SEPARATOR,
|
|
||||||
(unsigned short)key->object_type,
|
|
||||||
SETTINGS_NAME_SEPARATOR,
|
|
||||||
(unsigned long)key->object_instance,
|
|
||||||
SETTINGS_NAME_SEPARATOR,
|
|
||||||
(unsigned long)key->property_id,
|
|
||||||
SETTINGS_NAME_SEPARATOR,
|
|
||||||
(unsigned long)key->array_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Set a value with a specific key to non-volatile storage
|
|
||||||
* @param key [in] Key in string format.
|
|
||||||
* @param data [in] one or more bytes of data
|
|
||||||
* @param data_len [in] Value length in bytes.
|
|
||||||
* @return 0 on success, non-zero on failure.
|
|
||||||
*/
|
|
||||||
int bacnet_storage_set(BACNET_STORAGE_KEY *key, const void *data,
|
|
||||||
size_t data_len)
|
|
||||||
{
|
|
||||||
char name[SETTINGS_MAX_NAME_LEN + 1] = { 0 };
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
rc = bacnet_storage_key_encode(name, sizeof(name), key);
|
|
||||||
LOG_INF("Set a key-value pair. Key=%s", name);
|
|
||||||
rc = settings_save_one(name, data, data_len);
|
|
||||||
if (rc) {
|
|
||||||
LOG_INF(FAIL_MSG, rc);
|
|
||||||
} else {
|
|
||||||
LOG_HEXDUMP_INF(data, data_len, "value");
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Structure to hold immediate values
|
|
||||||
*/
|
|
||||||
struct direct_immediate_value {
|
|
||||||
size_t value_size;
|
|
||||||
size_t value_len;
|
|
||||||
void *value;
|
|
||||||
bool fetched;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Direct loader for immediate values
|
|
||||||
* @param name [in] Key in string format.
|
|
||||||
* @param len [in] Length of the key
|
|
||||||
* @param read_cb [in] Callback to read the value
|
|
||||||
* @param cb_arg [in] Callback argument
|
|
||||||
* @param param [in] Callback parameter
|
|
||||||
* @return 0 on success, non-zero on failure.
|
|
||||||
*/
|
|
||||||
static int direct_loader_immediate_value(const char *name, size_t len,
|
|
||||||
settings_read_cb read_cb, void *cb_arg,
|
|
||||||
void *param)
|
|
||||||
{
|
|
||||||
const char *next;
|
|
||||||
size_t name_len;
|
|
||||||
int rc;
|
|
||||||
struct direct_immediate_value *context =
|
|
||||||
(struct direct_immediate_value *)param;
|
|
||||||
|
|
||||||
/* only the exact match and ignore descendants of the searched name */
|
|
||||||
name_len = settings_name_next(name, &next);
|
|
||||||
if (name_len == 0) {
|
|
||||||
rc = read_cb(cb_arg, context->value, len);
|
|
||||||
if ((rc >= 0) && (rc <= context->value_size)) {
|
|
||||||
context->fetched = true;
|
|
||||||
context->value_len = rc;
|
|
||||||
LOG_INF("immediate load: OK.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* other keys aren't served by the callback
|
|
||||||
* Return success in order to skip them
|
|
||||||
* and keep storage processing.
|
|
||||||
*/
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Load an immediate value from non-volatile storage
|
|
||||||
* @param name [in] Key in string format.
|
|
||||||
* @param value [out] Buffer to store the value
|
|
||||||
* @param value_size [in] size of the buffer
|
|
||||||
* @return value length in bytes on success 0..N, negative on failure.
|
|
||||||
*/
|
|
||||||
static int load_immediate_value(const char *name, void *value,
|
|
||||||
size_t value_size)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
struct direct_immediate_value context;
|
|
||||||
|
|
||||||
context.fetched = false;
|
|
||||||
context.value_size = value_size;
|
|
||||||
context.value_len = 0;
|
|
||||||
context.value = value;
|
|
||||||
|
|
||||||
rc = settings_load_subtree_direct(name, direct_loader_immediate_value,
|
|
||||||
(void *)&context);
|
|
||||||
if (rc == 0) {
|
|
||||||
if (!context.fetched) {
|
|
||||||
rc = -ENOENT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return context.value_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get a value with a specific key to non-volatile storage
|
|
||||||
* @param key [in] Key in string format.
|
|
||||||
* @param data [out] Binary value.
|
|
||||||
* @param data_size [in] requested value length in bytes
|
|
||||||
* @return data length on success 0..N, negative on failure.
|
|
||||||
*/
|
|
||||||
int bacnet_storage_get(BACNET_STORAGE_KEY *key, void *data, size_t data_size)
|
|
||||||
{
|
|
||||||
char name[SETTINGS_MAX_NAME_LEN + 1] = { 0 };
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
rc = bacnet_storage_key_encode(name, sizeof(name), key);
|
|
||||||
LOG_INF("Get a key-value pair. Key=<%s>", name);
|
|
||||||
rc = load_immediate_value(name, data, data_size);
|
|
||||||
if (rc == 0) {
|
|
||||||
LOG_INF("empty entry");
|
|
||||||
} else if (rc > 0) {
|
|
||||||
LOG_HEXDUMP_INF(data, rc, "value");
|
|
||||||
} else if (rc == -ENOENT) {
|
|
||||||
LOG_INF("no entry");
|
|
||||||
} else {
|
|
||||||
LOG_INF("unexpected" FAIL_MSG, rc);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file
|
|
||||||
* @brief The BACnet shell commands for debugging and testing
|
|
||||||
* @author Greg Shue <greg.shue@outlook.com>
|
|
||||||
* @date May 2024
|
|
||||||
* @copyright SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
#include <zephyr/shell/shell.h>
|
|
||||||
|
|
||||||
SHELL_SUBCMD_SET_CREATE(sub_bacnet_cmds, (bacnet));
|
|
||||||
|
|
||||||
SHELL_CMD_REGISTER(bacnet, &sub_bacnet_cmds, "BACnet module", NULL);
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
#
|
|
||||||
# Copyright (c) 2022 Legrand North America, LLC.
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: MIT
|
|
||||||
#
|
|
||||||
|
|
||||||
zephyr_compile_definitions(
|
|
||||||
BACNET_STACK_DEPRECATED_DISABLE
|
|
||||||
)
|
|
||||||
|
|
||||||
zephyr_sources(device.c)
|
|
||||||
|
|
||||||
if(CONFIG_BACNET_USE_DYNAMIC_DESCRIPTION)
|
|
||||||
zephyr_sources(
|
|
||||||
acc.c
|
|
||||||
access_credential.c
|
|
||||||
access_door.c
|
|
||||||
access_point.c
|
|
||||||
access_rights.c
|
|
||||||
access_user.c
|
|
||||||
access_zone.c
|
|
||||||
ai.c
|
|
||||||
ao.c
|
|
||||||
av.c
|
|
||||||
bacfile.c
|
|
||||||
bi.c
|
|
||||||
bo.c
|
|
||||||
bv.c
|
|
||||||
calendar.c
|
|
||||||
channel.c
|
|
||||||
command.c
|
|
||||||
credential_data_input.c
|
|
||||||
csv.c
|
|
||||||
iv.c
|
|
||||||
lc.c
|
|
||||||
lo.c
|
|
||||||
lsp.c
|
|
||||||
ms-input.c
|
|
||||||
mso.c
|
|
||||||
msv.c
|
|
||||||
nc.c
|
|
||||||
osv.c
|
|
||||||
piv.c
|
|
||||||
schedule.c
|
|
||||||
time_value.c
|
|
||||||
trendlog.c
|
|
||||||
)
|
|
||||||
|
|
||||||
zephyr_sources_ifdef(CONFIG_BACDL_BIP netport.c)
|
|
||||||
|
|
||||||
zephyr_linker_sources(DATA_SECTIONS objects.ld)
|
|
||||||
|
|
||||||
endif()
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
# Feature configuration options for BACnet-Stack
|
|
||||||
|
|
||||||
# Copyright (c) 2022 Legrand North America, LLC.
|
|
||||||
# SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
if BACNETSTACK
|
|
||||||
|
|
||||||
config BACNET_USE_DYNAMIC_DESCRIPTION
|
|
||||||
bool "Use dynalic allocate for objects descriptions"
|
|
||||||
default false
|
|
||||||
help
|
|
||||||
Use dynalic allocate for objects descriptions
|
|
||||||
|
|
||||||
endif # BACNETSTACK
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022 Legrand North America, LLC.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* BACnet accumulator Objects used to represent meter registers */
|
|
||||||
|
|
||||||
#include "object.h"
|
|
||||||
#include "bacnet/basic/object/acc.h"
|
|
||||||
|
|
||||||
OBJECT_FUNCTIONS(Accumulator, ACCUMULATOR_DESCR);
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022 Legrand North America, LLC.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Access Credential Objects - customize for your use */
|
|
||||||
|
|
||||||
#include "object.h"
|
|
||||||
#include "bacnet/basic/object/access_credential.h"
|
|
||||||
|
|
||||||
OBJECT_FUNCTIONS(Access_Credential, ACCESS_CREDENTIAL_DESCR);
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022 Legrand North America, LLC.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Access Door Objects - customize for your use */
|
|
||||||
|
|
||||||
#include "object.h"
|
|
||||||
#include "bacnet/basic/object/access_door.h"
|
|
||||||
|
|
||||||
OBJECT_FUNCTIONS(Access_Door, ACCESS_DOOR_DESCR);
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022 Legrand North America, LLC.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Access Point Objects - customize for your use */
|
|
||||||
|
|
||||||
#include "object.h"
|
|
||||||
#include "bacnet/basic/object/access_point.h"
|
|
||||||
|
|
||||||
OBJECT_FUNCTIONS(Access_Point, ACCESS_POINT_DESCR);
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022 Legrand North America, LLC.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Access Rights Objects - customize for your use */
|
|
||||||
|
|
||||||
#include "object.h"
|
|
||||||
#include "bacnet/basic/object/access_rights.h"
|
|
||||||
|
|
||||||
OBJECT_FUNCTIONS(Access_Rights, ACCESS_RIGHTS_DESCR);
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022 Legrand North America, LLC.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Access User Objects - customize for your use */
|
|
||||||
|
|
||||||
#include "object.h"
|
|
||||||
#include "bacnet/basic/object/access_user.h"
|
|
||||||
|
|
||||||
OBJECT_FUNCTIONS(Access_User, ACCESS_USER_DESCR);
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022 Legrand North America, LLC.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Access Zone Objects - customize for your use */
|
|
||||||
|
|
||||||
#include "object.h"
|
|
||||||
#include "bacnet/basic/object/access_zone.h"
|
|
||||||
|
|
||||||
OBJECT_FUNCTIONS(Access_Zone, ACCESS_ZONE_DESCR);
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022 Legrand North America, LLC.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Analog Input Objects - Zephyr specific part */
|
|
||||||
|
|
||||||
#include "object.h"
|
|
||||||
#include "bacnet/basic/object/ai.h"
|
|
||||||
|
|
||||||
OBJECT_FUNCTIONS_WITHOUT_INIT(Analog_Input, ANALOG_INPUT_DESCR);
|
|
||||||
|
|
||||||
void Analog_Input_Init(void)
|
|
||||||
{
|
|
||||||
if (!Object_List) {
|
|
||||||
Object_List = Keylist_Create();
|
|
||||||
|
|
||||||
#if defined(INTRINSIC_REPORTING)
|
|
||||||
/* Set handler for GetEventInformation function */
|
|
||||||
handler_get_event_information_set(
|
|
||||||
OBJECT_ANALOG_INPUT, Analog_Input_Event_Information);
|
|
||||||
/* Set handler for AcknowledgeAlarm function */
|
|
||||||
handler_alarm_ack_set(OBJECT_ANALOG_INPUT, Analog_Input_Alarm_Ack);
|
|
||||||
/* Set handler for GetAlarmSummary Service */
|
|
||||||
handler_get_alarm_summary_set(
|
|
||||||
OBJECT_ANALOG_INPUT, Analog_Input_Alarm_Summary);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022 Legrand North America, LLC.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Analog Output Objects - customize for your use */
|
|
||||||
|
|
||||||
#include "object.h"
|
|
||||||
#include "bacnet/basic/object/ao.h"
|
|
||||||
|
|
||||||
OBJECT_FUNCTIONS(Analog_Output, ANALOG_OUTPUT_DESCR);
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022 Legrand North America, LLC.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Analog Value Objects - customize for your use */
|
|
||||||
|
|
||||||
#include "object.h"
|
|
||||||
#include "bacnet/basic/object/av.h"
|
|
||||||
|
|
||||||
OBJECT_FUNCTIONS_WITHOUT_INIT(Analog_Value, ANALOG_VALUE_DESCR);
|
|
||||||
|
|
||||||
void Analog_Value_Init(void)
|
|
||||||
{
|
|
||||||
if (!Object_List) {
|
|
||||||
Object_List = Keylist_Create();
|
|
||||||
|
|
||||||
#if defined(INTRINSIC_REPORTING)
|
|
||||||
/* Set handler for GetEventInformation function */
|
|
||||||
handler_get_event_information_set(
|
|
||||||
OBJECT_ANALOG_VALUE, Analog_Value_Event_Information);
|
|
||||||
/* Set handler for AcknowledgeAlarm function */
|
|
||||||
handler_alarm_ack_set(OBJECT_ANALOG_VALUE, Analog_Value_Alarm_Ack);
|
|
||||||
/* Set handler for GetAlarmSummary Service */
|
|
||||||
handler_get_alarm_summary_set(
|
|
||||||
OBJECT_ANALOG_VALUE, Analog_Value_Alarm_Summary);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022 Legrand North America, LLC.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "object.h"
|
|
||||||
#include "bacnet/basic/object/bacfile.h"
|
|
||||||
|
|
||||||
OBJECT_FUNCTIONS(Bacfile, BACNET_FILE_LISTING);
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022 Legrand North America, LLC.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Binary Input Objects customize for your use */
|
|
||||||
|
|
||||||
#include "object.h"
|
|
||||||
#include "bacnet/basic/object/bi.h"
|
|
||||||
|
|
||||||
OBJECT_FUNCTIONS(Binary_Input, BINARY_INPUT_DESCR);
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022 Legrand North America, LLC.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Binary Output Objects - customize for your use */
|
|
||||||
|
|
||||||
#include "object.h"
|
|
||||||
#include "bacnet/basic/object/bo.h"
|
|
||||||
|
|
||||||
OBJECT_FUNCTIONS(Binary_Output, BINARY_OUTPUT_DESCR);
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022 Legrand North America, LLC.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Binary Value Objects - customize for your use */
|
|
||||||
|
|
||||||
#include "object.h"
|
|
||||||
#include "bacnet/basic/object/bv.h"
|
|
||||||
|
|
||||||
OBJECT_FUNCTIONS(Binary_Value, BINARY_VALUE_DESCR);
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022 Legrand North America, LLC.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "object.h"
|
|
||||||
#include "bacnet/basic/object/channel.h"
|
|
||||||
|
|
||||||
OBJECT_FUNCTIONS(Channel, CHANNEL_OBJECT);
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022 Legrand North America, LLC.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "object.h"
|
|
||||||
#include "bacnet/basic/object/command.h"
|
|
||||||
|
|
||||||
OBJECT_FUNCTIONS(Command, COMMAND_DESCR);
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022 Legrand North America, LLC.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Credential Data Input Objects - customize for your use */
|
|
||||||
|
|
||||||
#include "object.h"
|
|
||||||
#include "bacnet/basic/object/credential_data_input.h"
|
|
||||||
|
|
||||||
OBJECT_FUNCTIONS(Credential_Data_Input, CREDENTIAL_DATA_INPUT_DESCR);
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022 Legrand North America, LLC.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* CharacterString Value Objects */
|
|
||||||
|
|
||||||
#include "object.h"
|
|
||||||
#include "bacnet/basic/object/csv.h"
|
|
||||||
|
|
||||||
OBJECT_FUNCTIONS(CharacterString_Value, CHARACTERSTRING_DESCR);
|
|
||||||
@@ -1,114 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022 Legrand North America, LLC.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file device.c Zephyr specific part of the Base "class". */
|
|
||||||
|
|
||||||
#ifdef CONFIG_BACNET_USE_SECTION_ITERABLE_OBJECT_TABLE
|
|
||||||
#include <zephyr/kernel.h>
|
|
||||||
#endif
|
|
||||||
#include "bacnet/basic/object/device.h"
|
|
||||||
#include "object.h"
|
|
||||||
|
|
||||||
#ifdef CONFIG_BACNET_USE_SECTION_ITERABLE_OBJECT_TABLE
|
|
||||||
extern struct object_functions _object_functions_list_end[];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BAC_ROUTING
|
|
||||||
static object_functions Routing_object = {
|
|
||||||
.Object_Type = OBJECT_DEVICE,
|
|
||||||
.Object_Init = NULL,
|
|
||||||
.Object_Count = Device_Count,
|
|
||||||
.Object_Index_To_Instance = Routed_Device_Index_To_Instance,
|
|
||||||
.Object_Valid_Instance = Routed_Device_Valid_Object_Instance_Number,
|
|
||||||
.Object_Name = Routed_Device_Name,
|
|
||||||
.Object_Read_Property = Routed_Device_Read_Property_Local,
|
|
||||||
.Object_Write_Property = Routed_Device_Write_Property_Local,
|
|
||||||
.Object_RPM_List = Device_Property_Lists,
|
|
||||||
.Object_RR_Info = DeviceGetRRInfo
|
|
||||||
.Object_Iterator = NULL,
|
|
||||||
.Object_Value_List = NULL,
|
|
||||||
.Object_COV = NULL,
|
|
||||||
.Object_COV_Clear = NULL,
|
|
||||||
.Object_Intrinsic_Reporting = NULL,
|
|
||||||
};
|
|
||||||
static bool routing_Device = false;
|
|
||||||
|
|
||||||
/* In Zephyr port the object_functions table is saved in ROM and
|
|
||||||
can't change fields value.
|
|
||||||
Instead this Device_Objects_Get_First(Next)_Object() returns the "Routing"
|
|
||||||
object when asked "Device" object, see static filter functions. */
|
|
||||||
void Routing_Device_Init(uint32_t first_object_instance)
|
|
||||||
{
|
|
||||||
/* Initialize with our preset strings */
|
|
||||||
Add_Routed_Device(first_object_instance, &My_Object_Name, Description);
|
|
||||||
|
|
||||||
routing_Device = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* BAC_ROUTING */
|
|
||||||
|
|
||||||
#ifdef CONFIG_BACNET_USE_SECTION_ITERABLE_OBJECT_TABLE
|
|
||||||
static struct object_functions *Device_Object_Filter_Out(
|
|
||||||
struct object_functions *pObject)
|
|
||||||
{
|
|
||||||
#if BAC_ROUTING
|
|
||||||
if (routing_Device && pObject == &Device_object)
|
|
||||||
return &Routing_object;
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
return pObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct object_functions *Device_Object_Filter_In(
|
|
||||||
struct object_functions *pObject)
|
|
||||||
{
|
|
||||||
#if BAC_ROUTING
|
|
||||||
if (routing_Device && pObject == &Routing_object)
|
|
||||||
return &Device_object;
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
return pObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct object_functions *Device_Objects_Get_First_Object(void)
|
|
||||||
{
|
|
||||||
STRUCT_SECTION_FOREACH(object_functions, pObject) {
|
|
||||||
return Device_Object_Filter_Out(pObject);
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct object_functions *Device_Objects_Get_Next_Object(
|
|
||||||
struct object_functions *object)
|
|
||||||
{
|
|
||||||
if (object == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
object = Device_Object_Filter_In(object);
|
|
||||||
++object;
|
|
||||||
|
|
||||||
if (object < _object_functions_list_end) {
|
|
||||||
return Device_Object_Filter_Out(object);
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_BACNET_USE_SECTION_ITERABLE_OBJECT_TABLE */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allocate a Bacnet object
|
|
||||||
*/
|
|
||||||
void* Bacnet_Object_Allocate(size_t size)
|
|
||||||
{
|
|
||||||
return k_malloc(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Free a Bacnet object
|
|
||||||
*/
|
|
||||||
void Bacnet_Object_Free(void *descr)
|
|
||||||
{
|
|
||||||
k_free(descr);
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022 Legrand North America, LLC.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "object.h"
|
|
||||||
#include "bacnet/basic/object/iv.h"
|
|
||||||
|
|
||||||
OBJECT_FUNCTIONS(Integer_Value, struct integer_object);
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022 Legrand North America, LLC.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Load Control Objects - customize for your use */
|
|
||||||
/* from 135-2004-Addendum e */
|
|
||||||
|
|
||||||
#include "object.h"
|
|
||||||
#include "bacnet/basic/object/lc.h"
|
|
||||||
|
|
||||||
OBJECT_FUNCTIONS(Load_Control, struct Load_Control);
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022 Legrand North America, LLC.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "object.h"
|
|
||||||
#include "bacnet/basic/object/lo.h"
|
|
||||||
|
|
||||||
OBJECT_FUNCTIONS(Lighting_Output, struct lighting_output_object);
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022 Legrand North America, LLC.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Life Safety Point Objects - customize for your use */
|
|
||||||
|
|
||||||
#include "object.h"
|
|
||||||
#include "bacnet/basic/object/lsp.h"
|
|
||||||
|
|
||||||
OBJECT_FUNCTIONS(Life_Safety_Point, struct life_safety_point_object);
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022 Legrand North America, LLC.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Multi-state Input Objects */
|
|
||||||
|
|
||||||
#include "object.h"
|
|
||||||
#include "bacnet/basic/object/ms-input.h"
|
|
||||||
|
|
||||||
OBJECT_FUNCTIONS(Multistate_Input, MULTISTATE_INPUT_DESCR);
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022 Legrand North America, LLC.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Multi-state Output Objects - customize for your use */
|
|
||||||
|
|
||||||
#include "object.h"
|
|
||||||
#include "bacnet/basic/object/mso.h"
|
|
||||||
|
|
||||||
OBJECT_FUNCTIONS(Multistate_Output, MULTISTATE_OUTPUT_DESCR);
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022 Legrand North America, LLC.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Multi-state Value Objects */
|
|
||||||
|
|
||||||
#include "object.h"
|
|
||||||
#include "bacnet/basic/object/msv.h"
|
|
||||||
|
|
||||||
OBJECT_FUNCTIONS(Multistate_Value, MULTISTATE_VALUE_DESCR);
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022 Legrand North America, LLC.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "object.h"
|
|
||||||
#include "bacnet/basic/object/nc.h"
|
|
||||||
|
|
||||||
#if defined(INTRINSIC_REPORTING)
|
|
||||||
OBJECT_FUNCTIONS(Notification_Class, NOTIFICATION_CLASS_INFO);
|
|
||||||
#endif
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022 Legrand North America, LLC.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "object.h"
|
|
||||||
#include "bacnet/readrange.h"
|
|
||||||
#include "bacnet/basic/object/netport.h"
|
|
||||||
|
|
||||||
OBJECT_FUNCTIONS(Network_Port, struct netport_object_data);
|
|
||||||
|
|
||||||
bool Network_Port_Object_Instance_Number_Set(
|
|
||||||
unsigned index, uint32_t object_instance)
|
|
||||||
{
|
|
||||||
struct netport_object_data *descr;
|
|
||||||
|
|
||||||
uint32_t old_inst = Network_Port_Index_To_Instance(index);
|
|
||||||
descr = Keylist_Data_Delete(Object_List, old_inst);
|
|
||||||
if (descr == NULL) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
descr->Instance_Number = object_instance;
|
|
||||||
return Keylist_Data_Add(Object_List, object_instance, descr) >= 0;
|
|
||||||
}
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022 Legrand North America, LLC.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ZTEST_UNITTEST
|
|
||||||
#include <zephyr/kernel.h>
|
|
||||||
#else
|
|
||||||
#include "stdlib.h"
|
|
||||||
#define k_malloc(a) malloc(a)
|
|
||||||
#define k_free(a) free(a)
|
|
||||||
|
|
||||||
#define _DO_CONCAT(x, y) x ## y
|
|
||||||
#define _CONCAT(x, y) _DO_CONCAT(x, y)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#include "bacnet/bacdef.h" // Must be before all other bacnet/*.h files
|
|
||||||
#include "bacnet/basic/sys/keylist.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define OBJECT_ENUM_FUNCTIONS(object_name, descr_type) \
|
|
||||||
descr_type *_CONCAT(object_name, _Find_Description)(uint32_t instance) \
|
|
||||||
{ return Keylist_Data(Object_List, instance); } \
|
|
||||||
unsigned _CONCAT(object_name, _Count)(void) \
|
|
||||||
{ return Keylist_Count(Object_List); } \
|
|
||||||
uint32_t _CONCAT(object_name, _Index_To_Instance)(unsigned index) \
|
|
||||||
{ return Keylist_Key(Object_List, index); } \
|
|
||||||
unsigned _CONCAT(object_name, _Instance_To_Index)(uint32_t instance) \
|
|
||||||
{ return (unsigned)Keylist_Index(Object_List, instance); }
|
|
||||||
|
|
||||||
|
|
||||||
#define OBJECT_MEMORY_FUNCTIONS(object_name, descr_type) \
|
|
||||||
bool _CONCAT(object_name, _Create)(uint32_t instance) \
|
|
||||||
{ \
|
|
||||||
descr_type *descr = Keylist_Data(Object_List, instance); \
|
|
||||||
if (!descr) { \
|
|
||||||
descr = k_malloc(sizeof(descr_type)); \
|
|
||||||
if (descr) { \
|
|
||||||
_CONCAT(object_name, _Init_Description)(descr, instance); \
|
|
||||||
return Keylist_Data_Add(Object_List, instance, descr) >= 0; \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
return false; \
|
|
||||||
} \
|
|
||||||
void _CONCAT(object_name, _Cleanup)(void) \
|
|
||||||
{ \
|
|
||||||
descr_type *descr; \
|
|
||||||
if (Object_List) { \
|
|
||||||
do { \
|
|
||||||
descr = Keylist_Data_Pop(Object_List); \
|
|
||||||
if (descr) { \
|
|
||||||
k_free(descr); \
|
|
||||||
} \
|
|
||||||
} while (descr); \
|
|
||||||
Keylist_Delete(Object_List); \
|
|
||||||
Object_List = NULL; \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
bool _CONCAT(object_name, _Delete)(uint32_t instance) \
|
|
||||||
{ \
|
|
||||||
bool status = false; \
|
|
||||||
descr_type *descr = Keylist_Data_Delete(Object_List, instance); \
|
|
||||||
if (descr) { \
|
|
||||||
k_free(descr); \
|
|
||||||
status = true; \
|
|
||||||
} \
|
|
||||||
return status; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define OBJECT_FUNCTIONS_WITHOUT_INIT(object_name, descr_type) \
|
|
||||||
static OS_Keylist Object_List = NULL; \
|
|
||||||
OBJECT_ENUM_FUNCTIONS(object_name, descr_type) \
|
|
||||||
OBJECT_MEMORY_FUNCTIONS(object_name, descr_type)
|
|
||||||
|
|
||||||
#define OBJECT_FUNCTIONS(object_name, descr_type) \
|
|
||||||
OBJECT_FUNCTIONS_WITHOUT_INIT(object_name, descr_type) \
|
|
||||||
void _CONCAT(object_name, _Init)(void){ \
|
|
||||||
if (!Object_List) { \
|
|
||||||
Object_List = Keylist_Create(); \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
ITERABLE_SECTION_ROM(object_functions, 4)
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022 Legrand North America, LLC.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "object.h"
|
|
||||||
#include "bacnet/basic/object/osv.h"
|
|
||||||
|
|
||||||
OBJECT_FUNCTIONS(OctetString_Value, OCTETSTRING_VALUE_DESCR);
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022 Legrand North America, LLC.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Positiveinteger Value Objects - customize for your use */
|
|
||||||
|
|
||||||
#include "object.h"
|
|
||||||
#include "bacnet/basic/object/piv.h"
|
|
||||||
|
|
||||||
OBJECT_FUNCTIONS(PositiveInteger_Value, POSITIVEINTEGER_VALUE_DESCR);
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022 Legrand North America, LLC.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "object.h"
|
|
||||||
#include "bacnet/basic/object/schedule.h"
|
|
||||||
|
|
||||||
OBJECT_FUNCTIONS(Schedule, SCHEDULE_DESCR);
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022 Legrand North America, LLC.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "object.h"
|
|
||||||
#include "bacnet/readrange.h"
|
|
||||||
#include "bacnet/basic/object/trendlog.h"
|
|
||||||
|
|
||||||
OBJECT_FUNCTIONS(Trend_Log, TL_DESCR);
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
# Copyright (c) 2020 Legrand North America, LLC.
|
|
||||||
# SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
zephyr_include_directories(include)
|
|
||||||
|
|
||||||
zephyr_interface_library_named(bac_server)
|
|
||||||
|
|
||||||
zephyr_library()
|
|
||||||
zephyr_library_sources(server.c)
|
|
||||||
|
|
||||||
zephyr_library_link_libraries(bac_server)
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
# Copyright (c) 2020 Legrand North America, LLC.
|
|
||||||
# SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
|
|
||||||
# Kconfig -
|
|
||||||
|
|
||||||
menuconfig BACNETSTACK_BACNET_SERVER
|
|
||||||
bool "BACNETSTACK_BACNET_SERVER"
|
|
||||||
help
|
|
||||||
This option enables BACnet Server services
|
|
||||||
|
|
||||||
if BACNETSTACK_BACNET_SERVER
|
|
||||||
|
|
||||||
module = BACNETSTACK_BACNET_SERVER
|
|
||||||
module-str = bac_server
|
|
||||||
|
|
||||||
config BACNETSTACK_BACNET_SERVER_APP_PRIORITY
|
|
||||||
int "App init priority"
|
|
||||||
default 0
|
|
||||||
help
|
|
||||||
This sets the starting priority of the thread.
|
|
||||||
|
|
||||||
config BACNETSTACK_BACNET_SERVER_PRIO
|
|
||||||
int "BACnet server thread priority"
|
|
||||||
default 50
|
|
||||||
help
|
|
||||||
This sets the execution priority of the thread.
|
|
||||||
|
|
||||||
config BACNETSTACK_BACNET_SERVER_STACK_SIZE
|
|
||||||
int "BACnet server stack size"
|
|
||||||
default 4096
|
|
||||||
help
|
|
||||||
This sets the stack size of the thread.
|
|
||||||
|
|
||||||
endif # BACNETSTACK_BACNET_SERVER
|
|
||||||
@@ -1,242 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2020 Legrand North America, LLC.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdalign.h> /*TODO: Not std until C11! */
|
|
||||||
#include <device.h>
|
|
||||||
#include <init.h>
|
|
||||||
#include <kernel.h>
|
|
||||||
#include <net/net_if.h>
|
|
||||||
#include <net/net_core.h>
|
|
||||||
#include <net/net_context.h>
|
|
||||||
#include <net/net_mgmt.h>
|
|
||||||
#include <net/net_ip.h>
|
|
||||||
#include <sys/printk.h>
|
|
||||||
/* some BACnet modules we use */
|
|
||||||
#include "bacnet/bacdef.h"
|
|
||||||
#include "bacnet/config.h"
|
|
||||||
#include "bacnet/bactext.h"
|
|
||||||
#include "bacnet/bacerror.h"
|
|
||||||
#include "bacnet/iam.h"
|
|
||||||
#include "bacnet/arf.h"
|
|
||||||
#include "bacnet/npdu.h"
|
|
||||||
#include "bacnet/apdu.h"
|
|
||||||
#include "bacnet/version.h"
|
|
||||||
/* some demo modules we use */
|
|
||||||
#include "bacnet/basic/sys/debug.h"
|
|
||||||
#include "bacnet/basic/tsm/tsm.h"
|
|
||||||
#include "bacnet/basic/binding/address.h"
|
|
||||||
#include "bacnet/basic/services.h"
|
|
||||||
/* our datalink layers */
|
|
||||||
#include "bacnet/datalink/bip.h"
|
|
||||||
#include "bacnet/datalink/bvlc.h"
|
|
||||||
/* include the device object */
|
|
||||||
#include "bacnet/basic/object/device.h"
|
|
||||||
|
|
||||||
/* Logging module registration is already done in ports/zephyr/main.c */
|
|
||||||
#include <logging/log.h>
|
|
||||||
LOG_MODULE_DECLARE(bacnet, CONFIG_BACNETSTACK_LOG_LEVEL);
|
|
||||||
|
|
||||||
enum bacnet_server_msg_type {
|
|
||||||
SERVER_MSG_TYPE_INVALID = 0,
|
|
||||||
SERVER_MSG_TYPE_IPV4_EVENT,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct bacnet_server_msg {
|
|
||||||
uint8_t type;
|
|
||||||
uint8_t dummy[3];
|
|
||||||
uint32_t parm_u32;
|
|
||||||
void *parm_ptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
K_MSGQ_DEFINE(bacnet_server_msgq, sizeof(struct bacnet_server_msg), 8,
|
|
||||||
alignof(struct bacnet_server_msg));
|
|
||||||
|
|
||||||
#define SERVER_IPV4_EVENTS_MASK \
|
|
||||||
(NET_EVENT_IPV4_ADDR_ADD | NET_EVENT_IPV4_ADDR_DEL)
|
|
||||||
|
|
||||||
static struct k_thread server_thread_data;
|
|
||||||
static K_THREAD_STACK_DEFINE(server_thread_stack,
|
|
||||||
CONFIG_BACNETSTACK_BACNET_SERVER_STACK_SIZE);
|
|
||||||
|
|
||||||
/* Keep a reference to the Ethernet interface */
|
|
||||||
static struct net_mgmt_event_callback mgmt_cb;
|
|
||||||
|
|
||||||
/* track our directly connected ports network number */
|
|
||||||
static uint16_t BIP_Net;
|
|
||||||
/* buffer for receiving packets from the directly connected ports */
|
|
||||||
static uint8_t BIP_Rx_Buffer[MAX_MPDU];
|
|
||||||
|
|
||||||
/** Initialize the handlers we will utilize.
|
|
||||||
* @see Device_Init, apdu_set_unconfirmed_handler, apdu_set_confirmed_handler
|
|
||||||
*/
|
|
||||||
static void service_handlers_init(void)
|
|
||||||
{
|
|
||||||
Device_Init(NULL);
|
|
||||||
/* we need to handle who-is to support dynamic device binding */
|
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS,
|
|
||||||
handler_who_is);
|
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_HAS,
|
|
||||||
handler_who_has);
|
|
||||||
/* set the handler for all the services we don't implement */
|
|
||||||
/* It is required to send the proper reject message... */
|
|
||||||
apdu_set_unrecognized_service_handler_handler(
|
|
||||||
handler_unrecognized_service);
|
|
||||||
/* Set the handlers for any confirmed services that we support. */
|
|
||||||
/* We must implement read property - it's required! */
|
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
|
||||||
handler_read_property);
|
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE,
|
|
||||||
handler_read_property_multiple);
|
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY,
|
|
||||||
handler_write_property);
|
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROP_MULTIPLE,
|
|
||||||
handler_write_property_multiple);
|
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_REINITIALIZE_DEVICE,
|
|
||||||
handler_reinitialize_device);
|
|
||||||
/* handle communication so we can shutup when asked */
|
|
||||||
apdu_set_confirmed_handler(
|
|
||||||
SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
|
|
||||||
handler_device_communication_control);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: Update copyright as this code pattern copied from
|
|
||||||
* conn_mgr_ipv4_events_handler()
|
|
||||||
*/
|
|
||||||
static void ipv4_events_handler(struct net_mgmt_event_callback *cb,
|
|
||||||
u32_t mgmt_event, struct net_if *iface)
|
|
||||||
{
|
|
||||||
static int counter = 0;
|
|
||||||
printk("\n*** Handler[%d]: IPv4 event %08x received on iface %p ***\n",
|
|
||||||
++counter, mgmt_event, iface);
|
|
||||||
|
|
||||||
if ((mgmt_event & SERVER_IPV4_EVENTS_MASK) != mgmt_event) {
|
|
||||||
printk("\n*** Handler[%d]: ignoring event %08x on iface %p ***\n",
|
|
||||||
counter, mgmt_event, iface);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct bacnet_server_msg msg = {
|
|
||||||
.type = SERVER_MSG_TYPE_IPV4_EVENT,
|
|
||||||
.parm_u32 = mgmt_event,
|
|
||||||
.parm_ptr = iface,
|
|
||||||
};
|
|
||||||
|
|
||||||
int ret = k_msgq_put(&bacnet_server_msgq, &msg, K_NO_WAIT);
|
|
||||||
if (ret != 0) {
|
|
||||||
printk("\n*** Handler[%d]: queue full, type %u event 0x%08x on iface %p dropped! ***\n",
|
|
||||||
counter, msg.type, msg.parm_u32, msg.parm_ptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief BACnet Server Thread
|
|
||||||
*/
|
|
||||||
static void server_thread(void)
|
|
||||||
{
|
|
||||||
LOG_INF("Server: started");
|
|
||||||
service_handlers_init();
|
|
||||||
|
|
||||||
bip_init("Server: from init");
|
|
||||||
BIP_Net = 1;
|
|
||||||
|
|
||||||
net_mgmt_init_event_callback(&mgmt_cb, ipv4_events_handler,
|
|
||||||
SERVER_IPV4_EVENTS_MASK);
|
|
||||||
net_mgmt_add_event_callback(&mgmt_cb);
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
const s32_t sleep_ms = K_FOREVER;
|
|
||||||
|
|
||||||
struct bacnet_server_msg msg = {
|
|
||||||
.type = SERVER_MSG_TYPE_INVALID,
|
|
||||||
};
|
|
||||||
int ret = k_msgq_get(&bacnet_server_msgq, &msg, sleep_ms);
|
|
||||||
|
|
||||||
/* Waiting period timed out */
|
|
||||||
if (-EAGAIN == ret) {
|
|
||||||
BACNET_ADDRESS src = {
|
|
||||||
0
|
|
||||||
}; /* address where message came from */
|
|
||||||
/* input */
|
|
||||||
/* returns 0 bytes on timeout */
|
|
||||||
uint16_t pdu_len = bip_receive(&src, &BIP_Rx_Buffer[0],
|
|
||||||
MAX_MPDU, 5);
|
|
||||||
|
|
||||||
/* process */
|
|
||||||
if (pdu_len) {
|
|
||||||
LOG_INF("Server: BIP received %u bytes.",
|
|
||||||
(unsigned)pdu_len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Message received */
|
|
||||||
else if (0 == ret) {
|
|
||||||
switch (msg.type) {
|
|
||||||
#if defined(CONFIG_NET_IPV4)
|
|
||||||
case SERVER_MSG_TYPE_IPV4_EVENT: {
|
|
||||||
LOG_INF("Server: MSG_TYPE_IPV4_EVENT u32: %08x ptr: %p",
|
|
||||||
msg.parm_u32, msg.parm_ptr);
|
|
||||||
const u32_t mgmt_event = msg.parm_u32;
|
|
||||||
//TODO: const struct net_if *iface = msg.parm_ptr;
|
|
||||||
|
|
||||||
/* Handle events */
|
|
||||||
if ((mgmt_event & SERVER_IPV4_EVENTS_MASK) !=
|
|
||||||
mgmt_event) {
|
|
||||||
LOG_INF("Server: thread ignoring event");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (NET_MGMT_GET_COMMAND(mgmt_event)) {
|
|
||||||
#if 0
|
|
||||||
case NET_EVENT_IPV4_CMD_ADDR_ADD:
|
|
||||||
LOG_INF("Server: IPv4 addr activated");
|
|
||||||
bip_init("Server: from CMD_ADDR_ADD");
|
|
||||||
BIP_Net = bip_valid() ? 1 : 0;
|
|
||||||
break;
|
|
||||||
case NET_EVENT_IPV4_CMD_ADDR_DEL:
|
|
||||||
LOG_INF("Server: IPv4 addr deactivated");
|
|
||||||
bip_cleanup();
|
|
||||||
BIP_Net = 0;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
LOG_INF("Server: Unsupported event %u",
|
|
||||||
mgmt_event);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
} break;
|
|
||||||
#endif /* defined(CONFIG_NET_IPV4) */
|
|
||||||
|
|
||||||
default:
|
|
||||||
LOG_WRN("Server: Dropping unsupported type %u",
|
|
||||||
msg.type);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returned without waiting and without message - why? */
|
|
||||||
else {
|
|
||||||
LOG_WRN("Server: Msgq returned w/o timeout or msg! req = %d",
|
|
||||||
ret);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int server_init(struct device *dev)
|
|
||||||
{
|
|
||||||
ARG_UNUSED(dev);
|
|
||||||
|
|
||||||
k_thread_create(&server_thread_data, server_thread_stack,
|
|
||||||
K_THREAD_STACK_SIZEOF(server_thread_stack),
|
|
||||||
(k_thread_entry_t)server_thread, NULL, NULL, NULL,
|
|
||||||
K_PRIO_PREEMPT(CONFIG_BACNETSTACK_BACNET_SERVER_PRIO), 0,
|
|
||||||
K_NO_WAIT);
|
|
||||||
k_thread_name_set(&server_thread_data, "BACserver");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
SYS_INIT(server_init, APPLICATION, CONFIG_BACNETSTACK_BACNET_SERVER_APP_PRIORITY);
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
# SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.13.1)
|
|
||||||
|
|
||||||
# Extract module path and names
|
|
||||||
string(REGEX REPLACE
|
|
||||||
"/zephyr/tests/[a-zA-Z_/-]*$" ""
|
|
||||||
BACNET_BASE
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR})
|
|
||||||
string(REGEX REPLACE
|
|
||||||
"/zephyr/tests/" "/src/"
|
|
||||||
BACNET_SRC_PATH
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR})
|
|
||||||
string(REGEX REPLACE
|
|
||||||
"/zephyr/tests/" "/test/"
|
|
||||||
BACNET_TEST_PATH
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR})
|
|
||||||
get_filename_component(BACNET_NAME ${BACNET_BASE} NAME)
|
|
||||||
|
|
||||||
|
|
||||||
if(BOARD STREQUAL unit_testing)
|
|
||||||
file(RELATIVE_PATH BACNET_INCLUDE $ENV{ZEPHYR_BASE} ${BACNET_BASE}/src)
|
|
||||||
list(APPEND INCLUDE ${BACNET_INCLUDE})
|
|
||||||
list(APPEND SOURCES
|
|
||||||
${BACNET_SRC_PATH}.c
|
|
||||||
${BACNET_TEST_PATH}/src/main.c
|
|
||||||
)
|
|
||||||
|
|
||||||
set(CONF_FILE "${CONF_FILE};prj.unit_testing.conf")
|
|
||||||
find_package(Zephyr COMPONENTS unittest REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
|
||||||
project(${BACNET_NAME})
|
|
||||||
else()
|
|
||||||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
|
||||||
project(${BACNET_NAME})
|
|
||||||
|
|
||||||
target_include_directories(app PRIVATE ${BACNET_BASE}/src)
|
|
||||||
target_sources(app PRIVATE
|
|
||||||
${BACNET_TEST_PATH}/src/main.c
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_compile_definitions(
|
|
||||||
CONFIG_ZTEST_NEW_API
|
|
||||||
BACNET_STACK_DEPRECATED_DISABLE
|
|
||||||
)
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
CONFIG_ZTEST=y
|
|
||||||
CONFIG_BACNETSTACK=y
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
CONFIG_ZTEST=y
|
|
||||||
#CONFIG_BACNETSTACK=y
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
tests:
|
|
||||||
bacnet.abort.unit:
|
|
||||||
tags: bacnet
|
|
||||||
type: unit
|
|
||||||
bacnet.abort:
|
|
||||||
tags: bacnet
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
# SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.13.1)
|
|
||||||
|
|
||||||
# Extract module path and names
|
|
||||||
string(REGEX REPLACE
|
|
||||||
"/zephyr/tests/[a-zA-Z_/-]*$" ""
|
|
||||||
BACNET_BASE
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR})
|
|
||||||
string(REGEX REPLACE
|
|
||||||
"/zephyr/tests/" "/src/"
|
|
||||||
BACNET_SRC_PATH
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR})
|
|
||||||
string(REGEX REPLACE
|
|
||||||
"/zephyr/tests/" "/test/"
|
|
||||||
BACNET_TEST_PATH
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR})
|
|
||||||
get_filename_component(BACNET_NAME ${BACNET_BASE} NAME)
|
|
||||||
|
|
||||||
# Update include path for this module
|
|
||||||
list(APPEND BACNET_INCLUDE ${BACNET_BASE}/src)
|
|
||||||
|
|
||||||
if(BOARD STREQUAL unit_testing)
|
|
||||||
file(RELATIVE_PATH BACNET_INCLUDE $ENV{ZEPHYR_BASE} ${BACNET_BASE}/src)
|
|
||||||
list(APPEND INCLUDE ${BACNET_INCLUDE})
|
|
||||||
list(APPEND SOURCES
|
|
||||||
${BACNET_SRC_PATH}.c
|
|
||||||
${BACNET_TEST_PATH}/src/main.c
|
|
||||||
)
|
|
||||||
|
|
||||||
get_filename_component(BACNET_SRC ${BACNET_SRC_PATH} PATH)
|
|
||||||
list(APPEND SOURCES
|
|
||||||
${BACNET_SRC}/bacdcode.c
|
|
||||||
${BACNET_SRC}/bacstr.c
|
|
||||||
${BACNET_SRC}/bacint.c
|
|
||||||
${BACNET_SRC}/bacreal.c
|
|
||||||
${BACNET_SRC}/datetime.c
|
|
||||||
${BACNET_SRC}/timestamp.c
|
|
||||||
${BACNET_SRC}/basic/sys/days.c
|
|
||||||
)
|
|
||||||
|
|
||||||
set(CONF_FILE "${CONF_FILE};prj.unit_testing.conf")
|
|
||||||
find_package(Zephyr COMPONENTS unittest REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
|
||||||
project(${BACNET_NAME})
|
|
||||||
else()
|
|
||||||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
|
||||||
project(${BACNET_NAME})
|
|
||||||
|
|
||||||
target_include_directories(app PRIVATE ${BACNET_INCLUDE})
|
|
||||||
target_sources(app PRIVATE
|
|
||||||
${BACNET_TEST_PATH}/src/main.c
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_compile_definitions(
|
|
||||||
CONFIG_ZTEST_NEW_API
|
|
||||||
BACNET_STACK_DEPRECATED_DISABLE
|
|
||||||
)
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
CONFIG_ZTEST=y
|
|
||||||
CONFIG_BACNETSTACK=y
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
CONFIG_ZTEST=y
|
|
||||||
#CONFIG_BACNETSTACK=y
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
tests:
|
|
||||||
bacnet.alarm_ack.unit:
|
|
||||||
tags: bacnet
|
|
||||||
type: unit
|
|
||||||
bacnet.alarm_ack:
|
|
||||||
tags: bacnet
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
# SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.13.1)
|
|
||||||
|
|
||||||
# Extract module path and names
|
|
||||||
string(REGEX REPLACE
|
|
||||||
"/zephyr/tests/[a-zA-Z_/-]*$" ""
|
|
||||||
BACNET_BASE
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR})
|
|
||||||
string(REGEX REPLACE
|
|
||||||
"/zephyr/tests/" "/src/"
|
|
||||||
BACNET_SRC_PATH
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR})
|
|
||||||
string(REGEX REPLACE
|
|
||||||
"/zephyr/tests/" "/test/"
|
|
||||||
BACNET_TEST_PATH
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR})
|
|
||||||
get_filename_component(BACNET_NAME ${BACNET_BASE} NAME)
|
|
||||||
|
|
||||||
# Update include path for this module
|
|
||||||
list(APPEND BACNET_INCLUDE ${BACNET_BASE}/src)
|
|
||||||
|
|
||||||
if(BOARD STREQUAL unit_testing)
|
|
||||||
file(RELATIVE_PATH BACNET_INCLUDE $ENV{ZEPHYR_BASE} ${BACNET_BASE}/src)
|
|
||||||
list(APPEND INCLUDE ${BACNET_INCLUDE})
|
|
||||||
list(APPEND SOURCES
|
|
||||||
${BACNET_SRC_PATH}.c
|
|
||||||
${BACNET_TEST_PATH}/src/main.c
|
|
||||||
)
|
|
||||||
|
|
||||||
get_filename_component(BACNET_SRC ${BACNET_SRC_PATH} PATH)
|
|
||||||
list(APPEND SOURCES
|
|
||||||
${BACNET_SRC}/bacdcode.c
|
|
||||||
${BACNET_SRC}/bacstr.c
|
|
||||||
${BACNET_SRC}/bacint.c
|
|
||||||
${BACNET_SRC}/bacreal.c
|
|
||||||
${BACNET_SRC}/datetime.c
|
|
||||||
${BACNET_SRC}/timestamp.c
|
|
||||||
${BACNET_SRC}/basic/sys/days.c
|
|
||||||
)
|
|
||||||
|
|
||||||
set(CONF_FILE "${CONF_FILE};prj.unit_testing.conf")
|
|
||||||
find_package(Zephyr COMPONENTS unittest REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
|
||||||
project(${BACNET_NAME})
|
|
||||||
else()
|
|
||||||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
|
||||||
project(${BACNET_NAME})
|
|
||||||
|
|
||||||
target_include_directories(app PRIVATE ${BACNET_INCLUDE})
|
|
||||||
target_sources(app PRIVATE
|
|
||||||
${BACNET_TEST_PATH}/src/main.c
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_compile_definitions(
|
|
||||||
CONFIG_ZTEST_NEW_API
|
|
||||||
BACNET_STACK_DEPRECATED_DISABLE
|
|
||||||
)
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
CONFIG_ZTEST=y
|
|
||||||
CONFIG_BACNETSTACK=y
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user