Indented with standard indent rules.

This commit is contained in:
skarg
2008-08-23 12:38:26 +00:00
parent 36c5c765b4
commit 0ffbb64c13
26 changed files with 1139 additions and 1155 deletions
+1 -2
View File
@@ -273,8 +273,7 @@ int main(int argc, char *argv[]) {
Init_DataLink();
/* configure the timeout values */
last_seconds = time(NULL);
timeout_seconds =
(apdu_timeout() / 1000) * apdu_retries();
timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
/* try to bind with the device */
Send_WhoIs(Target_Device_Object_Instance, Target_Device_Object_Instance);
/* loop forever */
+1 -2
View File
@@ -431,8 +431,7 @@ int main(int argc, char *argv[]) {
Init_DataLink();
/* configure the timeout values */
last_seconds = time(NULL);
timeout_seconds =
(apdu_timeout() / 1000) * apdu_retries();
timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
/* try to bind with the device */
found =
address_bind_request(Target_Device_Object_Instance, &max_apdu,
+219 -219
View File
@@ -1,219 +1,219 @@
/**************************************************************************
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <errno.h>
#include <string.h>
#include "config.h"
#include "config.h"
#include "txbuf.h"
#include "bacdef.h"
#include "bacdcode.h"
#include "address.h"
#include "tsm.h"
#include "npdu.h"
#include "apdu.h"
#include "device.h"
#include "datalink.h"
/* some demo stuff needed */
#include "handlers.h"
#include "txbuf.h"
static void npdu_encode_npdu_network(
BACNET_NPDU_DATA * npdu_data,
BACNET_NETWORK_MESSAGE_TYPE network_message_type,
BACNET_MESSAGE_PRIORITY priority)
{
if (npdu_data) {
npdu_data->data_expecting_reply = false;
npdu_data->protocol_version = BACNET_PROTOCOL_VERSION;
npdu_data->network_layer_message = true; /* false if APDU */
npdu_data->network_message_type = network_message_type; /* optional */
npdu_data->vendor_id = 0; /* optional, if net message type is > 0x80 */
npdu_data->priority = priority;
npdu_data->hop_count = 255;
}
}
/* find a specific router, or use -1 for limit if you want unlimited */
void Send_Who_Is_Router_To_Network(
BACNET_ADDRESS *dst,
int dnet)
{
int len = 0;
int pdu_len = 0;
int bytes_sent = 0;
BACNET_NPDU_DATA npdu_data;
npdu_encode_npdu_network(&npdu_data,
NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK,
MESSAGE_PRIORITY_NORMAL);
/* fixme: should dnet/dlen/dadr be set in NPDU? */
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], NULL, NULL, &npdu_data);
/* encode the optional DNET portion of the packet */
if (dnet >= 0) {
len = encode_unsigned16(&Handler_Transmit_Buffer[pdu_len], dnet);
pdu_len += len;
#if PRINT_ENABLED
fprintf(stderr, "Send Who-Is-Router-To-Network message to %u\n",dnet);
#endif
} else {
#if PRINT_ENABLED
fprintf(stderr, "Send Who-Is-Router-To-Network message\n");
#endif
}
bytes_sent =
datalink_send_pdu(dst, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
#if PRINT_ENABLED
if (bytes_sent <= 0)
fprintf(stderr, "Failed to Send Who-Is-Router-To-Network Request (%s)!\n",
strerror(errno));
#endif
}
/* pDNET_list: list of networks for which I am a router,
terminated with -1 */
void Send_I_Am_Router_To_Network(
const int DNET_list[])
{
int len = 0;
int pdu_len = 0;
BACNET_ADDRESS dest;
int bytes_sent = 0;
BACNET_NPDU_DATA npdu_data;
uint16_t dnet = 0;
unsigned index = 0;
npdu_encode_npdu_network(&npdu_data,
NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK,
MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], NULL, NULL, &npdu_data);
/* encode the optional DNET list portion of the packet */
#if PRINT_ENABLED
fprintf(stderr, "Send I-Am-Router-To-Network message to:\n");
#endif
while (DNET_list[index] != -1) {
dnet = DNET_list[index];
len = encode_unsigned16(&Handler_Transmit_Buffer[pdu_len], dnet);
pdu_len += len;
index++;
#if PRINT_ENABLED
fprintf(stderr, "%u\n",dnet);
#endif
}
/* I-Am-Router-To-Network shall always be transmitted with
a broadcast MAC address. */
datalink_get_broadcast_address(&dest);
bytes_sent =
datalink_send_pdu(&dest, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
#if PRINT_ENABLED
if (bytes_sent <= 0)
fprintf(stderr, "Failed to send I-Am-Router-To-Network message (%s)!\n",
strerror(errno));
#endif
}
/* */
void Send_Initialize_Routing_Table(
BACNET_ADDRESS *dst,
BACNET_ROUTER_PORT *router_port_list)
{
int len = 0;
int pdu_len = 0;
int bytes_sent = 0;
BACNET_NPDU_DATA npdu_data;
uint8_t number_of_ports = 0;
BACNET_ROUTER_PORT *router_port;
unsigned i = 0; /* counter */
npdu_encode_npdu_network(&npdu_data,
NETWORK_MESSAGE_INIT_RT_TABLE,
MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], NULL, NULL, &npdu_data);
/* encode the optional port_info list portion of the packet */
router_port = router_port_list;
while (router_port) {
number_of_ports++;
router_port = router_port->next;
}
Handler_Transmit_Buffer[pdu_len++] = number_of_ports;
if (number_of_ports) {
router_port = router_port_list;
while (router_port) {
len = encode_unsigned16(
&Handler_Transmit_Buffer[pdu_len],
router_port->dnet);
pdu_len += len;
Handler_Transmit_Buffer[pdu_len++] = router_port->id;
Handler_Transmit_Buffer[pdu_len++] = router_port->info_len;
for (i = 0; i < router_port->info_len; i++) {
Handler_Transmit_Buffer[pdu_len++] = router_port->info[i];
}
router_port = router_port->next;
}
}
#if PRINT_ENABLED
fprintf(stderr, "Send Initialize-Routing-Table message\n");
#endif
bytes_sent =
datalink_send_pdu(dst, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
#if PRINT_ENABLED
if (bytes_sent <= 0)
fprintf(stderr, "Failed to send Initialize-Routing-Table message (%s)!\n",
strerror(errno));
#endif
}
/* */
void Send_Initialize_Routing_Table_Ack(
BACNET_ROUTER_PORT *router_port_list)
{
int pdu_len = 0;
BACNET_ADDRESS dest;
int bytes_sent = 0;
BACNET_NPDU_DATA npdu_data;
npdu_encode_npdu_network(&npdu_data,
NETWORK_MESSAGE_INIT_RT_TABLE_ACK,
MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], NULL, NULL, &npdu_data);
/* encode the optional DNET list portion of the packet */
datalink_get_broadcast_address(&dest);
bytes_sent =
datalink_send_pdu(&dest, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
#if PRINT_ENABLED
if (bytes_sent <= 0)
fprintf(stderr, "Failed to Send Initialize-Routing-Table-Ack message (%s)!\n",
strerror(errno));
#endif
}
/**************************************************************************
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <errno.h>
#include <string.h>
#include "config.h"
#include "config.h"
#include "txbuf.h"
#include "bacdef.h"
#include "bacdcode.h"
#include "address.h"
#include "tsm.h"
#include "npdu.h"
#include "apdu.h"
#include "device.h"
#include "datalink.h"
/* some demo stuff needed */
#include "handlers.h"
#include "txbuf.h"
static void npdu_encode_npdu_network(
BACNET_NPDU_DATA * npdu_data,
BACNET_NETWORK_MESSAGE_TYPE network_message_type,
BACNET_MESSAGE_PRIORITY priority)
{
if (npdu_data) {
npdu_data->data_expecting_reply = false;
npdu_data->protocol_version = BACNET_PROTOCOL_VERSION;
npdu_data->network_layer_message = true; /* false if APDU */
npdu_data->network_message_type = network_message_type; /* optional */
npdu_data->vendor_id = 0; /* optional, if net message type is > 0x80 */
npdu_data->priority = priority;
npdu_data->hop_count = 255;
}
}
/* find a specific router, or use -1 for limit if you want unlimited */
void Send_Who_Is_Router_To_Network(
BACNET_ADDRESS * dst,
int dnet)
{
int len = 0;
int pdu_len = 0;
int bytes_sent = 0;
BACNET_NPDU_DATA npdu_data;
npdu_encode_npdu_network(&npdu_data,
NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK, MESSAGE_PRIORITY_NORMAL);
/* fixme: should dnet/dlen/dadr be set in NPDU? */
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], NULL, NULL, &npdu_data);
/* encode the optional DNET portion of the packet */
if (dnet >= 0) {
len = encode_unsigned16(&Handler_Transmit_Buffer[pdu_len], dnet);
pdu_len += len;
#if PRINT_ENABLED
fprintf(stderr, "Send Who-Is-Router-To-Network message to %u\n", dnet);
#endif
} else {
#if PRINT_ENABLED
fprintf(stderr, "Send Who-Is-Router-To-Network message\n");
#endif
}
bytes_sent =
datalink_send_pdu(dst, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
#if PRINT_ENABLED
if (bytes_sent <= 0)
fprintf(stderr,
"Failed to Send Who-Is-Router-To-Network Request (%s)!\n",
strerror(errno));
#endif
}
/* pDNET_list: list of networks for which I am a router,
terminated with -1 */
void Send_I_Am_Router_To_Network(
const int DNET_list[])
{
int len = 0;
int pdu_len = 0;
BACNET_ADDRESS dest;
int bytes_sent = 0;
BACNET_NPDU_DATA npdu_data;
uint16_t dnet = 0;
unsigned index = 0;
npdu_encode_npdu_network(&npdu_data,
NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], NULL, NULL, &npdu_data);
/* encode the optional DNET list portion of the packet */
#if PRINT_ENABLED
fprintf(stderr, "Send I-Am-Router-To-Network message to:\n");
#endif
while (DNET_list[index] != -1) {
dnet = DNET_list[index];
len = encode_unsigned16(&Handler_Transmit_Buffer[pdu_len], dnet);
pdu_len += len;
index++;
#if PRINT_ENABLED
fprintf(stderr, "%u\n", dnet);
#endif
}
/* I-Am-Router-To-Network shall always be transmitted with
a broadcast MAC address. */
datalink_get_broadcast_address(&dest);
bytes_sent =
datalink_send_pdu(&dest, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
#if PRINT_ENABLED
if (bytes_sent <= 0)
fprintf(stderr,
"Failed to send I-Am-Router-To-Network message (%s)!\n",
strerror(errno));
#endif
}
/* */
void Send_Initialize_Routing_Table(
BACNET_ADDRESS * dst,
BACNET_ROUTER_PORT * router_port_list)
{
int len = 0;
int pdu_len = 0;
int bytes_sent = 0;
BACNET_NPDU_DATA npdu_data;
uint8_t number_of_ports = 0;
BACNET_ROUTER_PORT *router_port;
unsigned i = 0; /* counter */
npdu_encode_npdu_network(&npdu_data, NETWORK_MESSAGE_INIT_RT_TABLE,
MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], NULL, NULL, &npdu_data);
/* encode the optional port_info list portion of the packet */
router_port = router_port_list;
while (router_port) {
number_of_ports++;
router_port = router_port->next;
}
Handler_Transmit_Buffer[pdu_len++] = number_of_ports;
if (number_of_ports) {
router_port = router_port_list;
while (router_port) {
len =
encode_unsigned16(&Handler_Transmit_Buffer[pdu_len],
router_port->dnet);
pdu_len += len;
Handler_Transmit_Buffer[pdu_len++] = router_port->id;
Handler_Transmit_Buffer[pdu_len++] = router_port->info_len;
for (i = 0; i < router_port->info_len; i++) {
Handler_Transmit_Buffer[pdu_len++] = router_port->info[i];
}
router_port = router_port->next;
}
}
#if PRINT_ENABLED
fprintf(stderr, "Send Initialize-Routing-Table message\n");
#endif
bytes_sent =
datalink_send_pdu(dst, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
#if PRINT_ENABLED
if (bytes_sent <= 0)
fprintf(stderr,
"Failed to send Initialize-Routing-Table message (%s)!\n",
strerror(errno));
#endif
}
/* */
void Send_Initialize_Routing_Table_Ack(
BACNET_ROUTER_PORT * router_port_list)
{
int pdu_len = 0;
BACNET_ADDRESS dest;
int bytes_sent = 0;
BACNET_NPDU_DATA npdu_data;
npdu_encode_npdu_network(&npdu_data, NETWORK_MESSAGE_INIT_RT_TABLE_ACK,
MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], NULL, NULL, &npdu_data);
/* encode the optional DNET list portion of the packet */
datalink_get_broadcast_address(&dest);
bytes_sent =
datalink_send_pdu(&dest, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
#if PRINT_ENABLED
if (bytes_sent <= 0)
fprintf(stderr,
"Failed to Send Initialize-Routing-Table-Ack message (%s)!\n",
strerror(errno));
#endif
}
+242 -243
View File
@@ -1,243 +1,242 @@
/**************************************************************************
*
* Copyright (C) 2008 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* command line tool that sends a BACnet service, and displays the reply */
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h> /* for time */
#include <errno.h>
#include "bactext.h"
#include "iam.h"
#include "address.h"
#include "config.h"
#include "bacdef.h"
#include "npdu.h"
#include "apdu.h"
#include "device.h"
#include "datalink.h"
/* some demo stuff needed */
#include "filename.h"
#include "handlers.h"
#include "client.h"
#include "txbuf.h"
#if defined(BACDL_MSTP)
#include "rs485.h"
#endif
/* buffer used for receive */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
/* global variables used in this file */
#define MAX_ROUTER_DNETS 64
static int Target_Router_Networks[MAX_ROUTER_DNETS] = { -1 };
static bool Error_Detected = false;
void MyAbortHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t abort_reason,
bool server)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
(void) server;
printf("BACnet Abort: %s\r\n", bactext_abort_reason_name(abort_reason));
Error_Detected = true;
}
void MyRejectHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t reject_reason)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
printf("BACnet Reject: %s\r\n", bactext_reject_reason_name(reject_reason));
Error_Detected = true;
}
static void Init_Service_Handlers(
void)
{
/* we need to handle who-is
to support dynamic device binding to us */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
/* 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);
/* we must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property);
/* handle the reply (request) coming back */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_add);
/* handle any errors coming back */
apdu_set_abort_handler(MyAbortHandler);
apdu_set_reject_handler(MyRejectHandler);
}
static void Init_DataLink(
void)
{
char *pEnv = NULL;
#if defined(BACDL_BIP) && BBMD_ENABLED
long bbmd_port = 0xBAC0;
long bbmd_address = 0;
long bbmd_timetolive_seconds = 60000;
#endif
#if defined(BACDL_ALL)
pEnv = getenv("BACNET_DATALINK");
if (pEnv) {
datalink_set(pEnv));
} else {
datalink_set(NULL);
}
#endif
#if defined(BACDL_BIP)
pEnv = getenv("BACNET_IP_PORT");
if (pEnv) {
bip_set_port(strtol(pEnv, NULL, 0));
} else {
bip_set_port(0xBAC0);
}
#elif defined(BACDL_MSTP)
pEnv = getenv("BACNET_MAX_INFO_FRAMES");
if (pEnv) {
dlmstp_set_max_info_frames(strtol(pEnv, NULL, 0));
} else {
dlmstp_set_max_info_frames(1);
}
pEnv = getenv("BACNET_MAX_MASTER");
if (pEnv) {
dlmstp_set_max_master(strtol(pEnv, NULL, 0));
} else {
dlmstp_set_max_master(127);
}
pEnv = getenv("BACNET_MSTP_BAUD");
if (pEnv) {
RS485_Set_Baud_Rate(strtol(pEnv, NULL, 0));
} else {
RS485_Set_Baud_Rate(38400);
}
pEnv = getenv("BACNET_MSTP_MAC");
if (pEnv) {
dlmstp_set_mac_address(strtol(pEnv, NULL, 0));
} else {
dlmstp_set_mac_address(127);
}
#endif
if (!datalink_init(getenv("BACNET_IFACE"))) {
exit(1);
}
#if defined(BACDL_BIP) && BBMD_ENABLED
pEnv = getenv("BACNET_BBMD_PORT");
if (pEnv) {
bbmd_port = strtol(pEnv, NULL, 0);
if (bbmd_port > 0xFFFF) {
bbmd_port = 0xBAC0;
}
}
pEnv = getenv("BACNET_BBMD_TIMETOLIVE");
if (pEnv) {
bbmd_timetolive_seconds = strtol(pEnv, NULL, 0);
if (bbmd_timetolive_seconds > 0xFFFF) {
bbmd_timetolive_seconds = 0xFFFF;
}
}
pEnv = getenv("BACNET_BBMD_ADDRESS");
if (pEnv) {
bbmd_address = bip_getaddrbyname(pEnv);
if (bbmd_address) {
struct in_addr addr;
addr.s_addr = bbmd_address;
printf("WhoIs: Registering with BBMD at %s:%ld for %ld seconds\n",
inet_ntoa(addr), bbmd_port, bbmd_timetolive_seconds);
bvlc_register_with_bbmd(bbmd_address, bbmd_port,
bbmd_timetolive_seconds);
}
}
#endif
}
int main(int argc, char *argv[]) {
unsigned arg_count = 0;
if (argc < 2) {
printf("Usage: %s DNET [DNET] [DNET] [...]\r\n",
filename_remove_path(argv[0]));
return 0;
}
if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) {
printf("Send BACnet I-Am-Router-To-Network message for \r\n"
"one or more networks.\r\n"
"\r\nDNET:\r\n"
"BACnet destination network number 0-65534\r\n"
"To send a I-Am-Router-To-Network message for DNET 86:\r\n"
"%s 86\r\n"
"To send a I-Am-Router-To-Network message for multiple DNETs\r\n"
"use the following command:\r\n"
"%s 86 42 24 14\r\n",
filename_remove_path(argv[0]),
filename_remove_path(argv[0]));
return 0;
}
/* decode the command line parameters */
if (argc > 1) {
for (arg_count = 1; arg_count < argc; arg_count++) {
if (arg_count > MAX_ROUTER_DNETS) {
fprintf(stderr,
"Limited to %u DNETS. Sorry!\r\n",
MAX_ROUTER_DNETS);
break;
}
Target_Router_Networks[arg_count-1] = strtol(argv[arg_count], NULL, 0);
/* mark the end of list */
Target_Router_Networks[arg_count] = -1;
/* invalid DNET? */
if (Target_Router_Networks[arg_count-1] >= 65535) {
fprintf(stderr,
"DNET=%u - it must be less than %u\r\n",
Target_Router_Networks[arg_count-1], 65535);
return 1;
}
}
}
/* setup my info */
Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
Init_Service_Handlers();
address_init();
Init_DataLink();
/* send the request */
Send_I_Am_Router_To_Network(Target_Router_Networks);
return 0;
}
/**************************************************************************
*
* Copyright (C) 2008 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* command line tool that sends a BACnet service, and displays the reply */
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h> /* for time */
#include <errno.h>
#include "bactext.h"
#include "iam.h"
#include "address.h"
#include "config.h"
#include "bacdef.h"
#include "npdu.h"
#include "apdu.h"
#include "device.h"
#include "datalink.h"
/* some demo stuff needed */
#include "filename.h"
#include "handlers.h"
#include "client.h"
#include "txbuf.h"
#if defined(BACDL_MSTP)
#include "rs485.h"
#endif
/* buffer used for receive */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
/* global variables used in this file */
#define MAX_ROUTER_DNETS 64
static int Target_Router_Networks[MAX_ROUTER_DNETS] = { -1 };
static bool Error_Detected = false;
void MyAbortHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t abort_reason,
bool server)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
(void) server;
printf("BACnet Abort: %s\r\n", bactext_abort_reason_name(abort_reason));
Error_Detected = true;
}
void MyRejectHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t reject_reason)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
printf("BACnet Reject: %s\r\n", bactext_reject_reason_name(reject_reason));
Error_Detected = true;
}
static void Init_Service_Handlers(
void)
{
/* we need to handle who-is
to support dynamic device binding to us */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
/* 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);
/* we must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property);
/* handle the reply (request) coming back */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_add);
/* handle any errors coming back */
apdu_set_abort_handler(MyAbortHandler);
apdu_set_reject_handler(MyRejectHandler);
}
static void Init_DataLink(
void)
{
char *pEnv = NULL;
#if defined(BACDL_BIP) && BBMD_ENABLED
long bbmd_port = 0xBAC0;
long bbmd_address = 0;
long bbmd_timetolive_seconds = 60000;
#endif
#if defined(BACDL_ALL)
pEnv = getenv("BACNET_DATALINK");
if (pEnv) {
datalink_set(pEnv));
} else {
datalink_set(NULL);
}
#endif
#if defined(BACDL_BIP)
pEnv = getenv("BACNET_IP_PORT");
if (pEnv) {
bip_set_port(strtol(pEnv, NULL, 0));
} else {
bip_set_port(0xBAC0);
}
#elif defined(BACDL_MSTP)
pEnv = getenv("BACNET_MAX_INFO_FRAMES");
if (pEnv) {
dlmstp_set_max_info_frames(strtol(pEnv, NULL, 0));
} else {
dlmstp_set_max_info_frames(1);
}
pEnv = getenv("BACNET_MAX_MASTER");
if (pEnv) {
dlmstp_set_max_master(strtol(pEnv, NULL, 0));
} else {
dlmstp_set_max_master(127);
}
pEnv = getenv("BACNET_MSTP_BAUD");
if (pEnv) {
RS485_Set_Baud_Rate(strtol(pEnv, NULL, 0));
} else {
RS485_Set_Baud_Rate(38400);
}
pEnv = getenv("BACNET_MSTP_MAC");
if (pEnv) {
dlmstp_set_mac_address(strtol(pEnv, NULL, 0));
} else {
dlmstp_set_mac_address(127);
}
#endif
if (!datalink_init(getenv("BACNET_IFACE"))) {
exit(1);
}
#if defined(BACDL_BIP) && BBMD_ENABLED
pEnv = getenv("BACNET_BBMD_PORT");
if (pEnv) {
bbmd_port = strtol(pEnv, NULL, 0);
if (bbmd_port > 0xFFFF) {
bbmd_port = 0xBAC0;
}
}
pEnv = getenv("BACNET_BBMD_TIMETOLIVE");
if (pEnv) {
bbmd_timetolive_seconds = strtol(pEnv, NULL, 0);
if (bbmd_timetolive_seconds > 0xFFFF) {
bbmd_timetolive_seconds = 0xFFFF;
}
}
pEnv = getenv("BACNET_BBMD_ADDRESS");
if (pEnv) {
bbmd_address = bip_getaddrbyname(pEnv);
if (bbmd_address) {
struct in_addr addr;
addr.s_addr = bbmd_address;
printf("WhoIs: Registering with BBMD at %s:%ld for %ld seconds\n",
inet_ntoa(addr), bbmd_port, bbmd_timetolive_seconds);
bvlc_register_with_bbmd(bbmd_address, bbmd_port,
bbmd_timetolive_seconds);
}
}
#endif
}
int main(int argc, char *argv[]) {
unsigned arg_count = 0;
if (argc < 2) {
printf("Usage: %s DNET [DNET] [DNET] [...]\r\n",
filename_remove_path(argv[0]));
return 0;
}
if ((
argc > 1) && (
strcmp(argv[1],
"--help") == 0)) {
printf("Send BACnet I-Am-Router-To-Network message for \r\n"
"one or more networks.\r\n" "\r\nDNET:\r\n"
"BACnet destination network number 0-65534\r\n"
"To send a I-Am-Router-To-Network message for DNET 86:\r\n"
"%s 86\r\n"
"To send a I-Am-Router-To-Network message for multiple DNETs\r\n"
"use the following command:\r\n" "%s 86 42 24 14\r\n",
filename_remove_path(argv[0]), filename_remove_path(argv[0]));
return 0;
}
/* decode the command line parameters */
if (argc > 1) {
for (arg_count = 1; arg_count < argc; arg_count++) {
if (arg_count > MAX_ROUTER_DNETS) {
fprintf(stderr, "Limited to %u DNETS. Sorry!\r\n",
MAX_ROUTER_DNETS);
break;
}
Target_Router_Networks[arg_count - 1] =
strtol(argv[arg_count], NULL, 0);
/* mark the end of list */
Target_Router_Networks[arg_count] = -1;
/* invalid DNET? */
if (Target_Router_Networks[arg_count - 1] >= 65535) {
fprintf(stderr, "DNET=%u - it must be less than %u\r\n",
Target_Router_Networks[arg_count - 1], 65535);
return 1;
}
}
}
/* setup my info */
Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
Init_Service_Handlers();
address_init();
Init_DataLink();
/* send the request */
Send_I_Am_Router_To_Network(Target_Router_Networks);
return 0;
}
+271 -270
View File
@@ -1,270 +1,271 @@
/**************************************************************************
*
* Copyright (C) 2008 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* command line tool that sends a BACnet service, and displays the reply */
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h> /* for time */
#include <errno.h>
#include "bactext.h"
#include "iam.h"
#include "address.h"
#include "config.h"
#include "bacdef.h"
#include "npdu.h"
#include "apdu.h"
#include "device.h"
#include "datalink.h"
/* some demo stuff needed */
#include "filename.h"
#include "handlers.h"
#include "client.h"
#include "txbuf.h"
#if defined(BACDL_MSTP)
#include "rs485.h"
#endif
/* buffer used for receive */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
/* target address */
static BACNET_ADDRESS Target_Router_Address;
static BACNET_ROUTER_PORT *Target_Router_Port_List;
static bool Error_Detected = false;
void MyAbortHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t abort_reason,
bool server)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
(void) server;
printf("BACnet Abort: %s\r\n", bactext_abort_reason_name(abort_reason));
Error_Detected = true;
}
void MyRejectHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t reject_reason)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
printf("BACnet Reject: %s\r\n", bactext_reject_reason_name(reject_reason));
Error_Detected = true;
}
static void Init_Service_Handlers(
void)
{
/* we need to handle who-is
to support dynamic device binding to us */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
/* 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);
/* we must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property);
/* handle the reply (request) coming back */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_add);
/* handle any errors coming back */
apdu_set_abort_handler(MyAbortHandler);
apdu_set_reject_handler(MyRejectHandler);
}
static void Init_DataLink(
void)
{
char *pEnv = NULL;
#if defined(BACDL_BIP) && BBMD_ENABLED
long bbmd_port = 0xBAC0;
long bbmd_address = 0;
long bbmd_timetolive_seconds = 60000;
#endif
#if defined(BACDL_ALL)
pEnv = getenv("BACNET_DATALINK");
if (pEnv) {
datalink_set(pEnv));
} else {
datalink_set(NULL);
}
#endif
#if defined(BACDL_BIP)
pEnv = getenv("BACNET_IP_PORT");
if (pEnv) {
bip_set_port(strtol(pEnv, NULL, 0));
} else {
bip_set_port(0xBAC0);
}
#elif defined(BACDL_MSTP)
pEnv = getenv("BACNET_MAX_INFO_FRAMES");
if (pEnv) {
dlmstp_set_max_info_frames(strtol(pEnv, NULL, 0));
} else {
dlmstp_set_max_info_frames(1);
}
pEnv = getenv("BACNET_MAX_MASTER");
if (pEnv) {
dlmstp_set_max_master(strtol(pEnv, NULL, 0));
} else {
dlmstp_set_max_master(127);
}
pEnv = getenv("BACNET_MSTP_BAUD");
if (pEnv) {
RS485_Set_Baud_Rate(strtol(pEnv, NULL, 0));
} else {
RS485_Set_Baud_Rate(38400);
}
pEnv = getenv("BACNET_MSTP_MAC");
if (pEnv) {
dlmstp_set_mac_address(strtol(pEnv, NULL, 0));
} else {
dlmstp_set_mac_address(127);
}
#endif
if (!datalink_init(getenv("BACNET_IFACE"))) {
exit(1);
}
#if defined(BACDL_BIP) && BBMD_ENABLED
pEnv = getenv("BACNET_BBMD_PORT");
if (pEnv) {
bbmd_port = strtol(pEnv, NULL, 0);
if (bbmd_port > 0xFFFF) {
bbmd_port = 0xBAC0;
}
}
pEnv = getenv("BACNET_BBMD_TIMETOLIVE");
if (pEnv) {
bbmd_timetolive_seconds = strtol(pEnv, NULL, 0);
if (bbmd_timetolive_seconds > 0xFFFF) {
bbmd_timetolive_seconds = 0xFFFF;
}
}
pEnv = getenv("BACNET_BBMD_ADDRESS");
if (pEnv) {
bbmd_address = bip_getaddrbyname(pEnv);
if (bbmd_address) {
struct in_addr addr;
addr.s_addr = bbmd_address;
printf("NPDU: Registering with BBMD at %s:%ld for %ld seconds\n",
inet_ntoa(addr), bbmd_port, bbmd_timetolive_seconds);
bvlc_register_with_bbmd(bbmd_address, bbmd_port,
bbmd_timetolive_seconds);
}
}
#endif
}
static void address_parse(BACNET_ADDRESS *dst, int argc, char *argv[])
{
unsigned mac[6];
unsigned port;
int count = 0;
int index = 0;
if (argc > 0) {
count =
sscanf(argv[0], "%u.%u.%u.%u:%u", &mac[0],
&mac[1], &mac[2], &mac[3], &port);
if (count == 5) {
dst->mac_len = 6;
for (index = 0; index < 4; index++) {
dst->mac[index] = mac[index];
}
encode_unsigned16(&dst->mac[4], port);
} else {
count =
sscanf(argv[0], "%x:%x:%x:%x:%x:%x", &mac[0],
&mac[1], &mac[2], &mac[3], &mac[4], &mac[5]);
dst->mac_len = count;
for (index = 0; index < MAX_MAC_LEN; index++) {
if (index < count) {
dst->mac[index] = mac[index];
} else {
dst->mac[index] = 0;
}
}
}
}
dst->net = 0;
dst->len = 0;
for (index = 0; index < MAX_MAC_LEN; index++) {
dst->adr[index] = 0;
}
}
int main(int argc, char *argv[]) {
if (argc < 2) {
printf("Usage: %s address number-of-ports [DNET ID Len Info]\r\n",
filename_remove_path(argv[0]));
return 0;
}
if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) {
printf("Send BACnet Initialize-Routing-Table message to a network\r\n"
"and wait for responses. Displays their network information.\r\n"
"\r\n"
"address:\r\n"
"MAC address in xx:xx:xx:xx:xx:xx format or IP x.x.x.x:port\r\n"
"number-of-ports:\r\n"
"Number of ports to update along with port-info data\r\n"
"To query the complete routing table, use 0.\r\n"
"To query using Initialize-Routing-Table message to 192.168.0.18:\r\n"
"%s 192.168.0.18:47808 0\r\n",
filename_remove_path(argv[0]));
return 0;
}
/* decode the command line parameters */
address_parse(&Target_Router_Address, argc-1, &argv[1]);
if (argc > 2) {
/* FIXME: add port info parse */
/* BACNET_ROUTER_PORT *router_port_list
Target_Router_Port_List
ports_parse(&router_port[0], argc-2, &argv[2]);
Target_Router_Port_List = router_port[0];
*/
}
/* setup my info */
Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
Init_Service_Handlers();
address_init();
Init_DataLink();
/* send the request */
Send_Initialize_Routing_Table(
&Target_Router_Address,
Target_Router_Port_List);
return 0;
}
/**************************************************************************
*
* Copyright (C) 2008 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* command line tool that sends a BACnet service, and displays the reply */
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h> /* for time */
#include <errno.h>
#include "bactext.h"
#include "iam.h"
#include "address.h"
#include "config.h"
#include "bacdef.h"
#include "npdu.h"
#include "apdu.h"
#include "device.h"
#include "datalink.h"
/* some demo stuff needed */
#include "filename.h"
#include "handlers.h"
#include "client.h"
#include "txbuf.h"
#if defined(BACDL_MSTP)
#include "rs485.h"
#endif
/* buffer used for receive */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
/* target address */
static BACNET_ADDRESS Target_Router_Address;
static BACNET_ROUTER_PORT *Target_Router_Port_List;
static bool Error_Detected = false;
void MyAbortHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t abort_reason,
bool server)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
(void) server;
printf("BACnet Abort: %s\r\n", bactext_abort_reason_name(abort_reason));
Error_Detected = true;
}
void MyRejectHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t reject_reason)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
printf("BACnet Reject: %s\r\n", bactext_reject_reason_name(reject_reason));
Error_Detected = true;
}
static void Init_Service_Handlers(
void)
{
/* we need to handle who-is
to support dynamic device binding to us */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
/* 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);
/* we must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property);
/* handle the reply (request) coming back */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_add);
/* handle any errors coming back */
apdu_set_abort_handler(MyAbortHandler);
apdu_set_reject_handler(MyRejectHandler);
}
static void Init_DataLink(
void)
{
char *pEnv = NULL;
#if defined(BACDL_BIP) && BBMD_ENABLED
long bbmd_port = 0xBAC0;
long bbmd_address = 0;
long bbmd_timetolive_seconds = 60000;
#endif
#if defined(BACDL_ALL)
pEnv = getenv("BACNET_DATALINK");
if (pEnv) {
datalink_set(pEnv));
} else {
datalink_set(NULL);
}
#endif
#if defined(BACDL_BIP)
pEnv = getenv("BACNET_IP_PORT");
if (pEnv) {
bip_set_port(strtol(pEnv, NULL, 0));
} else {
bip_set_port(0xBAC0);
}
#elif defined(BACDL_MSTP)
pEnv = getenv("BACNET_MAX_INFO_FRAMES");
if (pEnv) {
dlmstp_set_max_info_frames(strtol(pEnv, NULL, 0));
} else {
dlmstp_set_max_info_frames(1);
}
pEnv = getenv("BACNET_MAX_MASTER");
if (pEnv) {
dlmstp_set_max_master(strtol(pEnv, NULL, 0));
} else {
dlmstp_set_max_master(127);
}
pEnv = getenv("BACNET_MSTP_BAUD");
if (pEnv) {
RS485_Set_Baud_Rate(strtol(pEnv, NULL, 0));
} else {
RS485_Set_Baud_Rate(38400);
}
pEnv = getenv("BACNET_MSTP_MAC");
if (pEnv) {
dlmstp_set_mac_address(strtol(pEnv, NULL, 0));
} else {
dlmstp_set_mac_address(127);
}
#endif
if (!datalink_init(getenv("BACNET_IFACE"))) {
exit(1);
}
#if defined(BACDL_BIP) && BBMD_ENABLED
pEnv = getenv("BACNET_BBMD_PORT");
if (pEnv) {
bbmd_port = strtol(pEnv, NULL, 0);
if (bbmd_port > 0xFFFF) {
bbmd_port = 0xBAC0;
}
}
pEnv = getenv("BACNET_BBMD_TIMETOLIVE");
if (pEnv) {
bbmd_timetolive_seconds = strtol(pEnv, NULL, 0);
if (bbmd_timetolive_seconds > 0xFFFF) {
bbmd_timetolive_seconds = 0xFFFF;
}
}
pEnv = getenv("BACNET_BBMD_ADDRESS");
if (pEnv) {
bbmd_address = bip_getaddrbyname(pEnv);
if (bbmd_address) {
struct in_addr addr;
addr.s_addr = bbmd_address;
printf("NPDU: Registering with BBMD at %s:%ld for %ld seconds\n",
inet_ntoa(addr), bbmd_port, bbmd_timetolive_seconds);
bvlc_register_with_bbmd(bbmd_address, bbmd_port,
bbmd_timetolive_seconds);
}
}
#endif
}
static void address_parse(BACNET_ADDRESS * dst,
int argc, char *argv[]) {
unsigned mac[6];
unsigned port;
int count = 0;
int index = 0;
if (argc > 0) {
count =
sscanf(argv[0], "%u.%u.%u.%u:%u", &mac[0], &mac[1], &mac[2],
&mac[3], &port);
if (count == 5) {
dst->mac_len = 6;
for (index = 0; index < 4; index++) {
dst->mac[index] = mac[index];
} encode_unsigned16(&dst->mac[4],
port);
} else {
count =
sscanf(argv[0], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2],
&mac[3], &mac[4], &mac[5]);
dst->mac_len = count;
for (index = 0; index < MAX_MAC_LEN; index++) {
if (index < count) {
dst->mac[index] = mac[index];
} else {
dst->mac[index] = 0;
}
}
}
}
dst->net = 0;
dst->len = 0;
for (index = 0; index < MAX_MAC_LEN; index++) {
dst->adr[index] = 0;
}
}
int main(int argc, char *argv[]) {
if (argc < 2) {
printf("Usage: %s address number-of-ports [DNET ID Len Info]\r\n",
filename_remove_path(argv[0]));
return 0;
}
if ((
argc > 1) && (
strcmp(argv[1],
"--help") == 0)) {
printf("Send BACnet Initialize-Routing-Table message to a network\r\n"
"and wait for responses. Displays their network information.\r\n"
"\r\n" "address:\r\n"
"MAC address in xx:xx:xx:xx:xx:xx format or IP x.x.x.x:port\r\n"
"number-of-ports:\r\n"
"Number of ports to update along with port-info data\r\n"
"To query the complete routing table, use 0.\r\n"
"To query using Initialize-Routing-Table message to 192.168.0.18:\r\n"
"%s 192.168.0.18:47808 0\r\n", filename_remove_path(argv[0]));
return 0;
}
/* decode the command line parameters */
address_parse(&Target_Router_Address, argc - 1, &argv[1]);
if (argc > 2) {
/* FIXME: add port info parse */
/* BACNET_ROUTER_PORT *router_port_list
Target_Router_Port_List
ports_parse(&router_port[0], argc-2, &argv[2]);
Target_Router_Port_List = router_port[0];
*/
}
/* setup my info */
Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
Init_Service_Handlers();
address_init();
Init_DataLink();
/* send the request */
Send_Initialize_Routing_Table(&Target_Router_Address,
Target_Router_Port_List);
return 0;
}
+3 -6
View File
@@ -806,8 +806,7 @@ int Device_Encode_Property_APDU(
}
break;
case PROP_MAX_APDU_LENGTH_ACCEPTED:
apdu_len =
encode_application_unsigned(&apdu[0],MAX_APDU);
apdu_len = encode_application_unsigned(&apdu[0], MAX_APDU);
break;
case PROP_SEGMENTATION_SUPPORTED:
apdu_len =
@@ -818,8 +817,7 @@ int Device_Encode_Property_APDU(
apdu_len = encode_application_unsigned(&apdu[0], apdu_timeout());
break;
case PROP_NUMBER_OF_APDU_RETRIES:
apdu_len =
encode_application_unsigned(&apdu[0], apdu_retries());
apdu_len = encode_application_unsigned(&apdu[0], apdu_retries());
break;
case PROP_DEVICE_ADDRESS_BINDING:
/* FIXME: encode the list here, if it exists */
@@ -894,8 +892,7 @@ bool Device_Write_Property(
case PROP_NUMBER_OF_APDU_RETRIES:
if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
/* FIXME: bounds check? */
apdu_retries_set((uint8_t) value.type.
Unsigned_Int);
apdu_retries_set((uint8_t) value.type.Unsigned_Int);
status = true;
} else {
*error_class = ERROR_CLASS_PROPERTY;
+1 -2
View File
@@ -325,8 +325,7 @@ int main(int argc, char *argv[]) {
Init_DataLink();
/* configure the timeout values */
last_seconds = time(NULL);
timeout_seconds =
(apdu_timeout() / 1000) * apdu_retries();
timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
/* try to bind with the device */
Send_WhoIs(Target_Device_Object_Instance, Target_Device_Object_Instance);
/* loop forever */
+1 -2
View File
@@ -306,8 +306,7 @@ int main(int argc, char *argv[]) {
Init_DataLink();
/* configure the timeout values */
last_seconds = time(NULL);
timeout_seconds =
(apdu_timeout() / 1000) * apdu_retries();
timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
/* try to bind with the device */
found =
address_bind_request(Target_Device_Object_Instance, &max_apdu,
+1 -2
View File
@@ -267,8 +267,7 @@ int main(int argc, char *argv[]) {
Init_DataLink();
/* configure the timeout values */
last_seconds = time(NULL);
timeout_seconds =
(apdu_timeout() / 1000) * apdu_retries();
timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
/* try to bind with the device */
Send_WhoIs(Target_Device_Object_Instance, Target_Device_Object_Instance);
/* loop forever */
+1 -1
View File
@@ -188,7 +188,7 @@ int main(int argc, char *argv[]) {
BACNET_ADDRESS src = {
0}; /* address where message came from */
uint16_t pdu_len = 0;
unsigned timeout = 1000; /* milliseconds */
unsigned timeout = 1000; /* milliseconds */
time_t last_seconds = 0;
time_t current_seconds = 0;
uint32_t elapsed_seconds = 0;
+2 -2
View File
@@ -212,8 +212,8 @@ int main(int argc, char *argv[]) {
filename_remove_path(argv[0]), filename_remove_path(argv[0]));
return 0;
}
/* decode the command line parameters */ cov_data.
subscriberProcessIdentifier = strtol(argv[1], NULL, 0);
/* decode the command line parameters */
cov_data.subscriberProcessIdentifier = strtol(argv[1], NULL, 0);
cov_data.initiatingDeviceIdentifier = strtol(argv[2], NULL, 0);
cov_data.monitoredObjectIdentifier.type = strtol(argv[3], NULL, 0);
cov_data.monitoredObjectIdentifier.instance = strtol(argv[4], NULL, 0);
+319 -327
View File
@@ -1,327 +1,319 @@
/**************************************************************************
*
* Copyright (C) 2008 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* command line tool that sends a BACnet service, and displays the reply */
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h> /* for time */
#include <errno.h>
#include "bactext.h"
#include "iam.h"
#include "address.h"
#include "config.h"
#include "bacdef.h"
#include "npdu.h"
#include "apdu.h"
#include "device.h"
#include "datalink.h"
/* some demo stuff needed */
#include "filename.h"
#include "handlers.h"
#include "client.h"
#include "txbuf.h"
#if defined(BACDL_MSTP)
#include "rs485.h"
#endif
/* buffer used for receive */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
/* global variables used in this file */
static int32_t Target_Router_Network = 0;
static BACNET_ADDRESS Target_Router_Address;
static bool Error_Detected = false;
void MyAbortHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t abort_reason,
bool server)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
(void) server;
printf("BACnet Abort: %s\r\n", bactext_abort_reason_name(abort_reason));
Error_Detected = true;
}
void MyRejectHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t reject_reason)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
printf("BACnet Reject: %s\r\n", bactext_reject_reason_name(reject_reason));
Error_Detected = true;
}
static void Init_Service_Handlers(
void)
{
/* we need to handle who-is
to support dynamic device binding to us */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
/* 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);
/* we must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property);
/* handle the reply (request) coming back */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_add);
/* handle any errors coming back */
apdu_set_abort_handler(MyAbortHandler);
apdu_set_reject_handler(MyRejectHandler);
}
static void Init_DataLink(
void)
{
char *pEnv = NULL;
#if defined(BACDL_BIP) && BBMD_ENABLED
long bbmd_port = 0xBAC0;
long bbmd_address = 0;
long bbmd_timetolive_seconds = 60000;
#endif
#if defined(BACDL_ALL)
pEnv = getenv("BACNET_DATALINK");
if (pEnv) {
datalink_set(pEnv));
} else {
datalink_set(NULL);
}
#endif
#if defined(BACDL_BIP)
pEnv = getenv("BACNET_IP_PORT");
if (pEnv) {
bip_set_port(strtol(pEnv, NULL, 0));
} else {
bip_set_port(0xBAC0);
}
#elif defined(BACDL_MSTP)
pEnv = getenv("BACNET_MAX_INFO_FRAMES");
if (pEnv) {
dlmstp_set_max_info_frames(strtol(pEnv, NULL, 0));
} else {
dlmstp_set_max_info_frames(1);
}
pEnv = getenv("BACNET_MAX_MASTER");
if (pEnv) {
dlmstp_set_max_master(strtol(pEnv, NULL, 0));
} else {
dlmstp_set_max_master(127);
}
pEnv = getenv("BACNET_MSTP_BAUD");
if (pEnv) {
RS485_Set_Baud_Rate(strtol(pEnv, NULL, 0));
} else {
RS485_Set_Baud_Rate(38400);
}
pEnv = getenv("BACNET_MSTP_MAC");
if (pEnv) {
dlmstp_set_mac_address(strtol(pEnv, NULL, 0));
} else {
dlmstp_set_mac_address(127);
}
#endif
if (!datalink_init(getenv("BACNET_IFACE"))) {
exit(1);
}
#if defined(BACDL_BIP) && BBMD_ENABLED
pEnv = getenv("BACNET_BBMD_PORT");
if (pEnv) {
bbmd_port = strtol(pEnv, NULL, 0);
if (bbmd_port > 0xFFFF) {
bbmd_port = 0xBAC0;
}
}
pEnv = getenv("BACNET_BBMD_TIMETOLIVE");
if (pEnv) {
bbmd_timetolive_seconds = strtol(pEnv, NULL, 0);
if (bbmd_timetolive_seconds > 0xFFFF) {
bbmd_timetolive_seconds = 0xFFFF;
}
}
pEnv = getenv("BACNET_BBMD_ADDRESS");
if (pEnv) {
bbmd_address = bip_getaddrbyname(pEnv);
if (bbmd_address) {
struct in_addr addr;
addr.s_addr = bbmd_address;
printf("WhoIs: Registering with BBMD at %s:%ld for %ld seconds\n",
inet_ntoa(addr), bbmd_port, bbmd_timetolive_seconds);
bvlc_register_with_bbmd(bbmd_address, bbmd_port,
bbmd_timetolive_seconds);
}
}
#endif
}
static void address_parse(BACNET_ADDRESS *dst, int argc, char *argv[])
{
int dnet = 0;
unsigned mac[6];
int count = 0;
int index = 0;
if (argc > 0) {
count =
sscanf(argv[0], "%x:%x:%x:%x:%x:%x", &mac[0],
&mac[1], &mac[2], &mac[3], &mac[4], &mac[5]);
dst->mac_len = count;
for (index = 0; index < MAX_MAC_LEN; index++) {
if (index < count) {
dst->mac[index] = mac[index];
} else {
dst->mac[index] = 0;
}
}
}
if (argc > 1) {
count = sscanf(argv[1], "%d", &dnet);
dst->net = dnet;
}
if (dnet) {
if (argc > 2) {
count =
sscanf(argv[2], "%x:%x:%x:%x:%x:%x", &mac[0],
&mac[1], &mac[2], &mac[3], &mac[4], &mac[5]);
dst->len = count;
for (index = 0; index < MAX_MAC_LEN; index++) {
if (index < count) {
dst->adr[index] = mac[index];
} else {
dst->adr[index] = 0;
}
}
} else {
fprintf(stderr,"A non-zero DNET requires a DADR.\r\n");
}
} else {
dst->len = 0;
for (index = 0; index < MAX_MAC_LEN; index++) {
dst->adr[index] = 0;
}
}
}
int main(int argc, char *argv[]) {
BACNET_ADDRESS src = {
0}; /* address where message came from */
uint16_t pdu_len = 0;
unsigned timeout = 100; /* milliseconds */
time_t total_seconds = 0;
time_t elapsed_seconds = 0;
time_t last_seconds = 0;
time_t current_seconds = 0;
time_t timeout_seconds = 0;
if (argc < 2) {
printf("Usage: %s DNET [MAC]\r\n",
filename_remove_path(argv[0]));
return 0;
}
if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) {
printf("Send BACnet Who-Is-Router-To-Network message to a network.\r\n"
"\r\n"
"DNET:\r\n"
"BACnet destination network number 0-65534\r\n"
"MAC:\r\n"
"Optional MAC address of router for unicast message\r\n"
"Format: xx[:xx:xx:xx:xx:xx] [dnet xx[:xx:xx:xx:xx:xx]]\r\n"
"Use hexidecimal MAC addresses.\r\n"
"\r\n"
"To send a Who-Is-Router-To-Network request to DNET 86:\r\n"
"%s 86\r\n"
"To send a Who-Is-Router-To-Network request to all devices:\r\n"
"%s -1\r\n",
filename_remove_path(argv[0]),
filename_remove_path(argv[0]));
return 0;
}
/* decode the command line parameters */
if (argc > 1) {
Target_Router_Network = strtol(argv[1], NULL, 0);
if (Target_Router_Network >= 65535) {
fprintf(stderr,
"DNET=%u - it must be less than %u\r\n",
Target_Router_Network, 65535);
return 1;
}
}
if (argc > 2) {
address_parse(&Target_Router_Address, argc-2, &argv[2]);
} else {
datalink_get_broadcast_address(&Target_Router_Address);
}
/* setup my info */
Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
Init_Service_Handlers();
address_init();
Init_DataLink();
/* configure the timeout values */
last_seconds = time(NULL);
timeout_seconds = apdu_timeout() / 1000;
/* send the request */
Send_Who_Is_Router_To_Network(
&Target_Router_Address,
Target_Router_Network);
/* loop forever */
for (;;) {
/* increment timer - exit if timed out */
current_seconds = time(NULL);
/* returns 0 bytes on timeout */
pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
/* process */
if (pdu_len) {
npdu_handler(&src, &Rx_Buf[0], pdu_len);
}
if (Error_Detected)
break;
/* increment timer - exit if timed out */
elapsed_seconds = current_seconds - last_seconds;
if (elapsed_seconds) {
#if defined(BACDL_BIP) && BBMD_ENABLED
bvlc_maintenance_timer(elapsed_seconds);
#endif
}
total_seconds += elapsed_seconds;
if (total_seconds > timeout_seconds)
break;
/* keep track of time for next check */
last_seconds = current_seconds;
}
return 0;
}
/**************************************************************************
*
* Copyright (C) 2008 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* command line tool that sends a BACnet service, and displays the reply */
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h> /* for time */
#include <errno.h>
#include "bactext.h"
#include "iam.h"
#include "address.h"
#include "config.h"
#include "bacdef.h"
#include "npdu.h"
#include "apdu.h"
#include "device.h"
#include "datalink.h"
/* some demo stuff needed */
#include "filename.h"
#include "handlers.h"
#include "client.h"
#include "txbuf.h"
#if defined(BACDL_MSTP)
#include "rs485.h"
#endif
/* buffer used for receive */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
/* global variables used in this file */
static int32_t Target_Router_Network = 0;
static BACNET_ADDRESS Target_Router_Address;
static bool Error_Detected = false;
void MyAbortHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t abort_reason,
bool server)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
(void) server;
printf("BACnet Abort: %s\r\n", bactext_abort_reason_name(abort_reason));
Error_Detected = true;
}
void MyRejectHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t reject_reason)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
printf("BACnet Reject: %s\r\n", bactext_reject_reason_name(reject_reason));
Error_Detected = true;
}
static void Init_Service_Handlers(
void)
{
/* we need to handle who-is
to support dynamic device binding to us */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
/* 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);
/* we must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property);
/* handle the reply (request) coming back */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_add);
/* handle any errors coming back */
apdu_set_abort_handler(MyAbortHandler);
apdu_set_reject_handler(MyRejectHandler);
}
static void Init_DataLink(
void)
{
char *pEnv = NULL;
#if defined(BACDL_BIP) && BBMD_ENABLED
long bbmd_port = 0xBAC0;
long bbmd_address = 0;
long bbmd_timetolive_seconds = 60000;
#endif
#if defined(BACDL_ALL)
pEnv = getenv("BACNET_DATALINK");
if (pEnv) {
datalink_set(pEnv));
} else {
datalink_set(NULL);
}
#endif
#if defined(BACDL_BIP)
pEnv = getenv("BACNET_IP_PORT");
if (pEnv) {
bip_set_port(strtol(pEnv, NULL, 0));
} else {
bip_set_port(0xBAC0);
}
#elif defined(BACDL_MSTP)
pEnv = getenv("BACNET_MAX_INFO_FRAMES");
if (pEnv) {
dlmstp_set_max_info_frames(strtol(pEnv, NULL, 0));
} else {
dlmstp_set_max_info_frames(1);
}
pEnv = getenv("BACNET_MAX_MASTER");
if (pEnv) {
dlmstp_set_max_master(strtol(pEnv, NULL, 0));
} else {
dlmstp_set_max_master(127);
}
pEnv = getenv("BACNET_MSTP_BAUD");
if (pEnv) {
RS485_Set_Baud_Rate(strtol(pEnv, NULL, 0));
} else {
RS485_Set_Baud_Rate(38400);
}
pEnv = getenv("BACNET_MSTP_MAC");
if (pEnv) {
dlmstp_set_mac_address(strtol(pEnv, NULL, 0));
} else {
dlmstp_set_mac_address(127);
}
#endif
if (!datalink_init(getenv("BACNET_IFACE"))) {
exit(1);
}
#if defined(BACDL_BIP) && BBMD_ENABLED
pEnv = getenv("BACNET_BBMD_PORT");
if (pEnv) {
bbmd_port = strtol(pEnv, NULL, 0);
if (bbmd_port > 0xFFFF) {
bbmd_port = 0xBAC0;
}
}
pEnv = getenv("BACNET_BBMD_TIMETOLIVE");
if (pEnv) {
bbmd_timetolive_seconds = strtol(pEnv, NULL, 0);
if (bbmd_timetolive_seconds > 0xFFFF) {
bbmd_timetolive_seconds = 0xFFFF;
}
}
pEnv = getenv("BACNET_BBMD_ADDRESS");
if (pEnv) {
bbmd_address = bip_getaddrbyname(pEnv);
if (bbmd_address) {
struct in_addr addr;
addr.s_addr = bbmd_address;
printf("WhoIs: Registering with BBMD at %s:%ld for %ld seconds\n",
inet_ntoa(addr), bbmd_port, bbmd_timetolive_seconds);
bvlc_register_with_bbmd(bbmd_address, bbmd_port,
bbmd_timetolive_seconds);
}
}
#endif
}
static void address_parse(BACNET_ADDRESS * dst,
int argc, char *argv[]) {
int dnet = 0;
unsigned mac[6];
int count = 0;
int index = 0;
if (argc > 0) {
count =
sscanf(argv[0], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2],
&mac[3], &mac[4], &mac[5]);
dst->mac_len = count;
for (index = 0; index < MAX_MAC_LEN; index++) {
if (index < count) {
dst->mac[index] = mac[index];
} else {
dst->mac[index] = 0;
}
}
}
if (argc > 1) {
count = sscanf(argv[1], "%d", &dnet);
dst->net = dnet;
}
if (dnet) {
if (argc > 2) {
count =
sscanf(argv[2], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2],
&mac[3], &mac[4], &mac[5]);
dst->len = count;
for (index = 0; index < MAX_MAC_LEN; index++) {
if (index < count) {
dst->adr[index] = mac[index];
} else {
dst->adr[index] = 0;
}
}
} else {
fprintf(stderr, "A non-zero DNET requires a DADR.\r\n");
}
} else {
dst->len = 0;
for (index = 0; index < MAX_MAC_LEN; index++) {
dst->adr[index] = 0;
}
}
}
int main(int argc, char *argv[]) {
BACNET_ADDRESS src = {
0}; /* address where message came from */
uint16_t pdu_len = 0;
unsigned timeout = 100; /* milliseconds */
time_t total_seconds = 0;
time_t elapsed_seconds = 0;
time_t last_seconds = 0;
time_t current_seconds = 0;
time_t timeout_seconds = 0;
if (argc < 2) {
printf("Usage: %s DNET [MAC]\r\n", filename_remove_path(argv[0]));
return 0;
}
if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) {
printf("Send BACnet Who-Is-Router-To-Network message to a network.\r\n"
"\r\n" "DNET:\r\n" "BACnet destination network number 0-65534\r\n"
"MAC:\r\n" "Optional MAC address of router for unicast message\r\n"
"Format: xx[:xx:xx:xx:xx:xx] [dnet xx[:xx:xx:xx:xx:xx]]\r\n"
"Use hexidecimal MAC addresses.\r\n" "\r\n"
"To send a Who-Is-Router-To-Network request to DNET 86:\r\n"
"%s 86\r\n"
"To send a Who-Is-Router-To-Network request to all devices:\r\n"
"%s -1\r\n", filename_remove_path(argv[0]),
filename_remove_path(argv[0]));
return 0;
}
/* decode the command line parameters */
if (argc > 1) {
Target_Router_Network = strtol(argv[1], NULL, 0);
if (Target_Router_Network >= 65535) {
fprintf(stderr, "DNET=%u - it must be less than %u\r\n",
Target_Router_Network, 65535);
return 1;
}
}
if (argc > 2) {
address_parse(&Target_Router_Address, argc - 2, &argv[2]);
} else {
datalink_get_broadcast_address(&Target_Router_Address);
}
/* setup my info */
Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
Init_Service_Handlers();
address_init();
Init_DataLink();
/* configure the timeout values */
last_seconds = time(NULL);
timeout_seconds = apdu_timeout() / 1000;
/* send the request */
Send_Who_Is_Router_To_Network(&Target_Router_Address,
Target_Router_Network);
/* loop forever */
for (;;) {
/* increment timer - exit if timed out */
current_seconds = time(NULL);
/* returns 0 bytes on timeout */
pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
/* process */
if (pdu_len) {
npdu_handler(&src, &Rx_Buf[0], pdu_len);
}
if (Error_Detected)
break;
/* increment timer - exit if timed out */
elapsed_seconds = current_seconds - last_seconds;
if (elapsed_seconds) {
#if defined(BACDL_BIP) && BBMD_ENABLED
bvlc_maintenance_timer(elapsed_seconds);
#endif
}
total_seconds += elapsed_seconds;
if (total_seconds > timeout_seconds)
break;
/* keep track of time for next check */
last_seconds = current_seconds;
}
return 0;
}
+1 -2
View File
@@ -282,8 +282,7 @@ int main(int argc, char *argv[]) {
Init_DataLink();
/* configure the timeout values */
last_seconds = time(NULL);
timeout_seconds =
(apdu_timeout() / 1000) * apdu_retries();
timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
/* try to bind with the device */
Send_WhoIs(Target_Device_Object_Instance, Target_Device_Object_Instance);
/* loop forever */
+1 -2
View File
@@ -402,8 +402,7 @@ int main(int argc, char *argv[]) {
Init_DataLink();
/* configure the timeout values */
last_seconds = time(NULL);
timeout_seconds =
(apdu_timeout() / 1000) * apdu_retries();
timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
/* try to bind with the device */
found =
address_bind_request(Target_Device_Object_Instance, &max_apdu,
+8 -4
View File
@@ -176,10 +176,14 @@ extern "C" {
uint8_t ** service_request,
uint16_t * service_request_len);
uint16_t apdu_timeout(void);
void apdu_timeout_set(uint16_t value);
uint8_t apdu_retries(void);
void apdu_retries_set(uint8_t value);
uint16_t apdu_timeout(
void);
void apdu_timeout_set(
uint16_t value);
uint8_t apdu_retries(
void);
void apdu_retries_set(
uint8_t value);
void apdu_handler(
BACNET_ADDRESS * src, /* source address */
+9 -9
View File
@@ -110,19 +110,19 @@ extern "C" {
BACNET_OCTET_STRING * fileData);
void Send_Who_Is_Router_To_Network(
BACNET_ADDRESS *dst,
BACNET_ADDRESS * dst,
int dnet);
void Send_I_Am_Router_To_Network(
const int DNET_list[]);
const int DNET_list[]);
void Send_Initialize_Routing_Table(
BACNET_ADDRESS *dst,
BACNET_ROUTER_PORT *router_port_list);
BACNET_ADDRESS * dst,
BACNET_ROUTER_PORT * router_port_list);
void Send_Initialize_Routing_Table_Ack(
BACNET_ROUTER_PORT *router_port_list);
BACNET_ROUTER_PORT * router_port_list);
#ifdef __cplusplus
}
#endif /* __cplusplus */
+2 -2
View File
@@ -47,8 +47,8 @@ void debug_printf(
static void debug_printf(
const char *format,
...)
{
format=format;
{
format = format;
}
#endif
+1 -1
View File
@@ -57,7 +57,7 @@ struct router_port_t;
typedef struct router_port_t {
uint16_t dnet;
uint8_t id;
uint8_t info[256]; /* size could be 1-255 */
uint8_t info[256]; /* size could be 1-255 */
uint8_t info_len;
struct router_port_t *next; /* linked list */
} BACNET_ROUTER_PORT;
+3 -7
View File
@@ -397,8 +397,7 @@ int Device_Encode_Property_APDU(
}
break;
case PROP_MAX_APDU_LENGTH_ACCEPTED:
apdu_len =
encode_application_unsigned(&apdu[0], MAX_APDU);
apdu_len = encode_application_unsigned(&apdu[0], MAX_APDU);
break;
case PROP_SEGMENTATION_SUPPORTED:
apdu_len =
@@ -406,13 +405,10 @@ int Device_Encode_Property_APDU(
Device_Segmentation_Supported());
break;
case PROP_APDU_TIMEOUT:
apdu_len =
encode_application_unsigned(&apdu[0], apdu_timeout());
apdu_len = encode_application_unsigned(&apdu[0], apdu_timeout());
break;
case PROP_NUMBER_OF_APDU_RETRIES:
apdu_len =
encode_application_unsigned(&apdu[0],
apdu_retries());
apdu_len = encode_application_unsigned(&apdu[0], apdu_retries());
break;
case PROP_DEVICE_ADDRESS_BINDING:
/* FIXME: encode the list here, if it exists */
+17 -15
View File
@@ -75,7 +75,9 @@ void dlmstp_millisecond_timer(
INCREMENT_AND_LIMIT_UINT16(SilenceTime);
}
void get_abstime(struct timespec *abstime, unsigned long milliseconds)
void get_abstime(
struct timespec *abstime,
unsigned long milliseconds)
{
struct timeval tp;
unsigned long seconds;
@@ -86,8 +88,8 @@ void get_abstime(struct timespec *abstime, unsigned long milliseconds)
abstime->tv_nsec = tp.tv_usec * 1000;
seconds = milliseconds / 1000;
abstime->tv_sec += seconds;
abstime->tv_nsec += ((milliseconds - (seconds * 1000))*(1000*1000));
seconds = abstime->tv_nsec / (1000*1000*1000);
abstime->tv_nsec += ((milliseconds - (seconds * 1000)) * (1000 * 1000));
seconds = abstime->tv_nsec / (1000 * 1000 * 1000);
abstime->tv_sec += seconds;
}
@@ -152,10 +154,8 @@ uint16_t dlmstp_receive(
(void) max_pdu;
/* see if there is a packet available, and a place
to put the reply (if necessary) and process it */
get_abstime(&abstime,timeout);
rv = pthread_cond_timedwait(
&Receive_Packet_Flag,
&Receive_Packet_Mutex,
get_abstime(&abstime, timeout);
rv = pthread_cond_timedwait(&Receive_Packet_Flag, &Receive_Packet_Mutex,
&abstime);
if (rv == 0) {
if (Receive_Packet.ready) {
@@ -227,8 +227,8 @@ static void *dlmstp_master_fsm_task(
if (milliseconds) {
get_abstime(&abstime, milliseconds);
/* we want an OS effecient way to wait for a frame */
pthread_cond_timedwait(&Received_Frame_Flag,
&Received_Frame_Mutex, &abstime);
pthread_cond_timedwait(&Received_Frame_Flag, &Received_Frame_Mutex,
&abstime);
}
MSTP_Master_Node_FSM(&MSTP_Port);
}
@@ -622,26 +622,28 @@ bool dlmstp_init(
Receive_Packet.pdu_len = 0;
rv = pthread_cond_init(&Receive_Packet_Flag, NULL);
if (rv == -1) {
fprintf(stderr, "MS/TP Interface: %s\n cannot allocate PThread Condition.\n",
fprintf(stderr,
"MS/TP Interface: %s\n cannot allocate PThread Condition.\n",
ifname);
exit(1);
}
rv = pthread_cond_init(&Received_Frame_Flag, NULL);
if (rv == -1) {
fprintf(stderr, "MS/TP Interface: %s\n cannot allocate PThread Condition.\n",
fprintf(stderr,
"MS/TP Interface: %s\n cannot allocate PThread Condition.\n",
ifname);
exit(1);
}
rv = pthread_mutex_init(&Receive_Packet_Mutex, NULL);
if (rv == -1) {
fprintf(stderr, "MS/TP Interface: %s\n cannot allocate PThread Mutex.\n",
ifname);
fprintf(stderr,
"MS/TP Interface: %s\n cannot allocate PThread Mutex.\n", ifname);
exit(1);
}
rv = pthread_mutex_init(&Received_Frame_Mutex, NULL);
if (rv == -1) {
fprintf(stderr, "MS/TP Interface: %s\n cannot allocate PThread Mutex.\n",
ifname);
fprintf(stderr,
"MS/TP Interface: %s\n cannot allocate PThread Mutex.\n", ifname);
exit(1);
}
/* initialize hardware */
+5 -5
View File
@@ -110,7 +110,7 @@ static int ethernet_bind(
/* alias net-pf-17 af_packet */
/* Then follow it by: # modprobe af_packet */
/* Note: PF_INET/SOCK_PACKET has been replaced with
PF_PACKET/(SOCK_PACKET, SOCK_DGRAM, SOCK_RAW).*/
PF_PACKET/(SOCK_PACKET, SOCK_DGRAM, SOCK_RAW). */
/* Attempt to open the socket for 802.2 ethernet frames */
if ((sock_fd = socket(PF_INET, SOCK_PACKET, htons(ETH_P_802_2))) < 0) {
@@ -125,13 +125,13 @@ static int ethernet_bind(
"# modprobe af_packet\n");
exit(-1);
}
#if 0
#if 0
/* It is very advisable to do a IP_HDRINCL call, to make sure
that the kernel knows the header is included in the data,
and doesn't insert its own header into the packet before our data */
if (setsockopt (sock_fd, IPPROTO_IP, IP_HDRINCL, &sockopt,
sizeof(sockopt)) < 0) {
printf ("Warning: Cannot set HDRINCL!\n");
if (setsockopt(sock_fd, IPPROTO_IP, IP_HDRINCL, &sockopt,
sizeof(sockopt)) < 0) {
printf("Warning: Cannot set HDRINCL!\n");
}
#endif
/* Bind the socket to an address */
+14 -13
View File
@@ -117,12 +117,13 @@ uint16_t MSTP_Get_Reply(
return 0;
}
static int network_init(const char *name, int protocol)
static int network_init(
const char *name,
int protocol)
{
/* check to see if we are being run as root */
if (getuid() != 0) {
fprintf(stderr,
"Requires root priveleges.\n");
fprintf(stderr, "Requires root priveleges.\n");
return -1;
}
@@ -162,9 +163,9 @@ static void snap_received_packet(
volatile struct mstp_port_struct_t *mstp_port,
int sockfd)
{
uint16_t mtu_len = 0; /* number of octets of packet saved in file */
unsigned i = 0; /* counter */
static uint8_t mtu[1500] = {0};
uint16_t mtu_len = 0; /* number of octets of packet saved in file */
unsigned i = 0; /* counter */
static uint8_t mtu[1500] = { 0 };
mtu[0] = 0;
mtu[1] = 0;
@@ -177,7 +178,7 @@ static void snap_received_packet(
mtu[8] = 0;
mtu[9] = 0;
mtu[10] = 0;
mtu[11]= mstp_port->SourceAddress;
mtu[11] = mstp_port->SourceAddress;
/* length - 12, 13 */
mtu[14] = 0xaa; /* DSAP for SNAP */
mtu[15] = 0xaa; /* SSAP for SNAP */
@@ -199,15 +200,15 @@ static void snap_received_packet(
mtu_len = 31;
if (mstp_port->DataLength) {
for (i = 0; i < mstp_port->DataLength; i++) {
mtu[31+i] = mstp_port->InputBuffer[i];
mtu[31 + i] = mstp_port->InputBuffer[i];
}
mtu[31+mstp_port->DataLength] = mstp_port->DataCRCActualMSB;
mtu[31+mstp_port->DataLength+1] = mstp_port->DataCRCActualLSB;
mtu_len += (mstp_port->DataLength+2);
mtu[31 + mstp_port->DataLength] = mstp_port->DataCRCActualMSB;
mtu[31 + mstp_port->DataLength + 1] = mstp_port->DataCRCActualLSB;
mtu_len += (mstp_port->DataLength + 2);
}
/* Ethernet length is data only - not address or length bytes */
encode_unsigned16(&mtu[12], mtu_len-14);
write(sockfd,&mtu[0], mtu_len);
encode_unsigned16(&mtu[12], mtu_len - 14);
write(sockfd, &mtu[0], mtu_len);
}
+3 -7
View File
@@ -409,8 +409,7 @@ int Device_Encode_Property_APDU(
}
break;
case PROP_MAX_APDU_LENGTH_ACCEPTED:
apdu_len =
encode_application_unsigned(&apdu[0], MAX_APDU);
apdu_len = encode_application_unsigned(&apdu[0], MAX_APDU);
break;
case PROP_SEGMENTATION_SUPPORTED:
apdu_len =
@@ -418,13 +417,10 @@ int Device_Encode_Property_APDU(
Device_Segmentation_Supported());
break;
case PROP_APDU_TIMEOUT:
apdu_len =
encode_application_unsigned(&apdu[0], apdu_timeout());
apdu_len = encode_application_unsigned(&apdu[0], apdu_timeout());
break;
case PROP_NUMBER_OF_APDU_RETRIES:
apdu_len =
encode_application_unsigned(&apdu[0],
apdu_retries());
apdu_len = encode_application_unsigned(&apdu[0], apdu_retries());
break;
case PROP_DEVICE_ADDRESS_BINDING:
/* FIXME: encode the list here, if it exists */
+8 -4
View File
@@ -285,22 +285,26 @@ uint16_t apdu_decode_confirmed_service_request(
return len;
}
uint16_t apdu_timeout(void)
uint16_t apdu_timeout(
void)
{
return Timeout_Milliseconds;
}
void apdu_timeout_set(uint16_t milliseconds)
void apdu_timeout_set(
uint16_t milliseconds)
{
Timeout_Milliseconds = milliseconds;
}
uint8_t apdu_retries(void)
uint8_t apdu_retries(
void)
{
return Number_Of_Retries;
}
void apdu_retries_set(uint8_t value)
void apdu_retries_set(
uint8_t value)
{
Number_Of_Retries = value;
}
+1 -2
View File
@@ -49,8 +49,7 @@ int arf_encode_apdu(
if (apdu) {
apdu[0] = PDU_TYPE_CONFIRMED_SERVICE_REQUEST;
apdu[1] =
encode_max_segs_max_apdu(0, MAX_APDU);
apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU);
apdu[2] = invoke_id;
apdu[3] = SERVICE_CONFIRMED_ATOMIC_READ_FILE; /* service choice */
apdu_len = 4;
+4 -4
View File
@@ -72,7 +72,7 @@ static inline void printf_receive(
const char *format,
...)
{
format=format;
format = format;
}
#endif
@@ -83,7 +83,7 @@ static inline void printf_receive_data(
const char *format,
...)
{
format=format;
format = format;
}
#endif
@@ -94,7 +94,7 @@ static inline void printf_receive_error(
const char *format,
...)
{
format=format;
format = format;
}
#endif
@@ -105,7 +105,7 @@ static inline void printf_master(
const char *format,
...)
{
format=format;
format = format;
}
#endif