improve router-mstp app usage (#470)
* improve router-mstp app usage * add router-mstp app environment shell script --------- Co-authored-by: Steve Karg <skarg@users.sourceforge.net>
This commit is contained in:
+56
-22
@@ -35,6 +35,7 @@
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/config.h"
|
||||
@@ -102,6 +103,29 @@ static uint8_t MSTP_Rx_Buffer[DLMSTP_MPDU_MAX];
|
||||
static uint8_t Tx_Buffer[MAX(DLMSTP_MPDU_MAX, BIP_MPDU_MAX)];
|
||||
/* main loop exit control */
|
||||
static bool Exit_Requested;
|
||||
/* debugging info */
|
||||
static bool Debug_Enabled;
|
||||
|
||||
/**
|
||||
* @brief print debug info if debug is enabled
|
||||
* @param format - printf format string
|
||||
* @param ... variable arguments
|
||||
* @return number of bytes printed
|
||||
*/
|
||||
static int log_printf(const char *format, ...)
|
||||
{
|
||||
int length = 0;
|
||||
va_list ap;
|
||||
|
||||
if (Debug_Enabled) {
|
||||
va_start(ap, format);
|
||||
length = vfprintf(stdout, format, ap);
|
||||
va_end(ap);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search the router table to find a matching DNET entry
|
||||
@@ -289,7 +313,7 @@ static void dnet_cleanup(DNET *dnets)
|
||||
{
|
||||
DNET *dnet = dnets;
|
||||
while (dnet != NULL) {
|
||||
debug_printf("DNET %u removed\n", (unsigned)dnet->net);
|
||||
log_printf("DNET %u removed\n", (unsigned)dnet->net);
|
||||
dnet = dnet->next;
|
||||
free(dnets);
|
||||
dnets = dnet;
|
||||
@@ -313,7 +337,7 @@ static void datalink_get_broadcast_address(BACNET_ADDRESS *dest)
|
||||
}
|
||||
|
||||
/**
|
||||
* function to send a packet out the BACnet/IP and BACnet/IPv6 ports
|
||||
* function to send a packet out the BACnet/IP and BACnet MSTP ports
|
||||
*
|
||||
* @param snet - network number of the directly connected port to send
|
||||
* @param dest - address to where packet is sent
|
||||
@@ -332,14 +356,14 @@ static int datalink_send_pdu(uint16_t snet,
|
||||
int bytes_sent = 0;
|
||||
|
||||
if (snet == 0) {
|
||||
debug_printf("BVLC & MS/TP Send to DNET %u\n", (unsigned)dest->net);
|
||||
log_printf("BVLC & MS/TP Send to DNET %u\n", (unsigned)dest->net);
|
||||
bytes_sent = bip_send_pdu(dest, npdu_data, pdu, pdu_len);
|
||||
bytes_sent = dlmstp_send_pdu(dest, npdu_data, pdu, pdu_len);
|
||||
} else if (snet == BIP_Net) {
|
||||
debug_printf("BVLC Send to DNET %u\n", (unsigned)dest->net);
|
||||
log_printf("BVLC Send to DNET %u\n", (unsigned)dest->net);
|
||||
bytes_sent = bip_send_pdu(dest, npdu_data, pdu, pdu_len);
|
||||
} else if (snet == MSTP_Net) {
|
||||
debug_printf("MS/TP Send to DNET %u\n", (unsigned)dest->net);
|
||||
log_printf("MS/TP Send to DNET %u\n", (unsigned)dest->net);
|
||||
bytes_sent = dlmstp_send_pdu(dest, npdu_data, pdu, pdu_len);
|
||||
}
|
||||
|
||||
@@ -376,7 +400,7 @@ static void send_i_am_router_to_network(uint16_t snet, uint16_t net)
|
||||
len = encode_unsigned16(&Tx_Buffer[pdu_len], net);
|
||||
pdu_len += len;
|
||||
} else {
|
||||
debug_printf("I-Am-Router-To-Network ");
|
||||
log_printf("I-Am-Router-To-Network ");
|
||||
/* Each router shall broadcast out each port
|
||||
an I-Am-Router-To-Network message containing the network
|
||||
numbers of each accessible network except the networks
|
||||
@@ -387,12 +411,12 @@ static void send_i_am_router_to_network(uint16_t snet, uint16_t net)
|
||||
port = Router_Table_Head;
|
||||
while (port != NULL) {
|
||||
if (port->net != snet) {
|
||||
debug_printf("%u,", port->net);
|
||||
log_printf("%u,", port->net);
|
||||
len = encode_unsigned16(&Tx_Buffer[pdu_len], port->net);
|
||||
pdu_len += len;
|
||||
dnet = port->dnets;
|
||||
while (dnet != NULL) {
|
||||
debug_printf("%u,", dnet->net);
|
||||
log_printf("%u,", dnet->net);
|
||||
len = encode_unsigned16(&Tx_Buffer[pdu_len], dnet->net);
|
||||
pdu_len += len;
|
||||
dnet = dnet->next;
|
||||
@@ -400,7 +424,7 @@ static void send_i_am_router_to_network(uint16_t snet, uint16_t net)
|
||||
}
|
||||
port = port->next;
|
||||
}
|
||||
debug_printf("from %u\n", snet);
|
||||
log_printf("from %u\n", snet);
|
||||
}
|
||||
datalink_send_pdu(snet, &dest, &npdu_data, &Tx_Buffer[0], pdu_len);
|
||||
}
|
||||
@@ -600,6 +624,8 @@ static void who_is_router_to_network_handler(uint16_t snet,
|
||||
uint16_t network = 0;
|
||||
uint16_t len = 0;
|
||||
|
||||
(void)src;
|
||||
(void)npdu_data;
|
||||
if (npdu) {
|
||||
if (npdu_len >= 2) {
|
||||
len += decode_unsigned16(&npdu[len], &network);
|
||||
@@ -652,6 +678,8 @@ static void network_control_handler(uint16_t snet,
|
||||
uint16_t len = 0;
|
||||
const char *msg_name = NULL;
|
||||
|
||||
(void)src;
|
||||
(void)npdu_data;
|
||||
msg_name = bactext_network_layer_msg_name(npdu_data->network_message_type);
|
||||
fprintf(stderr, "Received %s\n", msg_name);
|
||||
switch (npdu_data->network_message_type) {
|
||||
@@ -852,7 +880,7 @@ static void routed_apdu_handler(uint16_t snet,
|
||||
npdu_encode_pdu(&Tx_Buffer[0], &local_dest, &router_src, npdu);
|
||||
memmove(&Tx_Buffer[npdu_len], apdu, apdu_len);
|
||||
/* send to my other ports */
|
||||
debug_printf("Routing a BROADCAST from %u\n", (unsigned)snet);
|
||||
log_printf("Routing a BROADCAST from %u\n", (unsigned)snet);
|
||||
port = Router_Table_Head;
|
||||
while (port != NULL) {
|
||||
if (port->net != snet) {
|
||||
@@ -866,7 +894,7 @@ static void routed_apdu_handler(uint16_t snet,
|
||||
port = dnet_find(dest->net, &remote_dest);
|
||||
if (port) {
|
||||
if (port->net == dest->net) {
|
||||
debug_printf("Routing to Port %u\n", (unsigned)dest->net);
|
||||
log_printf("Routing to Port %u\n", (unsigned)dest->net);
|
||||
/* Case 1: the router is directly
|
||||
connected to the network referred to by DNET. */
|
||||
/* In the first case, DNET, DADR, and Hop
|
||||
@@ -885,7 +913,7 @@ static void routed_apdu_handler(uint16_t snet,
|
||||
datalink_send_pdu(port->net, &local_dest, npdu, &Tx_Buffer[0],
|
||||
npdu_len + apdu_len);
|
||||
} else {
|
||||
debug_printf(
|
||||
log_printf(
|
||||
"Routing to another Router %u\n", (unsigned)remote_dest.net);
|
||||
/* Case 2: the message must be
|
||||
relayed to another router for further transmission */
|
||||
@@ -903,7 +931,7 @@ static void routed_apdu_handler(uint16_t snet,
|
||||
npdu_len + apdu_len);
|
||||
}
|
||||
} else if (dest->net) {
|
||||
debug_printf("Routing to Unknown Route %u\n", (unsigned)dest->net);
|
||||
log_printf("Routing to Unknown Route %u\n", (unsigned)dest->net);
|
||||
/* Case 3: a global broadcast is required. */
|
||||
dest->mac_len = 0;
|
||||
npdu->hop_count--;
|
||||
@@ -915,7 +943,7 @@ static void routed_apdu_handler(uint16_t snet,
|
||||
port = Router_Table_Head;
|
||||
while (port != NULL) {
|
||||
if (port->net != snet) {
|
||||
datalink_send_pdu(port->net, dest, npdu, &Tx_Buffer[0],
|
||||
datalink_send_pdu(port->net, dest, npdu, &Tx_Buffer[0],
|
||||
npdu_len + apdu_len);
|
||||
}
|
||||
port = port->next;
|
||||
@@ -998,15 +1026,22 @@ static void my_routing_npdu_handler(
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the BACnet/IPv6 and BACnet/IP data links
|
||||
* Initialize the BACnet MSTP and BACnet/IP data links
|
||||
*/
|
||||
static void datalink_init(void)
|
||||
{
|
||||
char *pEnv = NULL;
|
||||
BACNET_ADDRESS my_address = { 0 };
|
||||
|
||||
pEnv = getenv("BACNET_ROUTER_DEBUG");
|
||||
if (pEnv) {
|
||||
bip_debug_enable();
|
||||
Debug_Enabled = true;
|
||||
log_printf("Debug=enabled\n");
|
||||
} else {
|
||||
fprintf(stderr, "Debug=disabled\n");
|
||||
}
|
||||
/* BACnet/IP Initialization */
|
||||
bip_debug_enable();
|
||||
pEnv = getenv("BACNET_IP_PORT");
|
||||
if (pEnv) {
|
||||
bip_set_port((uint16_t)strtol(pEnv, NULL, 0));
|
||||
@@ -1138,7 +1173,6 @@ static void control_c_hooks(void)
|
||||
|
||||
|
||||
#ifndef FUZZING
|
||||
|
||||
/**
|
||||
* Main function of simple router demo.
|
||||
*
|
||||
@@ -1154,6 +1188,8 @@ int main(int argc, char *argv[])
|
||||
time_t current_seconds = 0;
|
||||
uint32_t elapsed_seconds = 0;
|
||||
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
printf("BACnet Simple MS/TP to IP Router Demo\n");
|
||||
printf("BACnet Stack Version %s\n", BACnet_Version);
|
||||
datalink_init();
|
||||
@@ -1175,7 +1211,7 @@ int main(int argc, char *argv[])
|
||||
bip_receive(&src, &BIP_Rx_Buffer[0], sizeof(BIP_Rx_Buffer), 5);
|
||||
/* process */
|
||||
if (pdu_len) {
|
||||
debug_printf("BACnet/IP Received packet\n");
|
||||
log_printf("BACnet/IP Received packet\n");
|
||||
my_routing_npdu_handler(BIP_Net, &src, &BIP_Rx_Buffer[0], pdu_len);
|
||||
}
|
||||
/* returns 0 bytes on timeout */
|
||||
@@ -1183,7 +1219,7 @@ int main(int argc, char *argv[])
|
||||
dlmstp_receive(&src, &MSTP_Rx_Buffer[0], sizeof(MSTP_Rx_Buffer), 5);
|
||||
/* process */
|
||||
if (pdu_len) {
|
||||
debug_printf("BACnet MS/TP Received packet\n");
|
||||
log_printf("BACnet MS/TP Received packet\n");
|
||||
my_routing_npdu_handler(
|
||||
MSTP_Net, &src, &MSTP_Rx_Buffer[0], pdu_len);
|
||||
}
|
||||
@@ -1202,6 +1238,4 @@ int main(int argc, char *argv[])
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif // FUZZING
|
||||
#endif
|
||||
|
||||
@@ -2,8 +2,9 @@ BACnet Simple Router Demo
|
||||
=========================
|
||||
|
||||
The Simple Router demo connects one BACnet/IP and one BACnet MS/TP network.
|
||||
It also includes a BBMD so that Foreign Device Registration can be used
|
||||
to tunnel local command line demos to BACnet/IP and BACnet MS/TP networks.
|
||||
The router demo also includes a BBMD so that Foreign Device Registration can
|
||||
be used to tunnel local command line demos to BACnet/IP and BACnet MS/TP
|
||||
networks.
|
||||
|
||||
Configuration
|
||||
=============
|
||||
@@ -31,4 +32,20 @@ set BACNET_IP_PORT=47808
|
||||
set BACNET_IP_NET=1
|
||||
set BACNET_MSTP_NET=2
|
||||
|
||||
Note: NET number must be unique and 1..65534 (never 0 or 65535)
|
||||
Note: NET number must be unique and 1..65534 (never 0 or 65535)
|
||||
|
||||
Example Usage
|
||||
=============
|
||||
Build the demo applications for BACnet/IP:
|
||||
$ make
|
||||
Build the simple router demo:
|
||||
$ make router-mstp
|
||||
Configure the router demo:
|
||||
$ ./bin/router-mstp.sh enp0s3 /dev/ttyUSB0
|
||||
Run the router demo:
|
||||
$ ./bin/router-mstp
|
||||
|
||||
In another terminal, configure client apps for Foreign Device Registration:
|
||||
$ ./bin/bvlc.sh 192.168.0.1
|
||||
$ ./bin/bacwi -1
|
||||
$ ./bin/bacepics 123
|
||||
|
||||
Executable
BIN
Binary file not shown.
Executable
+53
@@ -0,0 +1,53 @@
|
||||
#!/bin/bash
|
||||
echo Setting parameters for BACnet/IP to MSTP Router
|
||||
|
||||
# BACnet/IP configuration
|
||||
BACNET_IFACE=${1}
|
||||
export BACNET_IFACE
|
||||
echo "BACNET_IFACE=$BACNET_IFACE"
|
||||
|
||||
BACNET_IP_PORT=47808
|
||||
export BACNET_IP_PORT
|
||||
echo "BACNET_IP_PORT=$BACNET_IP_PORT"
|
||||
|
||||
# BBMD port for local apps
|
||||
BACNET_BBMD_PORT=47809
|
||||
export BACNET_BBMD_PORT
|
||||
echo "BACNET_BBMD_PORT=$BACNET_BBMD_PORT"
|
||||
|
||||
# BACnet MSTP settings
|
||||
BACNET_MSTP_IFACE=${2}
|
||||
export BACNET_MSTP_IFACE
|
||||
echo "BACNET_MSTP_IFACE=$BACNET_MSTP_IFACE"
|
||||
|
||||
BACNET_MSTP_BAUD=38400
|
||||
export BACNET_MSTP_BAUD
|
||||
echo "BACNET_MSTP_BAUD=$BACNET_MSTP_BAUD"
|
||||
|
||||
BACNET_MSTP_MAC=1
|
||||
export BACNET_MSTP_MAC
|
||||
echo "BACNET_MSTP_MAC=$BACNET_MSTP_MAC"
|
||||
|
||||
BACNET_MAX_INFO_FRAMES=128
|
||||
export BACNET_MAX_INFO_FRAMES
|
||||
echo "BACNET_MAX_INFO_FRAMES=$BACNET_MAX_INFO_FRAMES"
|
||||
|
||||
BACNET_MAX_MASTER=127
|
||||
export BACNET_MAX_MASTER
|
||||
echo "BACNET_MAX_MASTER=$BACNET_MAX_MASTER"
|
||||
|
||||
# Network Numbers
|
||||
BACNET_IP_NET=1
|
||||
export BACNET_IP_NET
|
||||
echo "BACNET_IP_NET=$BACNET_IP_NET"
|
||||
|
||||
BACNET_MSTP_NET=2
|
||||
export BACNET_MSTP_NET
|
||||
echo "BACNET_MSTP_NET=$BACNET_MSTP_NET"
|
||||
|
||||
BACNET_ROUTER_DEBUG=1
|
||||
export BACNET_ROUTER_DEBUG
|
||||
echo "BACNET_ROUTER_DEBUG=$BACNET_ROUTER_DEBUG"
|
||||
|
||||
echo Launching new shell using the BACnet Router environment...
|
||||
/bin/bash
|
||||
Reference in New Issue
Block a user