Zephyr core bacnet server port; bacnet/device test (#123)

Co-authored-by: Gregory Shue <gregory.shue@legrand.us>
This commit is contained in:
Greg Shue
2020-09-22 07:24:38 -07:00
committed by GitHub
parent cbaa106c59
commit a95b7d597e
26 changed files with 4166 additions and 86 deletions
@@ -0,0 +1,8 @@
# SPDX-License-Identifier: MIT
cmake_minimum_required(VERSION 3.13.1)
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
project(b-ss)
target_sources(app PRIVATE src/main.c)
+23
View File
@@ -0,0 +1,23 @@
.. _b-ss_sample:
BACnet Profile B-SS Sample
##########################
Overview
********
This is a simple application demonstrating configuration of a
BACnet B-SS 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.
+83
View File
@@ -0,0 +1,83 @@
CONFIG_BACNETSTACK=y
# BIP Options
CONFIG_BACDL_BIP=y
CONFIG_BACDL_BIP_PORT=47808
CONFIG_BACDL_BIP_ADDRESS_INDEX=0
# BIP6 Options
#CONFIG_BACDL_BIP6=y
CONFIG_BACDL_BIP6_PORT=47808
CONFIG_BACDL_BIP6_ADDRESS_INDEX=1
CONFIG_NET_IPV6_MLD=y
CONFIG_NET_IPV4=n
CONFIG_NET_ARP=n
CONFIG_BACDL_BIP6_ADDRESS_INDEX=0
CONFIG_BACDL_BIP6_MCAST_ADDRESS="FE80::0020" # YABE unicast workaround
CONFIG_NEWLIB_LIBC=y
# pthreads
CONFIG_POSIX_API=y
CONFIG_PTHREAD_IPC=y
CONFIG_POSIX_MQUEUE=y
# networking
CONFIG_NETWORKING=y
CONFIG_NET_IPV4=y
CONFIG_NET_IPV6=y
CONFIG_NET_ARP=y
CONFIG_NET_TCP=y
CONFIG_NET_UDP=y
#CONFIG_NET_DHCPV4=y
CONFIG_NET_MGMT=y
CONFIG_NET_MGMT_EVENT=y
CONFIG_NET_SOCKETS=y
CONFIG_NET_CONFIG_SETTINGS=y
CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.168.10.80"
CONFIG_NET_CONFIG_MY_IPV4_NETMASK="255.255.255.0"
CONFIG_NET_CONFIG_MY_IPV4_GW="192.168.10.1"
CONFIG_NET_CONFIG_PEER_IPV4_ADDR="192.168.10.1"
CONFIG_NET_LLDP=y
CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=4
CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT=4
CONFIG_NET_CONFIG_MY_IPV6_ADDR="FE80::0010"
# Promiscuous mode on layer 2 is required to receive IPv6 multicasts.
# Ethernet hardware will not respond to MAC 33:33:x:x:x:x without this:
CONFIG_ETH_MCUX_PROMISCUOUS_MODE=y
#CONFIG_LOG_STRDUP_BUF_COUNT=4
#CONFIG_LOG_STRDUP_MAX_STRING=96
CONFIG_DNS_RESOLVER=y
CONFIG_SLIP_STATISTICS=n
CONFIG_NET_SHELL=y
CONFIG_NET_TX_STACK_SIZE=8192
CONFIG_NET_RX_STACK_SIZE=8192
CONFIG_NET_IF_UNICAST_IPV4_ADDR_COUNT=4
# logging
#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_LOG=y
CONFIG_BACNETSTACK_LOG_LEVEL_DBG=y
# system
CONFIG_ISR_STACK_SIZE=8192
CONFIG_MAIN_STACK_SIZE=8192
CONFIG_IDLE_STACK_SIZE=2048
CONFIG_TEST_RANDOM_GENERATOR=y
CONFIG_INIT_STACKS=y
CONFIG_MINIMAL_LIBC_MALLOC_ARENA_SIZE=131072
+7
View File
@@ -0,0 +1,7 @@
sample:
name: BACnet Profile B-SS Sample
tests:
sample.profile.b-ss:
tags: bacnet
platform_whitelist: qemu_x86 native_posix native_posix_64
+157
View File
@@ -0,0 +1,157 @@
/*
* Copyright (C) 2020 Legrand North America, Inc.
*
* SPDX-License-Identifier: MIT
*/
#include <kernel.h>
#include <stdint.h>
#include "bacnet/config.h"
#include "bacnet/bacdef.h"
#include "bacnet/bacdcode.h"
#include "bacnet/apdu.h"
#include "bacnet/dcc.h"
#include "bacnet/iam.h"
#include "bacnet/npdu.h"
#include "bacnet/getevent.h"
#include "bacnet/version.h"
#include "bacnet/basic/services.h"
#include "bacnet/datalink/dlenv.h"
#include "bacnet/basic/sys/filename.h"
#include "bacnet/basic/tsm/tsm.h"
#include "bacnet/basic/tsm/tsm.h"
#include "bacnet/datalink/datalink.h"
#include "bacnet/basic/binding/address.h"
/* include the device object */
#include "bacnet/basic/object/device.h"
#include "bacnet/basic/object/lc.h"
#include "bacnet/basic/object/trendlog.h"
#if defined(INTRINSIC_REPORTING)
#include "bacnet/basic/object/nc.h"
#endif /* defined(INTRINSIC_REPORTING) */
/* Logging module registration is already done in ports/zephyr/main.c */
#include <logging/log.h>
LOG_MODULE_DECLARE(bacnet, CONFIG_BACNETSTACK_LOG_LEVEL);
/** Buffer used for receiving */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
/** 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);
}
void main(void)
{
LOG_INF("\n*** BACnet Profile B-SS Sample ***\n");
LOG_INF("BACnet Stack Version " BACNET_VERSION_TEXT);
LOG_INF("BACnet Device ID: %u", Device_Object_Instance_Number());
LOG_INF("BACnet Device Max APDU: %d", MAX_APDU);
service_handlers_init();
datalink_init(NULL);
/* configure the timeout values */
s64_t last_ms = k_uptime_get();
/* broadcast an I-Am on startup */
Send_I_Am(&Handler_Transmit_Buffer[0]);
s64_t address_binding_tmr = 0;
#if defined(INTRINSIC_REPORTING)
s64_t recipient_scan_tmr = 0;
#endif
#if defined(BACNET_TIME_MASTER)
BACNET_DATE_TIME bdatetime = { 0 };
#endif
for (;;) {
k_sleep(K_MSEC(1)); /* Allows debug prints */
BACNET_ADDRESS src = { 0 }; /* address where message came from */
const unsigned timeout_ms = 1;
s64_t current_ms = k_uptime_get();
/* returns 0 bytes on timeout */
uint16_t const pdu_len = datalink_receive(&src, &Rx_Buf[0],
MAX_MPDU, timeout_ms);
/* process */
if (pdu_len > 0) {
npdu_handler(&src, &Rx_Buf[0], pdu_len);
}
if (current_ms - last_ms > 1000) {
const uint32_t elapsed_milliseconds =
(uint32_t)(current_ms - last_ms);
//TODO: const uint32_t elapsed_seconds = elapsed_milliseconds / 1000UL;
last_ms = current_ms;
//TODO: dcc_timer_seconds(elapsed_seconds);
//TODO: datalink_maintenance_timer(elapsed_seconds);
//TODO: dlenv_maintenance_timer(elapsed_seconds);
//TODO: Load_Control_State_Machine_handler():
//TODO: handler_cov_timer_seconds(elapsed_seconds);
//TODO: tsm_timer_milliseconds(elapsed_milliseconds);
//TODO: trend_log_timer(elapsed_seconds);
#if defined(INTRINSIC_REPORTING)
//TODO: Device_local_reporting();
#endif
#if defined(BACNET_TIME_MASTER)
//TODO: Device_getCurrentDateTime(&bdatetime);
//TODO: handler_Timesync_task(&bdatetime);
#endif
address_binding_tmr += elapsed_milliseconds;
#if defined(INTRINSIC_REPORTING)
recipient_scan_tmr += elapsed_milliseconds;
#endif
}
//TODO: handler_cov_task();
/* scan cache address */
if (address_binding_tmr >= 60 * 1000) {
//TODO: address_cache_timer(address_binding_tmr / 1000);
address_binding_tmr = 0;
}
#if defined(INTRINSIC_REPORTING)
/* try to find addresses of recipients */
if (recipient_scan_tmr >= NC_RESCAN_RECIPIENTS_SECS * 1000) {
//TODO: Notification_Class_find_recipient();
recipient_scan_tmr = 0;
}
#endif
/* output */
/* blink LEDs, Turn on or off outputs, etc */
}
}