diff --git a/bacnet-stack/demo/dcc/Makefile b/bacnet-stack/demo/dcc/Makefile index a8fc1a32..12e98747 100644 --- a/bacnet-stack/demo/dcc/Makefile +++ b/bacnet-stack/demo/dcc/Makefile @@ -35,8 +35,10 @@ SRCS = main.c \ $(BACNET_OBJECT)/device.c \ $(BACNET_OBJECT)/ai.c \ $(BACNET_OBJECT)/ao.c \ + $(BACNET_OBJECT)/av.c \ $(BACNET_OBJECT)/bi.c \ $(BACNET_OBJECT)/bo.c \ + $(BACNET_OBJECT)/bv.c \ $(BACNET_OBJECT)/lsp.c \ $(BACNET_OBJECT)/bacfile.c \ $(BACNET_ROOT)/filename.c \ diff --git a/bacnet-stack/demo/dcc/makefile.b32 b/bacnet-stack/demo/dcc/makefile.b32 index 79da85d4..fdf11805 100644 --- a/bacnet-stack/demo/dcc/makefile.b32 +++ b/bacnet-stack/demo/dcc/makefile.b32 @@ -46,8 +46,10 @@ SRCS = main.c \ ..\..\demo\object\device.c \ ..\..\demo\object\ai.c \ ..\..\demo\object\ao.c \ + ..\..\demo\object\av.c \ ..\..\demo\object\bi.c \ ..\..\demo\object\bo.c \ + ..\..\demo\object\bv.c \ ..\..\demo\object\lsp.c \ ..\..\datalink.c \ ..\..\tsm.c \ diff --git a/bacnet-stack/demo/object/av.c b/bacnet-stack/demo/object/av.c new file mode 100644 index 00000000..191f7c56 --- /dev/null +++ b/bacnet-stack/demo/object/av.c @@ -0,0 +1,416 @@ +/************************************************************************** +* +* Copyright (C) 2006 Steve Karg +* +* 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. +* +*********************************************************************/ + +/* Analog Value Objects - customize for your use */ + +#include +#include +#include +#include "bacdef.h" +#include "bacdcode.h" +#include "bacenum.h" +#include "config.h" /* the custom stuff */ +#include "wp.h" + +#define MAX_ANALOG_VALUES 4 + +/* we choose to have a NULL level in our system represented by */ +/* a particular value. When the priorities are not in use, they */ +/* will be relinquished (i.e. set to the NULL level). */ +#define ANALOG_LEVEL_NULL 255 +/* When all the priorities are level null, the present value returns */ +/* the Relinquish Default value */ +#define ANALOG_RELINQUISH_DEFAULT 0 +/* Here is our Priority Array. They are supposed to be Real, but */ +/* we don't have that kind of memory, so we will use a single byte */ +/* and load a Real for returning the value when asked. */ +static uint8_t + Analog_Value_Level[MAX_ANALOG_VALUES][BACNET_MAX_PRIORITY]; +/* Writable out-of-service allows others to play with our Present Value */ +/* without changing the physical output */ +static bool Analog_Value_Out_Of_Service[MAX_ANALOG_VALUES]; + +/* we need to have our arrays initialized before answering any calls */ +static bool Analog_Value_Initialized = false; + +void Analog_Value_Init(void) +{ + unsigned i, j; + + if (!Analog_Value_Initialized) { + Analog_Value_Initialized = true; + + /* initialize all the analog output priority arrays to NULL */ + for (i = 0; i < MAX_ANALOG_VALUES; i++) { + for (j = 0; j < BACNET_MAX_PRIORITY; j++) { + Analog_Value_Level[i][j] = ANALOG_LEVEL_NULL; + } + } + } + + return; +} + +/* we simply have 0-n object instances. Yours might be */ +/* more complex, and then you need validate that the */ +/* given instance exists */ +bool Analog_Value_Valid_Instance(uint32_t object_instance) +{ + Analog_Value_Init(); + if (object_instance < MAX_ANALOG_VALUES) + return true; + + return false; +} + +/* we simply have 0-n object instances. Yours might be */ +/* more complex, and then count how many you have */ +unsigned Analog_Value_Count(void) +{ + Analog_Value_Init(); + return MAX_ANALOG_VALUES; +} + +/* we simply have 0-n object instances. Yours might be */ +/* more complex, and then you need to return the instance */ +/* that correlates to the correct index */ +uint32_t Analog_Value_Index_To_Instance(unsigned index) +{ + Analog_Value_Init(); + return index; +} + +/* we simply have 0-n object instances. Yours might be */ +/* more complex, and then you need to return the index */ +/* that correlates to the correct instance number */ +unsigned Analog_Value_Instance_To_Index(uint32_t object_instance) +{ + unsigned index = MAX_ANALOG_VALUES; + + Analog_Value_Init(); + if (object_instance < MAX_ANALOG_VALUES) + index = object_instance; + + return index; +} + +static float Analog_Value_Present_Value(uint32_t object_instance) +{ + float value = ANALOG_RELINQUISH_DEFAULT; + unsigned index = 0; + unsigned i = 0; + + Analog_Value_Init(); + index = Analog_Value_Instance_To_Index(object_instance); + if (index < MAX_ANALOG_VALUES) { + for (i = 0; i < BACNET_MAX_PRIORITY; i++) { + if (Analog_Value_Level[index][i] != ANALOG_LEVEL_NULL) { + value = Analog_Value_Level[index][i]; + break; + } + } + } + + return value; +} + +/* note: the object name must be unique within this device */ +char *Analog_Value_Name(uint32_t object_instance) +{ + static char text_string[32] = ""; /* okay for single thread */ + + if (object_instance < MAX_ANALOG_VALUES) { + sprintf(text_string, "ANALOG VALUE %u", object_instance); + return text_string; + } + + return NULL; +} + +/* return apdu len, or -1 on error */ +int Analog_Value_Encode_Property_APDU(uint8_t * apdu, + uint32_t object_instance, + BACNET_PROPERTY_ID property, + int32_t array_index, + BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code) +{ + int len = 0; + int apdu_len = 0; /* return value */ + BACNET_BIT_STRING bit_string; + BACNET_CHARACTER_STRING char_string; + float real_value = 1.414; + unsigned object_index = 0; + unsigned i = 0; + bool state = false; + + Analog_Value_Init(); + switch (property) { + case PROP_OBJECT_IDENTIFIER: + apdu_len = encode_tagged_object_id(&apdu[0], OBJECT_ANALOG_VALUE, + object_instance); + break; + case PROP_OBJECT_NAME: + case PROP_DESCRIPTION: + characterstring_init_ansi(&char_string, + Analog_Value_Name(object_instance)); + apdu_len = encode_tagged_character_string(&apdu[0], &char_string); + break; + case PROP_OBJECT_TYPE: + apdu_len = + encode_tagged_enumerated(&apdu[0], OBJECT_ANALOG_VALUE); + break; + case PROP_PRESENT_VALUE: + real_value = Analog_Value_Present_Value(object_instance); + apdu_len = encode_tagged_real(&apdu[0], real_value); + break; + case PROP_STATUS_FLAGS: + bitstring_init(&bit_string); + bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false); + bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false); + bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false); + bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false); + apdu_len = encode_tagged_bitstring(&apdu[0], &bit_string); + break; + case PROP_EVENT_STATE: + apdu_len = encode_tagged_enumerated(&apdu[0], EVENT_STATE_NORMAL); + break; + case PROP_OUT_OF_SERVICE: + object_index = Analog_Value_Instance_To_Index(object_instance); + state = Analog_Value_Out_Of_Service[object_index]; + apdu_len = encode_tagged_boolean(&apdu[0], state); + break; + case PROP_UNITS: + apdu_len = encode_tagged_enumerated(&apdu[0], UNITS_PERCENT); + break; + case PROP_PRIORITY_ARRAY: + /* Array element zero is the number of elements in the array */ + if (array_index == BACNET_ARRAY_LENGTH_INDEX) + apdu_len = + encode_tagged_unsigned(&apdu[0], BACNET_MAX_PRIORITY); + /* if no index was specified, then try to encode the entire list */ + /* into one packet. */ + else if (array_index == BACNET_ARRAY_ALL) { + object_index = + Analog_Value_Instance_To_Index(object_instance); + for (i = 0; i < BACNET_MAX_PRIORITY; i++) { + /* FIXME: check if we have room before adding it to APDU */ + if (Analog_Value_Level[object_index][i] == ANALOG_LEVEL_NULL) + len = encode_tagged_null(&apdu[apdu_len]); + else { + real_value = Analog_Value_Level[object_index][i]; + len = encode_tagged_real(&apdu[apdu_len], real_value); + } + /* add it if we have room */ + if ((apdu_len + len) < MAX_APDU) + apdu_len += len; + else { + *error_class = ERROR_CLASS_SERVICES; + *error_code = ERROR_CODE_NO_SPACE_FOR_OBJECT; + apdu_len = -1; + break; + } + } + } else { + object_index = + Analog_Value_Instance_To_Index(object_instance); + if (array_index <= BACNET_MAX_PRIORITY) { + if (Analog_Value_Level[object_index][array_index] == + ANALOG_LEVEL_NULL) + len = encode_tagged_null(&apdu[apdu_len]); + else { + real_value = + Analog_Value_Level[object_index][array_index]; + len = encode_tagged_real(&apdu[apdu_len], real_value); + } + } else { + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_INVALID_ARRAY_INDEX; + apdu_len = -1; + } + } + + break; + case PROP_RELINQUISH_DEFAULT: + real_value = ANALOG_RELINQUISH_DEFAULT; + apdu_len = encode_tagged_real(&apdu[0], real_value); + break; + default: + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_UNKNOWN_PROPERTY; + apdu_len = -1; + break; + } + + return apdu_len; +} + +/* returns true if successful */ +bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data, + BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code) +{ + bool status = false; /* return value */ + unsigned int object_index = 0; + unsigned int priority = 0; + uint8_t level = ANALOG_LEVEL_NULL; + + Analog_Value_Init(); + if (!Analog_Value_Valid_Instance(wp_data->object_instance)) { + *error_class = ERROR_CLASS_OBJECT; + *error_code = ERROR_CODE_UNKNOWN_OBJECT; + return false; + } + /* decode the some of the request */ + switch (wp_data->object_property) { + case PROP_PRESENT_VALUE: + if (wp_data->value.tag == BACNET_APPLICATION_TAG_REAL) { + priority = wp_data->priority; + /* Command priority 6 is reserved for use by Minimum On/Off + algorithm and may not be used for other purposes in any + object. */ + if (priority && (priority <= BACNET_MAX_PRIORITY) && + (priority != 6 /* reserved */ ) && + (wp_data->value.type.Real >= 0.0) && + (wp_data->value.type.Real <= 100.0)) { + level = (uint8_t) wp_data->value.type.Real; + object_index = + Analog_Value_Instance_To_Index(wp_data-> + object_instance); + priority--; + Analog_Value_Level[object_index][priority] = level; + /* Note: you could set the physical output here if we + are the highest priority. + However, if Out of Service is TRUE, then don't set the + physical output. This comment may apply to the + main loop (i.e. check out of service before changing output) */ + status = true; + } else if (priority == 6) { + /* Command priority 6 is reserved for use by Minimum On/Off + algorithm and may not be used for other purposes in any + object. */ + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_WRITE_ACCESS_DENIED; + } else { + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; + } + } else if (wp_data->value.tag == BACNET_APPLICATION_TAG_NULL) { + level = ANALOG_LEVEL_NULL; + object_index = + Analog_Value_Instance_To_Index(wp_data->object_instance); + priority = wp_data->priority; + if (priority && (priority <= BACNET_MAX_PRIORITY)) { + priority--; + Analog_Value_Level[object_index][priority] = level; + /* Note: you could set the physical output here to the next + highest priority, or to the relinquish default if no + priorities are set. + However, if Out of Service is TRUE, then don't set the + physical output. This comment may apply to the + main loop (i.e. check out of service before changing output) */ + status = true; + } else { + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; + } + } else { + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_INVALID_DATA_TYPE; + } + break; + case PROP_OUT_OF_SERVICE: + if (wp_data->value.tag == BACNET_APPLICATION_TAG_BOOLEAN) { + object_index = + Analog_Value_Instance_To_Index(wp_data->object_instance); + Analog_Value_Out_Of_Service[object_index] = + wp_data->value.type.Boolean; + status = true; + } else { + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_INVALID_DATA_TYPE; + } + break; + default: + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_WRITE_ACCESS_DENIED; + break; + } + + return status; +} + + +#ifdef TEST +#include +#include +#include "ctest.h" + +void testAnalog_Value(Test * pTest) +{ + uint8_t apdu[MAX_APDU] = { 0 }; + int len = 0; + uint32_t len_value = 0; + uint8_t tag_number = 0; + BACNET_OBJECT_TYPE decoded_type = OBJECT_ANALOG_VALUE; + uint32_t decoded_instance = 0; + uint32_t instance = 123; + BACNET_ERROR_CLASS error_class; + BACNET_ERROR_CODE error_code; + + + len = Analog_Value_Encode_Property_APDU(&apdu[0], + instance, + PROP_OBJECT_IDENTIFIER, + BACNET_ARRAY_ALL, &error_class, &error_code); + ct_test(pTest, len != 0); + len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value); + ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID); + len = decode_object_id(&apdu[len], + (int *) &decoded_type, &decoded_instance); + ct_test(pTest, decoded_type == OBJECT_ANALOG_VALUE); + ct_test(pTest, decoded_instance == instance); + + return; +} + +#ifdef TEST_ANALOG_VALUE +int main(void) +{ + Test *pTest; + bool rc; + + pTest = ct_create("BACnet Analog Value", NULL); + /* individual tests */ + rc = ct_addTestFunction(pTest, testAnalog_Value); + assert(rc); + + ct_setStream(pTest, stdout); + ct_run(pTest); + (void) ct_report(pTest); + ct_destroy(pTest); + + return 0; +} +#endif /* TEST_ANALOG_VALUE*/ +#endif /* TEST */ diff --git a/bacnet-stack/demo/object/av.h b/bacnet-stack/demo/object/av.h new file mode 100644 index 00000000..d89a52d1 --- /dev/null +++ b/bacnet-stack/demo/object/av.h @@ -0,0 +1,60 @@ +/************************************************************************** +* +* Copyright (C) 2006 Steve Karg +* +* 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. +* +*********************************************************************/ +#ifndef AV_H +#define AV_H + +#include +#include +#include "bacdef.h" +#include "bacerror.h" +#include "wp.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + bool Analog_Value_Valid_Instance(uint32_t object_instance); + unsigned Analog_Value_Count(void); + uint32_t Analog_Value_Index_To_Instance(unsigned index); + char *Analog_Value_Name(uint32_t object_instance); + + int Analog_Value_Encode_Property_APDU(uint8_t * apdu, + uint32_t object_instance, + BACNET_PROPERTY_ID property, + int32_t array_index, + BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code); + + bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data, + BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code); + +#ifdef TEST +#include "ctest.h" + void testAnalog_Value(Test * pTest); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/bacnet-stack/demo/object/av.mak b/bacnet-stack/demo/object/av.mak new file mode 100644 index 00000000..4d2b2997 --- /dev/null +++ b/bacnet-stack/demo/object/av.mak @@ -0,0 +1,35 @@ +#Makefile to build test case +CC = gcc +BASEDIR = . +#CFLAGS = -Wall -I. +# -g for debugging with gdb +#CFLAGS = -Wall -I. -g +CFLAGS = -Wall -I. -Itest -DTEST -DTEST_ANALOG_VALUE -g + +# NOTE: this file is normally called by the unittest.sh from up directory +SRCS = bacdcode.c \ + bacstr.c \ + bigend.c \ + demo/object/av.c \ + test/ctest.c + +OBJS = ${SRCS:.c=.o} + +TARGET = analog_value + +all: ${TARGET} + +${TARGET}: ${OBJS} + ${CC} -o $@ ${OBJS} + +.c.o: + ${CC} -c ${CFLAGS} $*.c -o $@ + +depend: + rm -f .depend + ${CC} -MM ${CFLAGS} *.c >> .depend + +clean: + rm -rf core ${TARGET} $(OBJS) *.bak *.1 *.ini + +include: .depend diff --git a/bacnet-stack/demo/object/bv.c b/bacnet-stack/demo/object/bv.c new file mode 100644 index 00000000..f3d8b42c --- /dev/null +++ b/bacnet-stack/demo/object/bv.c @@ -0,0 +1,414 @@ +/************************************************************************** +* +* Copyright (C) 2006 Steve Karg +* +* 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. +* +*********************************************************************/ + +/* Binary Output Objects - customize for your use */ + +#include +#include +#include +#include "bacdef.h" +#include "bacdcode.h" +#include "bacenum.h" +#include "config.h" /* the custom stuff */ +#include "wp.h" + +#define MAX_BINARY_VALUES 2 + +/* When all the priorities are level null, the present value returns */ +/* the Relinquish Default value */ +#define RELINQUISH_DEFAULT BINARY_INACTIVE +/* Here is our Priority Array.*/ +static BACNET_BINARY_PV + Binary_Value_Level[MAX_BINARY_VALUES][BACNET_MAX_PRIORITY]; +/* Writable out-of-service allows others to play with our Present Value */ +/* without changing the physical output */ +static bool Binary_Value_Out_Of_Service[MAX_BINARY_VALUES]; + +void Binary_Value_Init(void) +{ + unsigned i, j; + static bool initialized = false; + + if (!initialized) { + initialized = true; + + /* initialize all the analog output priority arrays to NULL */ + for (i = 0; i < MAX_BINARY_VALUES; i++) { + for (j = 0; j < BACNET_MAX_PRIORITY; j++) { + Binary_Value_Level[i][j] = BINARY_NULL; + } + } + } + + return; +} + +/* we simply have 0-n object instances. Yours might be */ +/* more complex, and then you need validate that the */ +/* given instance exists */ +bool Binary_Value_Valid_Instance(uint32_t object_instance) +{ + if (object_instance < MAX_BINARY_VALUES) + return true; + + return false; +} + +/* we simply have 0-n object instances. Yours might be */ +/* more complex, and then count how many you have */ +unsigned Binary_Value_Count(void) +{ + return MAX_BINARY_VALUES; +} + +/* we simply have 0-n object instances. Yours might be */ +/* more complex, and then you need to return the instance */ +/* that correlates to the correct index */ +uint32_t Binary_Value_Index_To_Instance(unsigned index) +{ + return index; +} + +/* we simply have 0-n object instances. Yours might be */ +/* more complex, and then you need to return the index */ +/* that correlates to the correct instance number */ +unsigned Binary_Value_Instance_To_Index(uint32_t object_instance) +{ + unsigned index = MAX_BINARY_VALUES; + + if (object_instance < MAX_BINARY_VALUES) + index = object_instance; + + return index; +} + +static BACNET_BINARY_PV Binary_Value_Present_Value(uint32_t + object_instance) +{ + BACNET_BINARY_PV value = RELINQUISH_DEFAULT; + unsigned index = 0; + unsigned i = 0; + + Binary_Value_Init(); + index = Binary_Value_Instance_To_Index(object_instance); + if (index < MAX_BINARY_VALUES) { + for (i = 0; i < BACNET_MAX_PRIORITY; i++) { + if (Binary_Value_Level[index][i] != BINARY_NULL) { + value = Binary_Value_Level[index][i]; + break; + } + } + } + + return value; +} + +/* note: the object name must be unique within this device */ +char *Binary_Value_Name(uint32_t object_instance) +{ + static char text_string[32] = ""; /* okay for single thread */ + + if (object_instance < MAX_BINARY_VALUES) { + sprintf(text_string, "BINARY VALUE %u", object_instance); + return text_string; + } + + return NULL; +} + +/* return apdu len, or -1 on error */ +int Binary_Value_Encode_Property_APDU(uint8_t * apdu, + uint32_t object_instance, + BACNET_PROPERTY_ID property, + int32_t array_index, + BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code) +{ + int len = 0; + int apdu_len = 0; /* return value */ + BACNET_BIT_STRING bit_string; + BACNET_CHARACTER_STRING char_string; + BACNET_BINARY_PV present_value = BINARY_INACTIVE; + BACNET_POLARITY polarity = POLARITY_NORMAL; + unsigned object_index = 0; + unsigned i = 0; + bool state = false; + + Binary_Value_Init(); + switch (property) { + case PROP_OBJECT_IDENTIFIER: + apdu_len = encode_tagged_object_id(&apdu[0], OBJECT_BINARY_VALUE, + object_instance); + break; + /* note: Name and Description don't have to be the same. + You could make Description writable and different */ + case PROP_OBJECT_NAME: + case PROP_DESCRIPTION: + characterstring_init_ansi(&char_string, + Binary_Value_Name(object_instance)); + apdu_len = encode_tagged_character_string(&apdu[0], &char_string); + break; + case PROP_OBJECT_TYPE: + apdu_len = + encode_tagged_enumerated(&apdu[0], OBJECT_BINARY_VALUE); + break; + case PROP_PRESENT_VALUE: + present_value = Binary_Value_Present_Value(object_instance); + apdu_len = encode_tagged_enumerated(&apdu[0], present_value); + break; + case PROP_STATUS_FLAGS: + /* note: see the details in the standard on how to use these */ + bitstring_init(&bit_string); + bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false); + bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false); + bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false); + bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false); + apdu_len = encode_tagged_bitstring(&apdu[0], &bit_string); + break; + case PROP_EVENT_STATE: + /* note: see the details in the standard on how to use this */ + apdu_len = encode_tagged_enumerated(&apdu[0], EVENT_STATE_NORMAL); + break; + case PROP_OUT_OF_SERVICE: + object_index = Binary_Value_Instance_To_Index(object_instance); + state = Binary_Value_Out_Of_Service[object_index]; + apdu_len = encode_tagged_boolean(&apdu[0], state); + break; + case PROP_POLARITY: + apdu_len = encode_tagged_enumerated(&apdu[0], polarity); + break; + case PROP_PRIORITY_ARRAY: + /* Array element zero is the number of elements in the array */ + if (array_index == BACNET_ARRAY_LENGTH_INDEX) + apdu_len = + encode_tagged_unsigned(&apdu[0], BACNET_MAX_PRIORITY); + /* if no index was specified, then try to encode the entire list */ + /* into one packet. */ + else if (array_index == BACNET_ARRAY_ALL) { + object_index = + Binary_Value_Instance_To_Index(object_instance); + for (i = 0; i < BACNET_MAX_PRIORITY; i++) { + /* FIXME: check if we have room before adding it to APDU */ + if (Binary_Value_Level[object_index][i] == BINARY_NULL) + len = encode_tagged_null(&apdu[apdu_len]); + else { + present_value = Binary_Value_Level[object_index][i]; + len = + encode_tagged_enumerated(&apdu[apdu_len], + present_value); + } + /* add it if we have room */ + if ((apdu_len + len) < MAX_APDU) + apdu_len += len; + else { + *error_class = ERROR_CLASS_SERVICES; + *error_code = ERROR_CODE_NO_SPACE_FOR_OBJECT; + apdu_len = -1; + break; + } + } + } else { + object_index = + Binary_Value_Instance_To_Index(object_instance); + if (array_index <= BACNET_MAX_PRIORITY) { + if (Binary_Value_Level[object_index][array_index] == + BINARY_NULL) + len = encode_tagged_null(&apdu[apdu_len]); + else { + present_value = + Binary_Value_Level[object_index][array_index]; + len = + encode_tagged_enumerated(&apdu[apdu_len], + present_value); + } + } else { + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_INVALID_ARRAY_INDEX; + apdu_len = -1; + } + } + + break; + case PROP_RELINQUISH_DEFAULT: + present_value = RELINQUISH_DEFAULT; + apdu_len = encode_tagged_enumerated(&apdu[0], present_value); + break; + default: + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_UNKNOWN_PROPERTY; + apdu_len = -1; + break; + } + + return apdu_len; +} + +/* returns true if successful */ +bool Binary_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data, + BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code) +{ + bool status = false; /* return value */ + unsigned int object_index = 0; + unsigned int priority = 0; + BACNET_BINARY_PV level = BINARY_NULL; + + Binary_Value_Init(); + if (!Binary_Value_Valid_Instance(wp_data->object_instance)) { + *error_class = ERROR_CLASS_OBJECT; + *error_code = ERROR_CODE_UNKNOWN_OBJECT; + return false; + } + /* decode the some of the request */ + switch (wp_data->object_property) { + case PROP_PRESENT_VALUE: + if (wp_data->value.tag == BACNET_APPLICATION_TAG_ENUMERATED) { + priority = wp_data->priority; + /* Command priority 6 is reserved for use by Minimum On/Off + algorithm and may not be used for other purposes in any + object. */ + if (priority && (priority <= BACNET_MAX_PRIORITY) && + (priority != 6 /* reserved */ ) && + (wp_data->value.type.Enumerated >= MIN_BINARY_PV) && + (wp_data->value.type.Real <= MAX_BINARY_PV)) { + level = wp_data->value.type.Enumerated; + object_index = + Binary_Value_Instance_To_Index(wp_data-> + object_instance); + priority--; + Binary_Value_Level[object_index][priority] = level; + /* Note: you could set the physical output here if we + are the highest priority. + However, if Out of Service is TRUE, then don't set the + physical output. This comment may apply to the + main loop (i.e. check out of service before changing output) */ + status = true; + } else if (priority == 6) { + /* Command priority 6 is reserved for use by Minimum On/Off + algorithm and may not be used for other purposes in any + object. */ + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_WRITE_ACCESS_DENIED; + } else { + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; + } + } else if (wp_data->value.tag == BACNET_APPLICATION_TAG_NULL) { + level = BINARY_NULL; + object_index = + Binary_Value_Instance_To_Index(wp_data->object_instance); + priority = wp_data->priority; + if (priority && (priority <= BACNET_MAX_PRIORITY)) { + priority--; + Binary_Value_Level[object_index][priority] = level; + /* Note: you could set the physical output here to the next + highest priority, or to the relinquish default if no + priorities are set. + However, if Out of Service is TRUE, then don't set the + physical output. This comment may apply to the + main loop (i.e. check out of service before changing output) */ + status = true; + } else { + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; + } + } else { + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_INVALID_DATA_TYPE; + } + break; + case PROP_OUT_OF_SERVICE: + if (wp_data->value.tag == BACNET_APPLICATION_TAG_BOOLEAN) { + object_index = + Binary_Value_Instance_To_Index(wp_data->object_instance); + Binary_Value_Out_Of_Service[object_index] = + wp_data->value.type.Boolean; + status = true; + } else { + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_INVALID_DATA_TYPE; + } + break; + default: + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_WRITE_ACCESS_DENIED; + break; + } + + return status; +} + + +#ifdef TEST +#include +#include +#include "ctest.h" + +void testBinary_Value(Test * pTest) +{ + uint8_t apdu[MAX_APDU] = { 0 }; + int len = 0; + uint32_t len_value = 0; + uint8_t tag_number = 0; + BACNET_OBJECT_TYPE decoded_type = OBJECT_BINARY_VALUE; + uint32_t decoded_instance = 0; + uint32_t instance = 123; + BACNET_ERROR_CLASS error_class; + BACNET_ERROR_CODE error_code; + + + len = Binary_Value_Encode_Property_APDU(&apdu[0], + instance, + PROP_OBJECT_IDENTIFIER, + BACNET_ARRAY_ALL, &error_class, &error_code); + ct_test(pTest, len != 0); + len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value); + ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID); + len = decode_object_id(&apdu[len], + (int *) &decoded_type, &decoded_instance); + ct_test(pTest, decoded_type == OBJECT_BINARY_VALUE); + ct_test(pTest, decoded_instance == instance); + + return; +} + +#ifdef TEST_BINARY_VALUE +int main(void) +{ + Test *pTest; + bool rc; + + pTest = ct_create("BACnet Binary_Value", NULL); + /* individual tests */ + rc = ct_addTestFunction(pTest, testBinary_Value); + assert(rc); + + ct_setStream(pTest, stdout); + ct_run(pTest); + (void) ct_report(pTest); + ct_destroy(pTest); + + return 0; +} +#endif /* TEST_BINARY_VALUE */ +#endif /* TEST */ diff --git a/bacnet-stack/demo/object/bv.h b/bacnet-stack/demo/object/bv.h new file mode 100644 index 00000000..30c0184d --- /dev/null +++ b/bacnet-stack/demo/object/bv.h @@ -0,0 +1,60 @@ +/************************************************************************** +* +* Copyright (C) 2006 Steve Karg +* +* 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. +* +*********************************************************************/ +#ifndef BV_H +#define BV_H + +#include +#include +#include "bacdef.h" +#include "bacerror.h" +#include "wp.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + bool Binary_Value_Valid_Instance(uint32_t object_instance); + unsigned Binary_Value_Count(void); + uint32_t Binary_Value_Index_To_Instance(unsigned index); + char *Binary_Value_Name(uint32_t object_instance); + + int Binary_Value_Encode_Property_APDU(uint8_t * apdu, + uint32_t object_instance, + BACNET_PROPERTY_ID property, + int32_t array_index, + BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code); + + bool Binary_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data, + BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code); + +#ifdef TEST +#include "ctest.h" + void testBinary_Value(Test * pTest); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/bacnet-stack/demo/object/bv.mak b/bacnet-stack/demo/object/bv.mak new file mode 100644 index 00000000..3e4917d3 --- /dev/null +++ b/bacnet-stack/demo/object/bv.mak @@ -0,0 +1,35 @@ +#Makefile to build test case +CC = gcc +BASEDIR = . +#CFLAGS = -Wall -I. +# -g for debugging with gdb +#CFLAGS = -Wall -I. -g +CFLAGS = -Wall -I. -Itest -DTEST -DTEST_BINARY_VALUE -g + +# NOTE: this file is normally called by the unittest.sh from up directory +SRCS = bacdcode.c \ + bacstr.c \ + bigend.c \ + demo/object/bv.c \ + test/ctest.c + +OBJS = ${SRCS:.c=.o} + +TARGET = binary_value + +all: ${TARGET} + +${TARGET}: ${OBJS} + ${CC} -o $@ ${OBJS} + +.c.o: + ${CC} -c ${CFLAGS} $*.c -o $@ + +depend: + rm -f .depend + ${CC} -MM ${CFLAGS} *.c >> .depend + +clean: + rm -rf core ${TARGET} $(OBJS) *.bak *.1 *.ini + +include: .depend diff --git a/bacnet-stack/demo/object/device.c b/bacnet-stack/demo/object/device.c index 093519a5..b0f8c62b 100644 --- a/bacnet-stack/demo/object/device.c +++ b/bacnet-stack/demo/object/device.c @@ -32,9 +32,11 @@ #include "config.h" /* the custom stuff */ #include "apdu.h" #include "ai.h" /* object list dependency */ +#include "ao.h" /* object list dependency */ +#include "av.h" /* object list dependency */ #include "bi.h" /* object list dependency */ #include "bo.h" /* object list dependency */ -#include "ao.h" /* object list dependency */ +#include "bv.h" /* object list dependency */ #include "lsp.h" /* object list dependency */ #include "wp.h" /* write property handling */ #include "device.h" /* me */ @@ -325,6 +327,7 @@ unsigned Device_Object_List_Count(void) count += Binary_Input_Count(); count += Binary_Output_Count(); count += Analog_Output_Count(); + count += Analog_Value_Count(); count += Life_Safety_Point_Count(); #if BACFILE count += bacfile_count(); @@ -338,6 +341,7 @@ bool Device_Object_List_Identifier(unsigned array_index, { bool status = false; unsigned object_index = 0; + unsigned object_count = 0; /* device object */ if (array_index == 1) { @@ -349,7 +353,8 @@ bool Device_Object_List_Identifier(unsigned array_index, if (!status) { /* array index starts at 1, and 1 for the device object */ object_index = array_index - 2; - if (object_index < Analog_Input_Count()) { + object_count = Analog_Input_Count(); + if (object_index < object_count) { *object_type = OBJECT_ANALOG_INPUT; *instance = Analog_Input_Index_To_Instance(object_index); status = true; @@ -359,9 +364,10 @@ bool Device_Object_List_Identifier(unsigned array_index, if (!status) { /* normalize the index since we know it is not the previous objects */ - object_index -= Analog_Input_Count(); + object_index -= object_count; + object_count = Binary_Input_Count(); /* is it a valid index for this object? */ - if (object_index < Binary_Input_Count()) { + if (object_index < object_count) { *object_type = OBJECT_BINARY_INPUT; *instance = Binary_Input_Index_To_Instance(object_index); status = true; @@ -371,9 +377,10 @@ bool Device_Object_List_Identifier(unsigned array_index, if (!status) { /* normalize the index since we know it is not the previous objects */ - object_index -= Binary_Input_Count(); + object_index -= object_count; + object_count = Binary_Output_Count(); /* is it a valid index for this object? */ - if (object_index < Binary_Output_Count()) { + if (object_index < object_count) { *object_type = OBJECT_BINARY_OUTPUT; *instance = Binary_Output_Index_To_Instance(object_index); status = true; @@ -383,21 +390,36 @@ bool Device_Object_List_Identifier(unsigned array_index, if (!status) { /* normalize the index since we know it is not the previous objects */ - object_index -= Binary_Output_Count(); + object_index -= object_count; + object_count = Analog_Output_Count(); /* is it a valid index for this object? */ - if (object_index < Analog_Output_Count()) { + if (object_index < object_count) { *object_type = OBJECT_ANALOG_OUTPUT; *instance = Analog_Output_Index_To_Instance(object_index); status = true; } } + /* analog value objects */ + if (!status) { + /* normalize the index since + we know it is not the previous objects */ + object_index -= object_count; + object_count = Analog_Value_Count(); + /* is it a valid index for this object? */ + if (object_index < object_count) { + *object_type = OBJECT_ANALOG_VALUE; + *instance = Analog_Value_Index_To_Instance(object_index); + status = true; + } + } /* life safety point objects */ if (!status) { /* normalize the index since we know it is not the previous objects */ - object_index -= Analog_Output_Count(); + object_index -= object_count; + object_count = Life_Safety_Point_Count(); /* is it a valid index for this object? */ - if (object_index < Life_Safety_Point_Count()) { + if (object_index < object_count) { *object_type = OBJECT_LIFE_SAFETY_POINT; *instance = Life_Safety_Point_Index_To_Instance(object_index); status = true; @@ -408,9 +430,10 @@ bool Device_Object_List_Identifier(unsigned array_index, if (!status) { /* normalize the index since we know it is not the previous objects */ - object_index -= Life_Safety_Point_Count(); + object_index -= object_count; + object_count = bacfile_count(); /* is it a valid index for this object? */ - if (object_index < bacfile_count()) { + if (object_index < object_count) { *object_type = OBJECT_FILE; *instance = bacfile_index_to_instance(object_index); status = true; @@ -468,6 +491,9 @@ char *Device_Valid_Object_Id(int object_type, uint32_t object_instance) case OBJECT_ANALOG_OUTPUT: name = Analog_Output_Name(object_instance); break; + case OBJECT_ANALOG_VALUE: + name = Analog_Value_Name(object_instance); + break; case OBJECT_LIFE_SAFETY_POINT: name = Life_Safety_Point_Name(object_instance); break; @@ -604,6 +630,8 @@ int Device_Encode_Property_APDU(uint8_t * apdu, bitstring_set_bit(&bit_string, OBJECT_ANALOG_INPUT, true); if (Analog_Output_Count()) bitstring_set_bit(&bit_string, OBJECT_ANALOG_OUTPUT, true); + if (Analog_Value_Count()) + bitstring_set_bit(&bit_string, OBJECT_ANALOG_VALUE, true); if (Binary_Input_Count()) bitstring_set_bit(&bit_string, OBJECT_BINARY_INPUT, true); if (Binary_Output_Count()) @@ -912,6 +940,22 @@ uint32_t Analog_Output_Index_To_Instance(unsigned index) return index; } +char *Analog_Value_Name(uint32_t object_instance) +{ + (void) object_instance; + return ""; +} + +unsigned Analog_Value_Count(void) +{ + return 0; +} + +uint32_t Analog_Value_Index_To_Instance(unsigned index) +{ + return index; +} + char *Life_Safety_Point_Name(uint32_t object_instance) { (void) object_instance; diff --git a/bacnet-stack/demo/readfile/Makefile b/bacnet-stack/demo/readfile/Makefile index dc72aba9..e7ce5089 100644 --- a/bacnet-stack/demo/readfile/Makefile +++ b/bacnet-stack/demo/readfile/Makefile @@ -44,8 +44,10 @@ SRCS = readfile.c \ $(BACNET_OBJECT)/device.c \ $(BACNET_OBJECT)/ai.c \ $(BACNET_OBJECT)/ao.c \ + $(BACNET_OBJECT)/av.c \ $(BACNET_OBJECT)/bi.c \ $(BACNET_OBJECT)/bo.c \ + $(BACNET_OBJECT)/bv.c \ $(BACNET_OBJECT)/lsp.c \ $(BACNET_OBJECT)/bacfile.c \ $(BACNET_ROOT)/arf.c \ diff --git a/bacnet-stack/demo/readfile/makefile.b32 b/bacnet-stack/demo/readfile/makefile.b32 index 068175c4..6df40e07 100644 --- a/bacnet-stack/demo/readfile/makefile.b32 +++ b/bacnet-stack/demo/readfile/makefile.b32 @@ -42,8 +42,10 @@ SRCS = readfile.c \ ..\..\demo\object\device.c \ ..\..\demo\object\ai.c \ ..\..\demo\object\ao.c \ + ..\..\demo\object\av.c \ ..\..\demo\object\bi.c \ ..\..\demo\object\bo.c \ + ..\..\demo\object\bv.c \ ..\..\demo\object\lsp.c \ ..\..\datalink.c \ ..\..\tsm.c \ diff --git a/bacnet-stack/demo/readprop/Makefile b/bacnet-stack/demo/readprop/Makefile index b2d6dbe7..fdff15c8 100644 --- a/bacnet-stack/demo/readprop/Makefile +++ b/bacnet-stack/demo/readprop/Makefile @@ -34,8 +34,10 @@ SRCS = readprop.c \ $(BACNET_OBJECT)/device.c \ $(BACNET_OBJECT)/ai.c \ $(BACNET_OBJECT)/ao.c \ + $(BACNET_OBJECT)/av.c \ $(BACNET_OBJECT)/bi.c \ $(BACNET_OBJECT)/bo.c \ + $(BACNET_OBJECT)/bv.c \ $(BACNET_OBJECT)/lsp.c \ $(BACNET_OBJECT)/bacfile.c \ $(BACNET_ROOT)/filename.c \ diff --git a/bacnet-stack/demo/readprop/makefile.b32 b/bacnet-stack/demo/readprop/makefile.b32 index ae62183a..07fed2fe 100644 --- a/bacnet-stack/demo/readprop/makefile.b32 +++ b/bacnet-stack/demo/readprop/makefile.b32 @@ -46,8 +46,10 @@ SRCS = readprop.c \ ..\..\demo\object\device.c \ ..\..\demo\object\ai.c \ ..\..\demo\object\ao.c \ + ..\..\demo\object\av.c \ ..\..\demo\object\bi.c \ ..\..\demo\object\bo.c \ + ..\..\demo\object\bv.c \ ..\..\demo\object\lsp.c \ ..\..\datalink.c \ ..\..\tsm.c \ diff --git a/bacnet-stack/demo/reinit/Makefile b/bacnet-stack/demo/reinit/Makefile index 46e14f11..5eb06334 100644 --- a/bacnet-stack/demo/reinit/Makefile +++ b/bacnet-stack/demo/reinit/Makefile @@ -34,8 +34,10 @@ SRCS = main.c \ $(BACNET_OBJECT)/device.c \ $(BACNET_OBJECT)/ai.c \ $(BACNET_OBJECT)/ao.c \ + $(BACNET_OBJECT)/av.c \ $(BACNET_OBJECT)/bi.c \ $(BACNET_OBJECT)/bo.c \ + $(BACNET_OBJECT)/bv.c \ $(BACNET_OBJECT)/lsp.c \ $(BACNET_OBJECT)/bacfile.c \ $(BACNET_ROOT)/filename.c \ diff --git a/bacnet-stack/demo/reinit/makefile.b32 b/bacnet-stack/demo/reinit/makefile.b32 index fe12b896..4713d368 100644 --- a/bacnet-stack/demo/reinit/makefile.b32 +++ b/bacnet-stack/demo/reinit/makefile.b32 @@ -46,8 +46,10 @@ SRCS = main.c \ ..\..\demo\object\device.c \ ..\..\demo\object\ai.c \ ..\..\demo\object\ao.c \ + ..\..\demo\object\av.c \ ..\..\demo\object\bi.c \ ..\..\demo\object\bo.c \ + ..\..\demo\object\bv.c \ ..\..\demo\object\lsp.c \ ..\..\datalink.c \ ..\..\tsm.c \ diff --git a/bacnet-stack/demo/server/Makefile b/bacnet-stack/demo/server/Makefile index 8c33e64b..edec668c 100644 --- a/bacnet-stack/demo/server/Makefile +++ b/bacnet-stack/demo/server/Makefile @@ -37,8 +37,10 @@ SRCS = server.c \ $(BACNET_OBJECT)/device.c \ $(BACNET_OBJECT)/ai.c \ $(BACNET_OBJECT)/ao.c \ + $(BACNET_OBJECT)/av.c \ $(BACNET_OBJECT)/bi.c \ $(BACNET_OBJECT)/bo.c \ + $(BACNET_OBJECT)/bv.c \ $(BACNET_OBJECT)/lsp.c \ $(BACNET_OBJECT)/bacfile.c \ $(BACNET_ROOT)/datalink.c \ diff --git a/bacnet-stack/demo/server/makefile.b32 b/bacnet-stack/demo/server/makefile.b32 index a31ff36a..024a078f 100644 --- a/bacnet-stack/demo/server/makefile.b32 +++ b/bacnet-stack/demo/server/makefile.b32 @@ -54,8 +54,10 @@ SRCS = server.c \ ..\..\demo\object\device.c \ ..\..\demo\object\ai.c \ ..\..\demo\object\ao.c \ + ..\..\demo\object\av.c \ ..\..\demo\object\bi.c \ ..\..\demo\object\bo.c \ + ..\..\demo\object\bv.c \ ..\..\demo\object\lsp.c \ ..\..\datalink.c \ ..\..\abort.c \ diff --git a/bacnet-stack/demo/timesync/Makefile b/bacnet-stack/demo/timesync/Makefile index 044f8257..11c84354 100644 --- a/bacnet-stack/demo/timesync/Makefile +++ b/bacnet-stack/demo/timesync/Makefile @@ -34,8 +34,10 @@ SRCS = main.c \ $(BACNET_OBJECT)/device.c \ $(BACNET_OBJECT)/ai.c \ $(BACNET_OBJECT)/ao.c \ + $(BACNET_OBJECT)/av.c \ $(BACNET_OBJECT)/bi.c \ $(BACNET_OBJECT)/bo.c \ + $(BACNET_OBJECT)/bv.c \ $(BACNET_OBJECT)/lsp.c \ $(BACNET_OBJECT)/bacfile.c \ $(BACNET_ROOT)/filename.c \ diff --git a/bacnet-stack/demo/timesync/makefile.b32 b/bacnet-stack/demo/timesync/makefile.b32 index 5c5e5eef..f17faf61 100644 --- a/bacnet-stack/demo/timesync/makefile.b32 +++ b/bacnet-stack/demo/timesync/makefile.b32 @@ -36,8 +36,10 @@ SRCS = main.c \ $(BACNET_OBJECT)\device.c \ $(BACNET_OBJECT)\ai.c \ $(BACNET_OBJECT)\ao.c \ + $(BACNET_OBJECT)\av.c \ $(BACNET_OBJECT)\bi.c \ $(BACNET_OBJECT)\bo.c \ + $(BACNET_OBJECT)\bv.c \ $(BACNET_OBJECT)\lsp.c \ $(BACNET_ROOT)\address.c \ $(BACNET_ROOT)\filename.c \ diff --git a/bacnet-stack/demo/ucov/Makefile b/bacnet-stack/demo/ucov/Makefile index 068801ad..4a449e89 100644 --- a/bacnet-stack/demo/ucov/Makefile +++ b/bacnet-stack/demo/ucov/Makefile @@ -31,8 +31,10 @@ SRCS = main.c \ $(BACNET_OBJECT)/device.c \ $(BACNET_OBJECT)/ai.c \ $(BACNET_OBJECT)/ao.c \ + $(BACNET_OBJECT)/av.c \ $(BACNET_OBJECT)/bi.c \ $(BACNET_OBJECT)/bo.c \ + $(BACNET_OBJECT)/bv.c \ $(BACNET_OBJECT)/lsp.c \ $(BACNET_OBJECT)/bacfile.c \ $(BACNET_ROOT)/filename.c \ diff --git a/bacnet-stack/demo/ucov/makefile.b32 b/bacnet-stack/demo/ucov/makefile.b32 index 3f365309..51139d22 100644 --- a/bacnet-stack/demo/ucov/makefile.b32 +++ b/bacnet-stack/demo/ucov/makefile.b32 @@ -44,8 +44,10 @@ SRCS = main.c \ ..\..\demo\object\device.c \ ..\..\demo\object\ai.c \ ..\..\demo\object\ao.c \ + ..\..\demo\object\av.c \ ..\..\demo\object\bi.c \ ..\..\demo\object\bo.c \ + ..\..\demo\object\bv.c \ ..\..\demo\object\lsp.c \ ..\..\datalink.c \ ..\..\address.c \ diff --git a/bacnet-stack/demo/whohas/Makefile b/bacnet-stack/demo/whohas/Makefile index 11d6a4f6..79e233f6 100644 --- a/bacnet-stack/demo/whohas/Makefile +++ b/bacnet-stack/demo/whohas/Makefile @@ -34,8 +34,10 @@ SRCS = main.c \ $(BACNET_OBJECT)/device.c \ $(BACNET_OBJECT)/ai.c \ $(BACNET_OBJECT)/ao.c \ + $(BACNET_OBJECT)/av.c \ $(BACNET_OBJECT)/bi.c \ $(BACNET_OBJECT)/bo.c \ + $(BACNET_OBJECT)/bv.c \ $(BACNET_OBJECT)/lsp.c \ $(BACNET_OBJECT)/bacfile.c \ $(BACNET_ROOT)/filename.c \ diff --git a/bacnet-stack/demo/whohas/makefile.b32 b/bacnet-stack/demo/whohas/makefile.b32 index afa66ff2..6463d213 100644 --- a/bacnet-stack/demo/whohas/makefile.b32 +++ b/bacnet-stack/demo/whohas/makefile.b32 @@ -48,8 +48,10 @@ SRCS = main.c \ ..\..\demo\object\device.c \ ..\..\demo\object\ai.c \ ..\..\demo\object\ao.c \ + ..\..\demo\object\av.c \ ..\..\demo\object\bi.c \ ..\..\demo\object\bo.c \ + ..\..\demo\object\bv.c \ ..\..\demo\object\lsp.c \ ..\..\datalink.c \ ..\..\abort.c \ diff --git a/bacnet-stack/demo/whois/Makefile b/bacnet-stack/demo/whois/Makefile index f468bd9e..e1d64430 100644 --- a/bacnet-stack/demo/whois/Makefile +++ b/bacnet-stack/demo/whois/Makefile @@ -35,8 +35,10 @@ SRCS = main.c \ $(BACNET_OBJECT)/device.c \ $(BACNET_OBJECT)/ai.c \ $(BACNET_OBJECT)/ao.c \ + $(BACNET_OBJECT)/av.c \ $(BACNET_OBJECT)/bi.c \ $(BACNET_OBJECT)/bo.c \ + $(BACNET_OBJECT)/bv.c \ $(BACNET_OBJECT)/lsp.c \ $(BACNET_OBJECT)/bacfile.c \ $(BACNET_ROOT)/filename.c \ diff --git a/bacnet-stack/demo/whois/makefile.b32 b/bacnet-stack/demo/whois/makefile.b32 index fa0c6f6e..866dcce3 100644 --- a/bacnet-stack/demo/whois/makefile.b32 +++ b/bacnet-stack/demo/whois/makefile.b32 @@ -35,8 +35,10 @@ SRCS = main.c \ $(BACNET_OBJECT)\device.c \ $(BACNET_OBJECT)\ai.c \ $(BACNET_OBJECT)\ao.c \ + $(BACNET_OBJECT)\av.c \ $(BACNET_OBJECT)\bi.c \ $(BACNET_OBJECT)\bo.c \ + $(BACNET_OBJECT)\bv.c \ $(BACNET_OBJECT)\lsp.c \ $(BACNET_ROOT)\address.c \ $(BACNET_ROOT)\filename.c \ diff --git a/bacnet-stack/demo/writefile/Makefile b/bacnet-stack/demo/writefile/Makefile index dbc581ea..09e22e22 100644 --- a/bacnet-stack/demo/writefile/Makefile +++ b/bacnet-stack/demo/writefile/Makefile @@ -44,8 +44,10 @@ SRCS = writefile.c \ $(BACNET_OBJECT)/device.c \ $(BACNET_OBJECT)/ai.c \ $(BACNET_OBJECT)/ao.c \ + $(BACNET_OBJECT)/av.c \ $(BACNET_OBJECT)/bi.c \ $(BACNET_OBJECT)/bo.c \ + $(BACNET_OBJECT)/bv.c \ $(BACNET_OBJECT)/lsp.c \ $(BACNET_OBJECT)/bacfile.c \ $(BACNET_ROOT)/arf.c \ diff --git a/bacnet-stack/demo/writefile/makefile.b32 b/bacnet-stack/demo/writefile/makefile.b32 index 3c38576f..efeb3844 100644 --- a/bacnet-stack/demo/writefile/makefile.b32 +++ b/bacnet-stack/demo/writefile/makefile.b32 @@ -42,8 +42,10 @@ SRCS = writefile.c \ ..\..\demo\object\device.c \ ..\..\demo\object\ai.c \ ..\..\demo\object\ao.c \ + ..\..\demo\object\av.c \ ..\..\demo\object\bi.c \ ..\..\demo\object\bo.c \ + ..\..\demo\object\bv.c \ ..\..\demo\object\lsp.c \ ..\..\datalink.c \ ..\..\tsm.c \ diff --git a/bacnet-stack/demo/writeprop/Makefile b/bacnet-stack/demo/writeprop/Makefile index 728a86b3..b95749fd 100644 --- a/bacnet-stack/demo/writeprop/Makefile +++ b/bacnet-stack/demo/writeprop/Makefile @@ -33,8 +33,10 @@ SRCS = writeprop.c \ $(BACNET_OBJECT)/device.c \ $(BACNET_OBJECT)/ai.c \ $(BACNET_OBJECT)/ao.c \ + $(BACNET_OBJECT)/av.c \ $(BACNET_OBJECT)/bi.c \ $(BACNET_OBJECT)/bo.c \ + $(BACNET_OBJECT)/bv.c \ $(BACNET_OBJECT)/lsp.c \ $(BACNET_OBJECT)/bacfile.c \ $(BACNET_ROOT)/filename.c \ diff --git a/bacnet-stack/demo/writeprop/makefile.b32 b/bacnet-stack/demo/writeprop/makefile.b32 index b18bde60..07f85ddc 100644 --- a/bacnet-stack/demo/writeprop/makefile.b32 +++ b/bacnet-stack/demo/writeprop/makefile.b32 @@ -45,8 +45,10 @@ SRCS = writeprop.c \ ..\..\demo\object\device.c \ ..\..\demo\object\ai.c \ ..\..\demo\object\ao.c \ + ..\..\demo\object\av.c \ ..\..\demo\object\bi.c \ ..\..\demo\object\bo.c \ + ..\..\demo\object\bv.c \ ..\..\demo\object\lsp.c \ ..\..\datalink.c \ ..\..\tsm.c \ diff --git a/bacnet-stack/ports/win32/MAKEFILE.MAK b/bacnet-stack/ports/win32/MAKEFILE.MAK index 163f0afb..c026163b 100644 --- a/bacnet-stack/ports/win32/MAKEFILE.MAK +++ b/bacnet-stack/ports/win32/MAKEFILE.MAK @@ -44,6 +44,11 @@ SRCS = main.c bip-init.c \ ..\..\demo\object\device.c \ ..\..\demo\object\ai.c \ ..\..\demo\object\ao.c \ + ..\..\demo\object\av.c \ + ..\..\demo\object\bi.c \ + ..\..\demo\object\bo.c \ + ..\..\demo\object\bv.c \ + ..\..\demo\object\lsp.c \ ..\..\datalink.c \ ..\..\tsm.c \ ..\..\address.c \ diff --git a/bacnet-stack/ports/win32/bacnet/bacnet.dsp b/bacnet-stack/ports/win32/bacnet/bacnet.dsp index 8616c621..e5fe5e32 100644 --- a/bacnet-stack/ports/win32/bacnet/bacnet.dsp +++ b/bacnet-stack/ports/win32/bacnet/bacnet.dsp @@ -105,6 +105,10 @@ SOURCE=..\..\..\demo\object\ao.c # End Source File # Begin Source File +SOURCE=..\..\..\demo\object\av.c +# End Source File +# Begin Source File + SOURCE=..\..\..\apdu.c # End Source File # Begin Source File @@ -141,7 +145,11 @@ SOURCE=..\..\..\demo\object\bi.c # End Source File # Begin Source File -SOURCE=..\..\..\demo\object\bi.h +SOURCE=..\..\..\demo\object\bo.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\demo\object\bv.h # End Source File # Begin Source File @@ -157,10 +165,6 @@ SOURCE=..\..\..\bip.c # End Source File # Begin Source File -SOURCE=..\..\..\demo\object\bo.c -# End Source File -# Begin Source File - SOURCE=..\..\..\demo\object\bo.h # End Source File # Begin Source File diff --git a/bacnet-stack/unittest.sh b/bacnet-stack/unittest.sh index 868cbc55..f9c471ba 100755 --- a/bacnet-stack/unittest.sh +++ b/bacnet-stack/unittest.sh @@ -34,6 +34,11 @@ make -f demo/object/ao.mak ./analog_output >> test.log make -f demo/object/ao.mak clean +make -f demo/object/av.mak clean +make -f demo/object/av.mak +./analog_value >> test.log +make -f demo/object/av.mak clean + make -f arf.mak clean make -f arf.mak ./atomicreadfile >> test.log @@ -74,6 +79,11 @@ make -f demo/object/bo.mak ./binary_output >> test.log make -f demo/object/bo.mak clean +make -f demo/object/bv.mak clean +make -f demo/object/bv.mak +./binary_value >> test.log +make -f demo/object/bv.mak clean + make -f crc.mak clean make -f crc.mak ./crc >> test.log