Added ReadPropertyMultiple client demo bacrpm.
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
# Compiler to use
|
# Compiler to use
|
||||||
CC = gcc
|
CC = gcc
|
||||||
# Executable file name
|
# Executable file name
|
||||||
TARGET = bacrp
|
TARGET = bacrpm
|
||||||
|
|
||||||
# Configure the BACnet Datalink Layer
|
# Configure the BACnet Datalink Layer
|
||||||
#BACDL_DEFINE = -DBACDL_ETHERNET=1
|
#BACDL_DEFINE = -DBACDL_ETHERNET=1
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||||
|
<CodeBlocks_project_file>
|
||||||
|
<FileVersion major="1" minor="6" />
|
||||||
|
<Project>
|
||||||
|
<Option title="BACnet ReadProperty Demo" />
|
||||||
|
<Option pch_mode="2" />
|
||||||
|
<Option compiler="gcc" />
|
||||||
|
<Build>
|
||||||
|
<Target title="Debug">
|
||||||
|
<Option output="bin\Debug\bacrpm" prefix_auto="1" extension_auto="1" />
|
||||||
|
<Option object_output="obj\Debug\" />
|
||||||
|
<Option type="1" />
|
||||||
|
<Option compiler="gcc" />
|
||||||
|
<Compiler>
|
||||||
|
<Add option="-g" />
|
||||||
|
</Compiler>
|
||||||
|
</Target>
|
||||||
|
<Target title="Release">
|
||||||
|
<Option output="bin\Release\bacrpm" prefix_auto="1" extension_auto="1" />
|
||||||
|
<Option object_output="obj\Release\" />
|
||||||
|
<Option type="1" />
|
||||||
|
<Option compiler="gcc" />
|
||||||
|
<Compiler>
|
||||||
|
<Add option="-O2" />
|
||||||
|
</Compiler>
|
||||||
|
<Linker>
|
||||||
|
<Add option="-s" />
|
||||||
|
</Linker>
|
||||||
|
</Target>
|
||||||
|
</Build>
|
||||||
|
<Compiler>
|
||||||
|
<Add option="-Wall" />
|
||||||
|
<Add option="-DBACDL_BIP" />
|
||||||
|
<Add option="-DPRINT_ENABLED=1" />
|
||||||
|
<Add option="-DBACAPP_ALL" />
|
||||||
|
<Add directory="..\..\include" />
|
||||||
|
<Add directory="..\handler" />
|
||||||
|
<Add directory="..\object" />
|
||||||
|
<Add directory="..\..\ports\win32" />
|
||||||
|
</Compiler>
|
||||||
|
<Linker>
|
||||||
|
<Add library="..\..\lib\libbacnet.a" />
|
||||||
|
<Add library="ws2_32" />
|
||||||
|
<Add library="iphlpapi" />
|
||||||
|
</Linker>
|
||||||
|
<Unit filename="main.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Extensions>
|
||||||
|
<code_completion />
|
||||||
|
<envvars />
|
||||||
|
<debugger />
|
||||||
|
</Extensions>
|
||||||
|
</Project>
|
||||||
|
</CodeBlocks_project_file>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Copyright (C) 2006 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
|
||||||
@@ -47,6 +47,7 @@
|
|||||||
#include "datalink.h"
|
#include "datalink.h"
|
||||||
#include "whois.h"
|
#include "whois.h"
|
||||||
/* some demo stuff needed */
|
/* some demo stuff needed */
|
||||||
|
#include "rpm.h"
|
||||||
#include "filename.h"
|
#include "filename.h"
|
||||||
#include "handlers.h"
|
#include "handlers.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
@@ -57,10 +58,7 @@ static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
|
|||||||
|
|
||||||
/* global variables used in this file */
|
/* global variables used in this file */
|
||||||
static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE;
|
static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE;
|
||||||
static uint32_t Target_Object_Instance = BACNET_MAX_INSTANCE;
|
static BACNET_READ_ACCESS_DATA *Read_Access_Data;
|
||||||
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 BACNET_ADDRESS Target_Address;
|
||||||
static bool Error_Detected = false;
|
static bool Error_Detected = false;
|
||||||
@@ -124,8 +122,8 @@ static void Init_Service_Handlers(
|
|||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
||||||
handler_read_property);
|
handler_read_property);
|
||||||
/* handle the data coming back from confirmed requests */
|
/* handle the data coming back from confirmed requests */
|
||||||
apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE,
|
||||||
handler_read_property_ack);
|
handler_read_property_multiple_ack);
|
||||||
/* handle any errors coming back */
|
/* handle any errors coming back */
|
||||||
apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, MyErrorHandler);
|
apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, MyErrorHandler);
|
||||||
apdu_set_abort_handler(MyAbortHandler);
|
apdu_set_abort_handler(MyAbortHandler);
|
||||||
@@ -218,22 +216,49 @@ static void Init_DataLink(
|
|||||||
#endif
|
#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[]) {
|
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 */
|
||||||
unsigned max_apdu = 0;
|
unsigned max_apdu = 0;
|
||||||
|
int args_remaining = 0, tag_value_arg = 0, arg_sets = 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;
|
||||||
uint8_t invoke_id = 0;
|
uint8_t invoke_id = 0;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
uint8_t buffer[MAX_PDU] = {0};
|
||||||
|
BACNET_READ_ACCESS_DATA *rpm_object;
|
||||||
|
BACNET_PROPERTY_REFERENCE *rpm_property;
|
||||||
|
|
||||||
|
|
||||||
if (argc < 5) {
|
if (argc < 5) {
|
||||||
printf("Usage: %s device-instance object-type object-instance "
|
printf("Usage: %s device-instance object-type object-instance "
|
||||||
"property [index]\r\n", filename_remove_path(argv[0]));
|
"property index [object-type ...]\r\n", filename_remove_path(argv[0]));
|
||||||
if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) {
|
if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) {
|
||||||
printf("device-instance:\r\n"
|
printf("device-instance:\r\n"
|
||||||
"BACnet Device Object Instance number that you are\r\n"
|
"BACnet Device Object Instance number that you are\r\n"
|
||||||
@@ -261,44 +286,94 @@ int main(int argc, char *argv[]) {
|
|||||||
"be read. If this parameter is missing and the property\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"
|
"is an array, the entire array will be read.\r\n"
|
||||||
"\r\nExample:\r\n"
|
"\r\nExample:\r\n"
|
||||||
"If you want read the Present-Value of Analog Output 101\r\n"
|
"If you want read the ALL property in\r\n"
|
||||||
"in Device 123, you could send the following command:\r\n"
|
"Device object 123, you would use the following command:\r\n"
|
||||||
"%s 123 1 101 85\r\n"
|
"%s 123 8 123 8 -1\r\n"
|
||||||
"If you want read the Priority-Array of Analog Output 101\r\n"
|
"If you want read the OPTIONAL property in\r\n"
|
||||||
"in Device 123, you could send the following command:\r\n"
|
"Device object 123, you would use the following command:\r\n"
|
||||||
"%s 123 1 101 87\r\n", filename_remove_path(argv[0]),
|
"%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]));
|
filename_remove_path(argv[0]));
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* decode the command line parameters */
|
/* decode the command line parameters */
|
||||||
Target_Device_Object_Instance = strtol(argv[1], NULL, 0);
|
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) {
|
if (Target_Device_Object_Instance >= BACNET_MAX_INSTANCE) {
|
||||||
fprintf(stderr, "device-instance=%u - it must be less than %u\r\n",
|
fprintf(stderr, "device-instance=%u - it must be less than %u\r\n",
|
||||||
Target_Device_Object_Instance, BACNET_MAX_INSTANCE);
|
Target_Device_Object_Instance, BACNET_MAX_INSTANCE);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (Target_Object_Type > MAX_BACNET_OBJECT_TYPE) {
|
atexit(cleanup);
|
||||||
fprintf(stderr, "object-type=%u - it must be less than %u\r\n",
|
Read_Access_Data = calloc(1, sizeof(BACNET_READ_ACCESS_DATA));
|
||||||
Target_Object_Type, MAX_BACNET_OBJECT_TYPE + 1);
|
rpm_object = Read_Access_Data;
|
||||||
return 1;
|
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_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 */
|
/* setup my info */
|
||||||
Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
|
Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
|
||||||
address_init();
|
address_init();
|
||||||
@@ -338,10 +413,11 @@ int main(int argc, char *argv[]) {
|
|||||||
&Target_Address);
|
&Target_Address);
|
||||||
if (found) {
|
if (found) {
|
||||||
if (invoke_id == 0) {
|
if (invoke_id == 0) {
|
||||||
invoke_id =
|
invoke_id = Send_Read_Property_Multiple_Request(
|
||||||
Send_Read_Property_Request(Target_Device_Object_Instance,
|
&buffer[0],
|
||||||
Target_Object_Type, Target_Object_Instance,
|
sizeof(buffer),
|
||||||
Target_Object_Property, Target_Object_Index);
|
Target_Device_Object_Instance,
|
||||||
|
Read_Access_Data);
|
||||||
} else if (tsm_invoke_id_free(invoke_id))
|
} else if (tsm_invoke_id_free(invoke_id))
|
||||||
break;
|
break;
|
||||||
else if (tsm_invoke_id_failed(invoke_id)) {
|
else if (tsm_invoke_id_failed(invoke_id)) {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ BORLAND_DIR_Not_Defined:
|
|||||||
@echo You must define environment variable BORLAND_DIR to compile.
|
@echo You must define environment variable BORLAND_DIR to compile.
|
||||||
!endif
|
!endif
|
||||||
|
|
||||||
PRODUCT = bacrp
|
PRODUCT = bacrpm
|
||||||
PRODUCT_EXE = $(PRODUCT).exe
|
PRODUCT_EXE = $(PRODUCT).exe
|
||||||
|
|
||||||
# tools
|
# tools
|
||||||
@@ -26,7 +26,7 @@ BACNET_LIB = $(BACNET_LIB_DIR)\bacnet.lib
|
|||||||
# directories
|
# directories
|
||||||
BACNET_PORT = ..\..\ports\win32
|
BACNET_PORT = ..\..\ports\win32
|
||||||
BACNET_INCLUDE = ..\..\include
|
BACNET_INCLUDE = ..\..\include
|
||||||
INCLUDES = \
|
INCLUDES = \
|
||||||
-I$(BACNET_INCLUDE) \
|
-I$(BACNET_INCLUDE) \
|
||||||
-I$(BACNET_PORT) \
|
-I$(BACNET_PORT) \
|
||||||
-I$(BORLAND_DIR)\include
|
-I$(BORLAND_DIR)\include
|
||||||
@@ -65,7 +65,7 @@ LIBS = $(BACNET_LIB) \
|
|||||||
#
|
#
|
||||||
# This should be the first one in the makefile
|
# 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)
|
del $(BCC_CFG)
|
||||||
|
|
||||||
install: $(PRODUCT_EXE)
|
install: $(PRODUCT_EXE)
|
||||||
|
|||||||
Reference in New Issue
Block a user