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