Fixed checkin of subversion where I had copied the .svn file when creating the new directory.

This commit is contained in:
skarg
2008-11-24 04:52:37 +00:00
parent e3f91b3916
commit fdfd6a9f9f
7 changed files with 694 additions and 118 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
# Compiler to use
CC = gcc
# Executable file name
TARGET = bacrpm
TARGET = bacrp
# Configure the BACnet Datalink Layer
#BACDL_DEFINE = -DBACDL_ETHERNET=1
+38 -114
View File
@@ -1,5 +1,5 @@
/*************************************************************************
* Copyright (C) 2008 Steve Karg <skarg@users.sourceforge.net>
* Copyright (C) 2006 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
@@ -47,7 +47,6 @@
#include "datalink.h"
#include "whois.h"
/* some demo stuff needed */
#include "rpm.h"
#include "filename.h"
#include "handlers.h"
#include "client.h"
@@ -58,7 +57,10 @@ static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
/* global variables used in this file */
static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE;
static BACNET_READ_ACCESS_DATA *Read_Access_Data;
static uint32_t Target_Object_Instance = BACNET_MAX_INSTANCE;
static BACNET_OBJECT_TYPE Target_Object_Type = OBJECT_ANALOG_INPUT;
static BACNET_PROPERTY_ID Target_Object_Property = PROP_ACKED_TRANSITIONS;
static int32_t Target_Object_Index = BACNET_ARRAY_ALL;
static BACNET_ADDRESS Target_Address;
static bool Error_Detected = false;
@@ -122,8 +124,8 @@ static void Init_Service_Handlers(
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property);
/* handle the data coming back from confirmed requests */
apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE,
handler_read_property_multiple_ack);
apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property_ack);
/* handle any errors coming back */
apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, MyErrorHandler);
apdu_set_abort_handler(MyAbortHandler);
@@ -216,49 +218,22 @@ static void Init_DataLink(
#endif
}
void cleanup(void)
{
BACNET_READ_ACCESS_DATA *rpm_object;
BACNET_READ_ACCESS_DATA *old_rpm_object;
BACNET_PROPERTY_REFERENCE *rpm_property;
BACNET_PROPERTY_REFERENCE *old_rpm_property;
rpm_object = Read_Access_Data;
old_rpm_object = rpm_object;
while (rpm_object) {
rpm_property = rpm_object->listOfProperties;
while (rpm_property) {
old_rpm_property = rpm_property;
rpm_property = rpm_property->next;
free(old_rpm_property);
}
old_rpm_object = rpm_object;
rpm_object = rpm_object->next;
free(old_rpm_object);
}
}
int main(int argc, char *argv[]) {
BACNET_ADDRESS src = {
0}; /* address where message came from */
uint16_t pdu_len = 0;
unsigned timeout = 100; /* milliseconds */
unsigned max_apdu = 0;
int args_remaining = 0, tag_value_arg = 0, arg_sets = 0;
time_t elapsed_seconds = 0;
time_t last_seconds = 0;
time_t current_seconds = 0;
time_t timeout_seconds = 0;
uint8_t invoke_id = 0;
bool found = false;
uint8_t buffer[MAX_PDU] = {0};
BACNET_READ_ACCESS_DATA *rpm_object;
BACNET_PROPERTY_REFERENCE *rpm_property;
if (argc < 5) {
printf("Usage: %s device-instance object-type object-instance "
"property index [object-type ...]\r\n", filename_remove_path(argv[0]));
"property [index]\r\n", filename_remove_path(argv[0]));
if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) {
printf("device-instance:\r\n"
"BACnet Device Object Instance number that you are\r\n"
@@ -286,94 +261,44 @@ int main(int argc, char *argv[]) {
"be read. If this parameter is missing and the property\r\n"
"is an array, the entire array will be read.\r\n"
"\r\nExample:\r\n"
"If you want read the ALL property in\r\n"
"Device object 123, you would use the following command:\r\n"
"%s 123 8 123 8 -1\r\n"
"If you want read the OPTIONAL property in\r\n"
"Device object 123, you would use the following command:\r\n"
"%s 123 8 123 80 -1\r\n"
"If you want read the REQUIRED property in\r\n"
"Device object 123, you would use the following command:\r\n"
"%s 123 8 123 105 -1\r\n",
filename_remove_path(argv[0]),
filename_remove_path(argv[0]),
"If you want read the Present-Value of Analog Output 101\r\n"
"in Device 123, you could send the following command:\r\n"
"%s 123 1 101 85\r\n"
"If you want read the Priority-Array of Analog Output 101\r\n"
"in Device 123, you could send the following command:\r\n"
"%s 123 1 101 87\r\n", filename_remove_path(argv[0]),
filename_remove_path(argv[0]));
}
return 0;
}
/* decode the command line parameters */
Target_Device_Object_Instance = strtol(argv[1], NULL, 0);
Target_Object_Type = strtol(argv[2], NULL, 0);
Target_Object_Instance = strtol(argv[3], NULL, 0);
Target_Object_Property = strtol(argv[4], NULL, 0);
if (argc > 5)
Target_Object_Index = strtol(argv[5], NULL, 0);
if (Target_Device_Object_Instance >= BACNET_MAX_INSTANCE) {
fprintf(stderr, "device-instance=%u - it must be less than %u\r\n",
Target_Device_Object_Instance, BACNET_MAX_INSTANCE);
return 1;
}
atexit(cleanup);
Read_Access_Data = calloc(1, sizeof(BACNET_READ_ACCESS_DATA));
rpm_object = Read_Access_Data;
args_remaining = (argc - 2);
arg_sets = 0;
while (rpm_object) {
tag_value_arg = 2 + (arg_sets * 4);
rpm_object->object_type =
strtol(argv[tag_value_arg], NULL, 0);
tag_value_arg++;
args_remaining--;
if (args_remaining <= 0) {
fprintf(stderr, "Error: not enough object property quads.\r\n");
return 1;
}
if (rpm_object->object_type > MAX_BACNET_OBJECT_TYPE) {
fprintf(stderr, "object-type=%u - it must be less than %u\r\n",
rpm_object->object_type, MAX_BACNET_OBJECT_TYPE + 1);
return 1;
}
rpm_object->object_instance =
strtol(argv[tag_value_arg], NULL, 0);
tag_value_arg++;
args_remaining--;
if (args_remaining <= 0) {
fprintf(stderr, "Error: not enough object property quads.\r\n");
return 1;
}
if (rpm_object->object_instance > BACNET_MAX_INSTANCE) {
fprintf(stderr, "object-instance=%u - it must be less than %u\r\n",
rpm_object->object_instance, BACNET_MAX_INSTANCE + 1);
return 1;
}
rpm_property = calloc(1, sizeof(BACNET_PROPERTY_REFERENCE));
rpm_object->listOfProperties = rpm_property;
if (rpm_property) {
rpm_property->propertyIdentifier =
strtol(argv[tag_value_arg], NULL, 0);
/* used up another arg */
tag_value_arg++;
args_remaining--;
if (args_remaining <= 0) {
fprintf(stderr, "Error: not enough object property quads.\r\n");
return 1;
}
if (rpm_property->propertyIdentifier > MAX_BACNET_PROPERTY_ID) {
fprintf(stderr, "property=%u - it must be less than %u\r\n",
rpm_property->propertyIdentifier, MAX_BACNET_PROPERTY_ID + 1);
return 1;
}
rpm_property->propertyArrayIndex =
strtol(argv[tag_value_arg], NULL, 0);
/* note: we are only loading one property for now */
rpm_property->next = NULL;
/* used up another arg */
tag_value_arg++;
args_remaining--;
}
if (args_remaining) {
arg_sets++;
rpm_object->next = calloc(1, sizeof(BACNET_READ_ACCESS_DATA));
rpm_object = rpm_object->next;
} else {
break;
}
if (Target_Object_Type > MAX_BACNET_OBJECT_TYPE) {
fprintf(stderr, "object-type=%u - it must be less than %u\r\n",
Target_Object_Type, MAX_BACNET_OBJECT_TYPE + 1);
return 1;
}
if (Target_Object_Instance > BACNET_MAX_INSTANCE) {
fprintf(stderr, "object-instance=%u - it must be less than %u\r\n",
Target_Object_Instance, BACNET_MAX_INSTANCE + 1);
return 1;
}
if (Target_Object_Property > MAX_BACNET_PROPERTY_ID) {
fprintf(stderr, "property=%u - it must be less than %u\r\n",
Target_Object_Property, MAX_BACNET_PROPERTY_ID + 1);
return 1;
}
/* setup my info */
Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
address_init();
@@ -413,11 +338,10 @@ int main(int argc, char *argv[]) {
&Target_Address);
if (found) {
if (invoke_id == 0) {
invoke_id = Send_Read_Property_Multiple_Request(
&buffer[0],
sizeof(buffer),
Target_Device_Object_Instance,
Read_Access_Data);
invoke_id =
Send_Read_Property_Request(Target_Device_Object_Instance,
Target_Object_Type, Target_Object_Instance,
Target_Object_Property, Target_Object_Index);
} else if (tsm_invoke_id_free(invoke_id))
break;
else if (tsm_invoke_id_failed(invoke_id)) {
+3 -3
View File
@@ -11,7 +11,7 @@ BORLAND_DIR_Not_Defined:
@echo You must define environment variable BORLAND_DIR to compile.
!endif
PRODUCT = bacrpm
PRODUCT = bacrp
PRODUCT_EXE = $(PRODUCT).exe
# tools
@@ -26,7 +26,7 @@ BACNET_LIB = $(BACNET_LIB_DIR)\bacnet.lib
# directories
BACNET_PORT = ..\..\ports\win32
BACNET_INCLUDE = ..\..\include
INCLUDES = \
INCLUDES = \
-I$(BACNET_INCLUDE) \
-I$(BACNET_PORT) \
-I$(BORLAND_DIR)\include
@@ -65,7 +65,7 @@ LIBS = $(BACNET_LIB) \
#
# This should be the first one in the makefile
all : $(BACNET_LIB) $(BCC_CFG) $(OBJS) $(PRODUCT_EXE)
all : $(BACNET_LIB) $(BCC_CFG) $(OBJS) $(PRODUCT_EXE)
del $(BCC_CFG)
install: $(PRODUCT_EXE)
+72
View File
@@ -0,0 +1,72 @@
#Makefile to build BACnet Application for the Linux Port
# Compiler to use
CC = gcc
# Executable file name
TARGET = bacrpm
# Configure the BACnet Datalink Layer
#BACDL_DEFINE = -DBACDL_ETHERNET=1
#BACDL_DEFINE = -DBACDL_ARCNET=1
#BACDL_DEFINE = -DBACDL_MSTP=1
BACDL_DEFINE = -DBACDL_BIP=1
BACNET_DEFINES = -DBACFILE=1 -DPRINT_ENABLED=1 -DBACAPP_ALL
DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE)
# Directories
BACNET_PORT = linux
BACNET_PORT_DIR = ../../ports/${BACNET_PORT}
BACNET_INCLUDE = ../../include
# BACnet Library
BACNET_LIB_DIR = ../../lib
BACNET_LIB_NAME = bacnet
BACNET_LIB_TARGET = $(BACNET_LIB_DIR)/lib$(BACNET_LIB_NAME).a
# Compiler Setup
INCLUDES = -I$(BACNET_INCLUDE) -I$(BACNET_PORT_DIR)
ifeq (${BACNET_PORT},linux)
PFLAGS = -pthread
TARGET_BIN = ${TARGET}
LIBRARIES=-lc,-lgcc,-lm,-L=$(BACNET_LIB_DIR),-l$(BACNET_LIB_NAME)
endif
ifeq (${BACNET_PORT},win32)
TARGET_BIN = ${TARGET}.exe
LIBRARY1=-L=$(BACNET_LIB_DIR),-l$(BACNET_LIB_NAME)
LIBRARY2=-lws2_32,-lgcc,-lm,-liphlpapi
LIBRARIES=$(LIBRARY1),$(LIBRARY2)
endif
#build for release (default) or debug
DEBUGGING =
OPTIMIZATION = -Os
ifeq (${BUILD},debug)
OPTIMIZATION = -O0
DEBUGGING = -g
endif
# put all the flags together
CFLAGS = -Wall $(DEBUGGING) $(OPTIMIZATION) $(INCLUDES) $(DEFINES)
LFLAGS = -Wl,-Map=$(TARGET).map,$(LIBRARIES)
SRCS = main.c
OBJS = ${SRCS:.c=.o}
all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN}
size ${TARGET_BIN}
${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET}
${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@
lib: ${BACNET_LIB_TARGET}
${BACNET_LIB_TARGET}:
( cd ${BACNET_LIB_DIR} ; make clean ; make )
.c.o:
${CC} -c ${CFLAGS} $*.c -o $@
depend:
rm -f .depend
${CC} -MM ${CFLAGS} *.c >> .depend
clean:
rm -f core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET}
include: .depend
+446
View File
@@ -0,0 +1,446 @@
/*************************************************************************
* 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 <errno.h>
#include <time.h> /* for time */
#define PRINT_ENABLED 1
#include "bacdef.h"
#include "config.h"
#include "bactext.h"
#include "bacerror.h"
#include "iam.h"
#include "arf.h"
#include "tsm.h"
#include "address.h"
#include "npdu.h"
#include "apdu.h"
#include "device.h"
#include "net.h"
#include "datalink.h"
#include "whois.h"
/* some demo stuff needed */
#include "rpm.h"
#include "filename.h"
#include "handlers.h"
#include "client.h"
#include "txbuf.h"
/* buffer used for receive */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
/* global variables used in this file */
static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE;
static BACNET_READ_ACCESS_DATA *Read_Access_Data;
static BACNET_ADDRESS Target_Address;
static bool Error_Detected = false;
static void MyErrorHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
printf("BACnet Error: %s: %s\r\n",
bactext_error_class_name((int) error_class),
bactext_error_code_name((int) error_code));
Error_Detected = true;
}
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((int) 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((int) 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);
/* handle i-am to support binding to other devices */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_bind);
/* 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 data coming back from confirmed requests */
apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE,
handler_read_property_multiple_ack);
/* handle any errors coming back */
apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, MyErrorHandler);
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
("ReadProperty: 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
}
void cleanup(void)
{
BACNET_READ_ACCESS_DATA *rpm_object;
BACNET_READ_ACCESS_DATA *old_rpm_object;
BACNET_PROPERTY_REFERENCE *rpm_property;
BACNET_PROPERTY_REFERENCE *old_rpm_property;
rpm_object = Read_Access_Data;
old_rpm_object = rpm_object;
while (rpm_object) {
rpm_property = rpm_object->listOfProperties;
while (rpm_property) {
old_rpm_property = rpm_property;
rpm_property = rpm_property->next;
free(old_rpm_property);
}
old_rpm_object = rpm_object;
rpm_object = rpm_object->next;
free(old_rpm_object);
}
}
int main(int argc, char *argv[]) {
BACNET_ADDRESS src = {
0}; /* address where message came from */
uint16_t pdu_len = 0;
unsigned timeout = 100; /* milliseconds */
unsigned max_apdu = 0;
int args_remaining = 0, tag_value_arg = 0, arg_sets = 0;
time_t elapsed_seconds = 0;
time_t last_seconds = 0;
time_t current_seconds = 0;
time_t timeout_seconds = 0;
uint8_t invoke_id = 0;
bool found = false;
uint8_t buffer[MAX_PDU] = {0};
BACNET_READ_ACCESS_DATA *rpm_object;
BACNET_PROPERTY_REFERENCE *rpm_property;
if (argc < 5) {
printf("Usage: %s device-instance object-type object-instance "
"property index [object-type ...]\r\n", filename_remove_path(argv[0]));
if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) {
printf("device-instance:\r\n"
"BACnet Device Object Instance number that you are\r\n"
"trying to communicate to. This number will be used\r\n"
"to try and bind with the device using Who-Is and\r\n"
"I-Am services. For example, if you were reading\r\n"
"Device Object 123, the device-instance would be 123.\r\n"
"\r\nobject-type:\r\n"
"The object type is the integer value of the enumeration\r\n"
"BACNET_OBJECT_TYPE in bacenum.h. It is the object\r\n"
"that you are reading. For example if you were\r\n"
"reading Analog Output 2, the object-type would be 1.\r\n"
"\r\nobject-instance:\r\n"
"This is the object instance number of the object that\r\n"
"you are reading. For example, if you were reading\r\n"
"Analog Output 2, the object-instance would be 2.\r\n"
"\r\nproperty:\r\n"
"The property is an integer value of the enumeration\r\n"
"BACNET_PROPERTY_ID in bacenum.h. It is the property\r\n"
"you are reading. For example, if you were reading the\r\n"
"Present Value property, use 85 as the property.\r\n"
"\r\nindex:\r\n"
"This integer parameter is the index number of an array.\r\n"
"If the property is an array, individual elements can\r\n"
"be read. If this parameter is missing and the property\r\n"
"is an array, the entire array will be read.\r\n"
"\r\nExample:\r\n"
"If you want read the ALL property in\r\n"
"Device object 123, you would use the following command:\r\n"
"%s 123 8 123 8 -1\r\n"
"If you want read the OPTIONAL property in\r\n"
"Device object 123, you would use the following command:\r\n"
"%s 123 8 123 80 -1\r\n"
"If you want read the REQUIRED property in\r\n"
"Device object 123, you would use the following command:\r\n"
"%s 123 8 123 105 -1\r\n",
filename_remove_path(argv[0]),
filename_remove_path(argv[0]),
filename_remove_path(argv[0]));
}
return 0;
}
/* decode the command line parameters */
Target_Device_Object_Instance = strtol(argv[1], NULL, 0);
if (Target_Device_Object_Instance >= BACNET_MAX_INSTANCE) {
fprintf(stderr, "device-instance=%u - it must be less than %u\r\n",
Target_Device_Object_Instance, BACNET_MAX_INSTANCE);
return 1;
}
atexit(cleanup);
Read_Access_Data = calloc(1, sizeof(BACNET_READ_ACCESS_DATA));
rpm_object = Read_Access_Data;
args_remaining = (argc - 2);
arg_sets = 0;
while (rpm_object) {
tag_value_arg = 2 + (arg_sets * 4);
rpm_object->object_type =
strtol(argv[tag_value_arg], NULL, 0);
tag_value_arg++;
args_remaining--;
if (args_remaining <= 0) {
fprintf(stderr, "Error: not enough object property quads.\r\n");
return 1;
}
if (rpm_object->object_type > MAX_BACNET_OBJECT_TYPE) {
fprintf(stderr, "object-type=%u - it must be less than %u\r\n",
rpm_object->object_type, MAX_BACNET_OBJECT_TYPE + 1);
return 1;
}
rpm_object->object_instance =
strtol(argv[tag_value_arg], NULL, 0);
tag_value_arg++;
args_remaining--;
if (args_remaining <= 0) {
fprintf(stderr, "Error: not enough object property quads.\r\n");
return 1;
}
if (rpm_object->object_instance > BACNET_MAX_INSTANCE) {
fprintf(stderr, "object-instance=%u - it must be less than %u\r\n",
rpm_object->object_instance, BACNET_MAX_INSTANCE + 1);
return 1;
}
rpm_property = calloc(1, sizeof(BACNET_PROPERTY_REFERENCE));
rpm_object->listOfProperties = rpm_property;
if (rpm_property) {
rpm_property->propertyIdentifier =
strtol(argv[tag_value_arg], NULL, 0);
/* used up another arg */
tag_value_arg++;
args_remaining--;
if (args_remaining <= 0) {
fprintf(stderr, "Error: not enough object property quads.\r\n");
return 1;
}
if (rpm_property->propertyIdentifier > MAX_BACNET_PROPERTY_ID) {
fprintf(stderr, "property=%u - it must be less than %u\r\n",
rpm_property->propertyIdentifier, MAX_BACNET_PROPERTY_ID + 1);
return 1;
}
rpm_property->propertyArrayIndex =
strtol(argv[tag_value_arg], NULL, 0);
/* note: we are only loading one property for now */
rpm_property->next = NULL;
/* used up another arg */
tag_value_arg++;
args_remaining--;
}
if (args_remaining) {
arg_sets++;
rpm_object->next = calloc(1, sizeof(BACNET_READ_ACCESS_DATA));
rpm_object = rpm_object->next;
} else {
break;
}
}
/* setup my info */
Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
address_init();
Init_Service_Handlers();
Init_DataLink();
/* configure the timeout values */
last_seconds = time(NULL);
timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
/* try to bind with the device */
found =
address_bind_request(Target_Device_Object_Instance, &max_apdu,
&Target_Address);
if (!found) {
Send_WhoIs(Target_Device_Object_Instance,
Target_Device_Object_Instance);
}
/* 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);
}
/* at least one second has passed */
if (current_seconds != last_seconds)
tsm_timer_milliseconds(((current_seconds - last_seconds) * 1000));
if (Error_Detected)
break;
/* wait until the device is bound, or timeout and quit */
found =
address_bind_request(Target_Device_Object_Instance, &max_apdu,
&Target_Address);
if (found) {
if (invoke_id == 0) {
invoke_id = Send_Read_Property_Multiple_Request(
&buffer[0],
sizeof(buffer),
Target_Device_Object_Instance,
Read_Access_Data);
} else if (tsm_invoke_id_free(invoke_id))
break;
else if (tsm_invoke_id_failed(invoke_id)) {
fprintf(stderr, "\rError: TSM Timeout!\r\n");
tsm_free_invoke_id(invoke_id);
Error_Detected = true;
/* try again or abort? */
break;
}
} else {
/* increment timer - exit if timed out */
elapsed_seconds += (current_seconds - last_seconds);
if (elapsed_seconds > timeout_seconds) {
printf("\rError: APDU Timeout!\r\n");
Error_Detected = true;
break;
}
}
/* keep track of time for next check */
last_seconds = current_seconds;
}
if (Error_Detected)
return 1;
return 0;
}
+134
View File
@@ -0,0 +1,134 @@
#
# Simple makefile to build an executable for Win32
#
# This makefile assumes Borland bcc32 development environment
# on Windows NT/9x/2000/XP
#
!ifndef BORLAND_DIR
BORLAND_DIR_Not_Defined:
@echo .
@echo You must define environment variable BORLAND_DIR to compile.
!endif
PRODUCT = bacrpm
PRODUCT_EXE = $(PRODUCT).exe
# tools
CC = $(BORLAND_DIR)\bin\bcc32
MAKE=$(BORLAND_DIR)\bin\make.exe
#LINK = $(BORLAND_DIR)\bin\tlink32
LINK = $(BORLAND_DIR)\bin\ilink32
BACNET_LIB_DIR = ..\..\lib
BACNET_LIB = $(BACNET_LIB_DIR)\bacnet.lib
# directories
BACNET_PORT = ..\..\ports\win32
BACNET_INCLUDE = ..\..\include
INCLUDES = \
-I$(BACNET_INCLUDE) \
-I$(BACNET_PORT) \
-I$(BORLAND_DIR)\include
#
BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL
#BACDL_DEFINE=-DBACDL_MSTP=1
BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1
DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE)
SRCS = main.c
OBJS = $(SRCS:.c=.obj)
#
# Compiler definitions
#
BCC_CFG = bcc32.cfg
#
# Include directories
#
CFLAGS = $(INCLUDES) $(DEFINES)
#
# Libraries
#
C_LIB_DIR = $(BORLAND_DIR)\lib
LIBS = $(BACNET_LIB) \
$(C_LIB_DIR)\IMPORT32.lib \
$(C_LIB_DIR)\CW32MT.lib \
#
# Main target
#
# This should be the first one in the makefile
all : $(BACNET_LIB) $(BCC_CFG) $(OBJS) $(PRODUCT_EXE)
del $(BCC_CFG)
install: $(PRODUCT_EXE)
copy $(PRODUCT_EXE) ..\..\bin\$(PRODUCT_EXE)
# Linker specific: the link below is for BCC linker/compiler. If you link
# with a different linker - please change accordingly.
#
# need a temp response file (@&&| ... |) because command line is too long
# $** lists each dependency
# $< target name
# $* target name without extension
$(PRODUCT_EXE) : $(OBJS)
@echo Running Linker for $(PRODUCT_EXE)
$(LINK) -L$(C_LIB_DIR) -L$(BACNET_LIB_DIR) -m -c -s -v @&&|
$(BORLAND_DIR)\lib\c0x32.obj $**
$<
$*.map
$(LIBS)
|
#
# Utilities
clean :
del $(OBJS)
del $(PRODUCT_EXE)
del $(PRODUCT).map
del $(PRODUCT).ilc
del $(PRODUCT).ild
del $(PRODUCT).ilf
del $(PRODUCT).ils
del $(PRODUCT).tds
del $(BCC_CFG)
#
# Generic rules
#
.SUFFIXES: .cpp .c .sbr .obj
#
# cc generic rule
#
.c.obj:
$(CC) +$(BCC_CFG) -o$@ $<
# Compiler configuration file
$(BCC_CFG) :
Copy &&|
$(CFLAGS)
-c
-y #include line numbers in OBJ's
-v #include debug info
-w+ #turn on all warnings
-Od #disable all optimizations
#-a4 #32 bit data alignment
#-M # generate link map
#-ls # linker options
#-WM- #not multithread
-WM #multithread
-w-aus # ignore warning assigned a value that is never used
-w-sig # ignore warning conversion may lose sig digits
| $@
# EOF: makefile