Added ReadPropertyMultiple client demo bacrpm.

This commit is contained in:
skarg
2008-11-23 22:41:57 +00:00
parent 7921d2f811
commit e3f91b3916
4 changed files with 173 additions and 42 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
# Compiler to use
CC = gcc
# Executable file name
TARGET = bacrp
TARGET = bacrpm
# Configure the BACnet Datalink Layer
#BACDL_DEFINE = -DBACDL_ETHERNET=1
+55
View File
@@ -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>
+114 -38
View 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
* a copy of this software and associated documentation files (the
@@ -47,6 +47,7 @@
#include "datalink.h"
#include "whois.h"
/* some demo stuff needed */
#include "rpm.h"
#include "filename.h"
#include "handlers.h"
#include "client.h"
@@ -57,10 +58,7 @@ 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 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_READ_ACCESS_DATA *Read_Access_Data;
static BACNET_ADDRESS Target_Address;
static bool Error_Detected = false;
@@ -124,8 +122,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_PROPERTY,
handler_read_property_ack);
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);
@@ -218,22 +216,49 @@ 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]\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)) {
printf("device-instance:\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"
"is an array, the entire array will be read.\r\n"
"\r\nExample:\r\n"
"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]),
"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);
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;
}
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;
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_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();
@@ -338,10 +413,11 @@ int main(int argc, char *argv[]) {
&Target_Address);
if (found) {
if (invoke_id == 0) {
invoke_id =
Send_Read_Property_Request(Target_Device_Object_Instance,
Target_Object_Type, Target_Object_Instance,
Target_Object_Property, Target_Object_Index);
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)) {
+3 -3
View File
@@ -11,7 +11,7 @@ BORLAND_DIR_Not_Defined:
@echo You must define environment variable BORLAND_DIR to compile.
!endif
PRODUCT = bacrp
PRODUCT = bacrpm
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)