diff --git a/bacnet-stack/demo/object/device.c b/bacnet-stack/demo/object/device.c index ca8df75b..07015c83 100644 --- a/bacnet-stack/demo/object/device.c +++ b/bacnet-stack/demo/object/device.c @@ -554,9 +554,7 @@ bool Device_Set_Object_Name( const char *name, size_t length) { - bool status; /*return value */ - - status = false; + bool status = false; /*return value */ /* FIXME: All the object names in a device must be unique. Disallow setting the Device Object Name to any objects in @@ -582,9 +580,8 @@ int Device_Set_System_Status( BACNET_DEVICE_STATUS status, bool local) { - int result; /*return value - 0 = ok, -1 = bad value, -2 = not allowed */ + int result = 0; /*return value - 0 = ok, -1 = bad value, -2 = not allowed */ - result = 0; /* We limit the options available depending on whether the source is * internal or external. */ if(local) { diff --git a/bacnet-stack/ports/at91sam7s/Makefile b/bacnet-stack/ports/at91sam7s/Makefile index 14e4a5f2..8b59f5d2 100644 --- a/bacnet-stack/ports/at91sam7s/Makefile +++ b/bacnet-stack/ports/at91sam7s/Makefile @@ -57,16 +57,19 @@ DEMOSRC = ai.c \ av.c \ bi.c \ bv.c \ - h_rp.c \ - h_wp.c \ device.c \ $(BACNET_DEMO)/handler/txbuf.c \ $(BACNET_DEMO)/handler/noserv.c \ $(BACNET_DEMO)/handler/h_npdu.c \ + $(BACNET_DEMO)/handler/h_whohas.c \ $(BACNET_DEMO)/handler/h_whois.c \ $(BACNET_DEMO)/handler/h_rd.c \ + $(BACNET_DEMO)/handler/h_rp.c \ + $(BACNET_DEMO)/handler/h_rpm.c \ + $(BACNET_DEMO)/handler/h_wp.c \ $(BACNET_DEMO)/handler/h_dcc.c \ - $(BACNET_DEMO)/handler/s_iam.c + $(BACNET_DEMO)/handler/s_iam.c \ + $(BACNET_DEMO)/handler/s_ihave.c CORESRC = $(BACNET_CORE)/npdu.c \ $(BACNET_CORE)/apdu.c \ @@ -80,12 +83,16 @@ CORESRC = $(BACNET_CORE)/npdu.c \ $(BACNET_CORE)/reject.c \ $(BACNET_CORE)/bacapp.c \ $(BACNET_CORE)/datetime.c \ - $(BACNET_CORE)/rp.c \ - $(BACNET_CORE)/wp.c \ $(BACNET_CORE)/dcc.c \ - $(BACNET_CORE)/rd.c \ - $(BACNET_CORE)/whois.c \ $(BACNET_CORE)/iam.c \ + $(BACNET_CORE)/ihave.c \ + $(BACNET_CORE)/memcopy.c \ + $(BACNET_CORE)/rd.c \ + $(BACNET_CORE)/rp.c \ + $(BACNET_CORE)/rpm.c \ + $(BACNET_CORE)/wp.c \ + $(BACNET_CORE)/whohas.c \ + $(BACNET_CORE)/whois.c \ $(BACNET_CORE)/version.c CSRC = $(PORTSRC) $(DEMOSRC) diff --git a/bacnet-stack/ports/at91sam7s/ai.c b/bacnet-stack/ports/at91sam7s/ai.c index 62152db8..6c89903e 100644 --- a/bacnet-stack/ports/at91sam7s/ai.c +++ b/bacnet-stack/ports/at91sam7s/ai.c @@ -32,15 +32,55 @@ #include "bacdcode.h" #include "bacenum.h" #include "config.h" +#include "ai.h" +#include "handlers.h" -/* Analog Input = Photocell */ +#ifndef MAX_ANALOG_INPUTS #define MAX_ANALOG_INPUTS 2 +#endif #if (MAX_ANALOG_INPUTS > 9) #error Modify the Analog_Input_Name to handle multiple digits #endif static float Present_Value[MAX_ANALOG_INPUTS]; +/* These three arrays are used by the ReadPropertyMultiple handler */ +static const int Analog_Input_Properties_Required[] = { + PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, + PROP_OBJECT_TYPE, + PROP_PRESENT_VALUE, + PROP_STATUS_FLAGS, + PROP_EVENT_STATE, + PROP_OUT_OF_SERVICE, + PROP_UNITS, + -1 +}; + +static const int Analog_Input_Properties_Optional[] = { + PROP_DESCRIPTION, + -1 +}; + +static const int Analog_Input_Properties_Proprietary[] = { + -1 +}; + +void Analog_Input_Property_Lists( + const int **pRequired, + const int **pOptional, + const int **pProprietary) +{ + if (pRequired) + *pRequired = Analog_Input_Properties_Required; + if (pOptional) + *pOptional = Analog_Input_Properties_Optional; + if (pProprietary) + *pProprietary = Analog_Input_Properties_Proprietary; + + return; +} + /* we simply have 0-n object instances. Yours might be */ /* more complex, and then you need validate that the */ /* given instance exists */ @@ -102,30 +142,32 @@ void Analog_Input_Present_Value_Set( /* return apdu length, or -1 on error */ /* assumption - object has already exists */ -int Analog_Input_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 Analog_Input_Read_Property( + BACNET_READ_PROPERTY_DATA *rpdata) { int apdu_len = 0; /* return value */ BACNET_BIT_STRING bit_string; BACNET_CHARACTER_STRING char_string; + uint8_t *apdu = NULL; - switch (property) { + if ((rpdata == NULL) || + (rpdata->application_data == NULL) || + (rpdata->application_data_len == 0)) { + return 0; + } + apdu = rpdata->application_data; + switch (rpdata->object_property) { case PROP_OBJECT_IDENTIFIER: apdu_len = encode_application_object_id(&apdu[0], OBJECT_ANALOG_INPUT, - object_instance); + rpdata->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, - Analog_Input_Name(object_instance)); + Analog_Input_Name(rpdata->object_instance)); apdu_len = encode_application_character_string(&apdu[0], &char_string); break; @@ -136,7 +178,7 @@ int Analog_Input_Encode_Property_APDU( case PROP_PRESENT_VALUE: apdu_len = encode_application_real(&apdu[0], - Analog_Input_Present_Value(object_instance)); + Analog_Input_Present_Value(rpdata->object_instance)); break; case PROP_STATUS_FLAGS: bitstring_init(&bit_string); @@ -157,74 +199,24 @@ int Analog_Input_Encode_Property_APDU( apdu_len = encode_application_enumerated(&apdu[0], UNITS_PERCENT); break; default: - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_UNKNOWN_PROPERTY; + rpdata->error_class = ERROR_CLASS_PROPERTY; + rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY; apdu_len = -1; break; } /* only array properties can have array options */ if ((apdu_len >= 0) && - (array_index != BACNET_ARRAY_ALL)) { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; + (rpdata->array_index != BACNET_ARRAY_ALL)) { + rpdata->error_class = ERROR_CLASS_PROPERTY; + rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; apdu_len = -1; } return apdu_len; } -#ifdef TEST -#include -#include -#include "ctest.h" - -void testAnalogInput( - 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_OUTPUT; - uint32_t decoded_instance = 0; - uint32_t instance = 123; - BACNET_ERROR_CLASS error_class; - BACNET_ERROR_CODE error_code; - - - /* FIXME: we should do a lot more testing here... */ - len = - Analog_Input_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_INPUT); - ct_test(pTest, decoded_instance == instance); - - return; -} - -#ifdef TEST_ANALOG_INPUT -int main( +void Analog_Input_Init( void) { - Test *pTest; - bool rc; - - pTest = ct_create("BACnet Analog Input", NULL); - /* individual tests */ - rc = ct_addTestFunction(pTest, testAnalogInput); - assert(rc); - - ct_setStream(pTest, stdout); - ct_run(pTest); - (void) ct_report(pTest); - ct_destroy(pTest); - - return 0; + return; } -#endif /* TEST_ANALOG_INPUT */ -#endif /* TEST */ diff --git a/bacnet-stack/ports/at91sam7s/ai.h b/bacnet-stack/ports/at91sam7s/ai.h deleted file mode 100644 index 9b9e0c5e..00000000 --- a/bacnet-stack/ports/at91sam7s/ai.h +++ /dev/null @@ -1,98 +0,0 @@ -/************************************************************************** -* -* Copyright (C) 2005 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 AI_H -#define AI_H - -#include -#include -#include "bacdef.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#ifndef MAX_ANALOG_INPUTS -#define MAX_ANALOG_INPUTS 7 -#endif - - void Analog_Input_Property_Lists( - const int **pRequired, - const int **pOptional, - const int **pProprietary); - - bool Analog_Input_Valid_Instance( - uint32_t object_instance); - unsigned Analog_Input_Count( - void); - uint32_t Analog_Input_Index_To_Instance( - unsigned index); - unsigned Analog_Input_Instance_To_Index( - uint32_t instance); - bool Analog_Input_Object_Instance_Add( - uint32_t instance); - - char *Analog_Input_Name( - uint32_t object_instance); - bool Analog_Input_Name_Set( - uint32_t object_instance, - char *new_name); - - char *Analog_Input_Description( - uint32_t instance); - bool Analog_Input_Description_Set( - uint32_t instance, - char *new_name); - - bool Analog_Input_Units_Set( - uint32_t instance, - uint32_t units); - uint32_t Analog_Input_Units( - uint32_t instance); - - int Analog_Input_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); - float Analog_Input_Present_Value( - uint32_t object_instance); - void Analog_Input_Present_Value_Set( - uint32_t object_instance, - float value); - void Analog_Input_Init( - void); - -#ifdef TEST -#include "ctest.h" - void testAnalogInput( - Test * pTest); -#endif - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif diff --git a/bacnet-stack/ports/at91sam7s/av.c b/bacnet-stack/ports/at91sam7s/av.c index b10b1e61..05d1b5d4 100644 --- a/bacnet-stack/ports/at91sam7s/av.c +++ b/bacnet-stack/ports/at91sam7s/av.c @@ -32,9 +32,12 @@ #include "bacenum.h" #include "bacapp.h" #include "config.h" /* the custom stuff */ -#include "wp.h" +#include "av.h" +#include "handlers.h" +#ifndef MAX_ANALOG_VALUES #define MAX_ANALOG_VALUES 4 +#endif #if (MAX_ANALOG_VALUES > 9) #error Modify the Analog_Value_Name to handle multiple digits #endif @@ -51,21 +54,55 @@ /* and load a Real for returning the value when asked. */ static uint8_t Present_Value[MAX_ANALOG_VALUES]; -/* we need to have our arrays initialized before answering any calls */ -static bool Analog_Value_Initialized = false; +/* These three arrays are used by the ReadPropertyMultiple handler */ +static const int Analog_Value_Properties_Required[] = { + PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, + PROP_OBJECT_TYPE, + PROP_PRESENT_VALUE, + PROP_STATUS_FLAGS, + PROP_EVENT_STATE, + PROP_OUT_OF_SERVICE, + PROP_UNITS, + -1 +}; + +static const int Analog_Value_Properties_Optional[] = { + PROP_DESCRIPTION, +#if 0 + PROP_PRIORITY_ARRAY, + PROP_RELINQUISH_DEFAULT, +#endif + -1 +}; + +static const int Analog_Value_Properties_Proprietary[] = { + -1 +}; + +void Analog_Value_Property_Lists( + const int **pRequired, + const int **pOptional, + const int **pProprietary) +{ + if (pRequired) + *pRequired = Analog_Value_Properties_Required; + if (pOptional) + *pOptional = Analog_Value_Properties_Optional; + if (pProprietary) + *pProprietary = Analog_Value_Properties_Proprietary; + + return; +} void Analog_Value_Init( void) { unsigned i; - 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++) { - Present_Value[i] = ANALOG_LEVEL_NULL; - } + /* initialize all the analog output priority arrays to NULL */ + for (i = 0; i < MAX_ANALOG_VALUES; i++) { + Present_Value[i] = ANALOG_LEVEL_NULL; } return; @@ -77,7 +114,6 @@ void Analog_Value_Init( bool Analog_Value_Valid_Instance( uint32_t object_instance) { - Analog_Value_Init(); if (object_instance < MAX_ANALOG_VALUES) return true; @@ -89,7 +125,6 @@ bool Analog_Value_Valid_Instance( unsigned Analog_Value_Count( void) { - Analog_Value_Init(); return MAX_ANALOG_VALUES; } @@ -99,7 +134,6 @@ unsigned Analog_Value_Count( uint32_t Analog_Value_Index_To_Instance( unsigned index) { - Analog_Value_Init(); return index; } @@ -111,20 +145,18 @@ unsigned Analog_Value_Instance_To_Index( { 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( +float Analog_Value_Present_Value( uint32_t object_instance) { float value = ANALOG_RELINQUISH_DEFAULT; unsigned index = 0; - Analog_Value_Init(); index = Analog_Value_Instance_To_Index(object_instance); if (index < MAX_ANALOG_VALUES) { value = Present_Value[index]; @@ -148,13 +180,8 @@ char *Analog_Value_Name( } /* 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 Analog_Value_Read_Property( + BACNET_READ_PROPERTY_DATA *rpdata) { int apdu_len = 0; /* return value */ BACNET_BIT_STRING bit_string; @@ -166,18 +193,24 @@ int Analog_Value_Encode_Property_APDU( unsigned i = 0; bool state = false; #endif + uint8_t *apdu = NULL; - Analog_Value_Init(); - switch (property) { + if ((rpdata == NULL) || + (rpdata->application_data == NULL) || + (rpdata->application_data_len == 0)) { + return 0; + } + apdu = rpdata->application_data; + switch (rpdata->object_property) { case PROP_OBJECT_IDENTIFIER: apdu_len = encode_application_object_id(&apdu[0], OBJECT_ANALOG_VALUE, - object_instance); + rpdata->object_instance); break; case PROP_OBJECT_NAME: case PROP_DESCRIPTION: characterstring_init_ansi(&char_string, - Analog_Value_Name(object_instance)); + Analog_Value_Name(rpdata->object_instance)); apdu_len = encode_application_character_string(&apdu[0], &char_string); break; @@ -186,7 +219,7 @@ int Analog_Value_Encode_Property_APDU( encode_application_enumerated(&apdu[0], OBJECT_ANALOG_VALUE); break; case PROP_PRESENT_VALUE: - real_value = Analog_Value_Present_Value(object_instance); + real_value = Analog_Value_Present_Value(rpdata->object_instance); apdu_len = encode_application_real(&apdu[0], real_value); break; case PROP_STATUS_FLAGS: @@ -203,7 +236,7 @@ int Analog_Value_Encode_Property_APDU( break; case PROP_OUT_OF_SERVICE: #if 0 - object_index = Analog_Value_Instance_To_Index(object_instance); + object_index = Analog_Value_Instance_To_Index(rpdata->object_instance); state = Analog_Value_Out_Of_Service[object_index]; #endif apdu_len = encode_application_boolean(&apdu[0], false); @@ -214,13 +247,13 @@ int Analog_Value_Encode_Property_APDU( #if 0 case PROP_PRIORITY_ARRAY: /* Array element zero is the number of elements in the array */ - if (array_index == 0) + if (rpdata->array_index == 0) apdu_len = encode_application_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); + else if (rpdata->array_index == BACNET_ARRAY_ALL) { + object_index = Analog_Value_Instance_To_Index(rpdata->object_instance); for (i = 0; i < BACNET_MAX_PRIORITY; i++) { /* FIXME: check if we have room before adding it to APDU */ if (Present_Value[object_index][i] == ANALOG_LEVEL_NULL) @@ -235,27 +268,27 @@ int Analog_Value_Encode_Property_APDU( if ((apdu_len + len) < MAX_APDU) apdu_len += len; else { - *error_class = ERROR_CLASS_SERVICES; - *error_code = ERROR_CODE_NO_SPACE_FOR_OBJECT; + rpdata->error_class = ERROR_CLASS_SERVICES; + rpdata->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 (Present_Value[object_index][array_index - 1] == + if (rpdata->array_index <= BACNET_MAX_PRIORITY) { + if (Present_Value[object_index][rpdata->array_index - 1] == ANALOG_LEVEL_NULL) apdu_len = encode_application_null(&apdu[0]); else { real_value = - Present_Value[object_index][array_index - 1]; + Present_Value[object_index][rpdata->array_index - 1]; apdu_len = encode_application_real(&apdu[0], real_value); } } else { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_INVALID_ARRAY_INDEX; + rpdata->error_class = ERROR_CLASS_PROPERTY; + rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX; apdu_len = -1; } } @@ -267,19 +300,19 @@ int Analog_Value_Encode_Property_APDU( break; #endif default: - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_UNKNOWN_PROPERTY; + rpdata->error_class = ERROR_CLASS_PROPERTY; + rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY; apdu_len = -1; break; } /* only array properties can have array options */ if ((apdu_len >= 0) && #if 0 - (property != PROP_PRIORITY_ARRAY) && + (rpdata->object_property != PROP_PRIORITY_ARRAY) && #endif - (array_index != BACNET_ARRAY_ALL)) { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; + (rpdata->array_index != BACNET_ARRAY_ALL)) { + rpdata->error_class = ERROR_CLASS_PROPERTY; + rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; apdu_len = -1; } @@ -288,9 +321,7 @@ int Analog_Value_Encode_Property_APDU( /* 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) + BACNET_WRITE_PROPERTY_DATA * wp_data) { bool status = false; /* return value */ unsigned int object_index = 0; @@ -299,10 +330,9 @@ bool Analog_Value_Write_Property( int len = 0; BACNET_APPLICATION_DATA_VALUE value; - Analog_Value_Init(); if (!Analog_Value_Valid_Instance(wp_data->object_instance)) { - *error_class = ERROR_CLASS_OBJECT; - *error_code = ERROR_CODE_UNKNOWN_OBJECT; + wp_data->error_class = ERROR_CLASS_OBJECT; + wp_data->error_code = ERROR_CODE_UNKNOWN_OBJECT; return false; } /* decode the some of the request */ @@ -337,11 +367,11 @@ bool Analog_Value_Write_Property( /* 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; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED; } else { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; } #if 0 } else if (value.tag == BACNET_APPLICATION_TAG_NULL) { @@ -360,13 +390,13 @@ bool Analog_Value_Write_Property( 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; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; } #endif } else { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_INVALID_DATA_TYPE; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE; } break; #if 0 @@ -377,72 +407,17 @@ bool Analog_Value_Write_Property( Analog_Value_Out_Of_Service[object_index] = value.type.Boolean; status = true; } else { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_INVALID_DATA_TYPE; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE; } break; #endif default: - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_WRITE_ACCESS_DENIED; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->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/ports/at91sam7s/av.h b/bacnet-stack/ports/at91sam7s/av.h deleted file mode 100644 index 1a31b523..00000000 --- a/bacnet-stack/ports/at91sam7s/av.h +++ /dev/null @@ -1,86 +0,0 @@ -/************************************************************************** -* -* 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" - -#ifndef MAX_ANALOG_VALUES -#define MAX_ANALOG_VALUES 4 -#endif - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - void Analog_Value_Property_Lists( - const int **pRequired, - const int **pOptional, - const int **pProprietary); - 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); - - bool Analog_Value_Present_Value_Set( - uint32_t object_instance, - float value, - uint8_t priority); - float Analog_Value_Present_Value( - uint32_t object_instance); - - void Analog_Value_Init( - void); - -#ifdef TEST -#include "ctest.h" - void testAnalog_Value( - Test * pTest); -#endif - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif diff --git a/bacnet-stack/ports/at91sam7s/bi.c b/bacnet-stack/ports/at91sam7s/bi.c index ed145b84..055db9be 100644 --- a/bacnet-stack/ports/at91sam7s/bi.c +++ b/bacnet-stack/ports/at91sam7s/bi.c @@ -32,6 +32,8 @@ #include "bacdcode.h" #include "bacenum.h" #include "config.h" +#include "bi.h" +#include "handlers.h" #define MAX_BINARY_INPUTS 8 #if (MAX_BINARY_INPUTS > 9) @@ -40,17 +42,53 @@ static BACNET_BINARY_PV Present_Value[MAX_BINARY_INPUTS]; -static void Binary_Input_Initialize( +/* These three arrays are used by the ReadPropertyMultiple handler */ +static const int Binary_Input_Properties_Required[] = { + PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, + PROP_OBJECT_TYPE, + PROP_PRESENT_VALUE, + PROP_STATUS_FLAGS, + PROP_EVENT_STATE, + PROP_OUT_OF_SERVICE, + PROP_POLARITY, + -1 +}; + +static const int Binary_Input_Properties_Optional[] = { + PROP_DESCRIPTION, + -1 +}; + +static const int Binary_Input_Properties_Proprietary[] = { + -1 +}; + +void Binary_Input_Property_Lists( + const int **pRequired, + const int **pOptional, + const int **pProprietary) +{ + if (pRequired) { + *pRequired = Binary_Input_Properties_Required; + } + if (pOptional) { + *pOptional = Binary_Input_Properties_Optional; + } + if (pProprietary) { + *pProprietary = Binary_Input_Properties_Proprietary; + } + + return; +} + +void Binary_Input_Init( void) { - static bool initialized = false; unsigned i; - if (!initialized) { - initialized = true; - for (i = 0; i < MAX_BINARY_INPUTS; i++) { - Present_Value[i] = BINARY_INACTIVE; - } + for (i = 0; i < MAX_BINARY_INPUTS; i++) { + Present_Value[i] = BINARY_INACTIVE; } } @@ -92,13 +130,12 @@ unsigned Binary_Input_Instance_To_Index( return index; } -static BACNET_BINARY_PV Binary_Input_Present_Value( +BACNET_BINARY_PV Binary_Input_Present_Value( uint32_t object_instance) { BACNET_BINARY_PV value = BINARY_INACTIVE; unsigned index = 0; - Binary_Input_Initialize(); index = Binary_Input_Instance_To_Index(object_instance); if (index < MAX_BINARY_INPUTS) { value = Present_Value[index]; @@ -122,33 +159,33 @@ char *Binary_Input_Name( /* return apdu length, or -1 on error */ /* assumption - object already exists, and has been bounds checked */ -int Binary_Input_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 Binary_Input_Read_Property( + BACNET_READ_PROPERTY_DATA *rpdata) { int apdu_len = 0; /* return value */ BACNET_BIT_STRING bit_string; BACNET_CHARACTER_STRING char_string; BACNET_POLARITY polarity = POLARITY_NORMAL; BACNET_BINARY_PV value = BINARY_INACTIVE; + uint8_t *apdu = NULL; - - Binary_Input_Initialize(); - switch (property) { + if ((rpdata == NULL) || + (rpdata->application_data == NULL) || + (rpdata->application_data_len == 0)) { + return 0; + } + apdu = rpdata->application_data; + switch (rpdata->object_property) { case PROP_OBJECT_IDENTIFIER: apdu_len = encode_application_object_id(&apdu[0], OBJECT_BINARY_INPUT, - object_instance); + rpdata->object_instance); break; case PROP_OBJECT_NAME: case PROP_DESCRIPTION: /* note: object name must be unique in our device */ characterstring_init_ansi(&char_string, - Binary_Input_Name(object_instance)); + Binary_Input_Name(rpdata->object_instance)); apdu_len = encode_application_character_string(&apdu[0], &char_string); break; @@ -157,7 +194,7 @@ int Binary_Input_Encode_Property_APDU( encode_application_enumerated(&apdu[0], OBJECT_BINARY_INPUT); break; case PROP_PRESENT_VALUE: - value = Binary_Input_Present_Value(object_instance); + value = Binary_Input_Present_Value(rpdata->object_instance); apdu_len = encode_application_enumerated(&apdu[0], value); break; case PROP_STATUS_FLAGS: @@ -181,74 +218,19 @@ int Binary_Input_Encode_Property_APDU( apdu_len = encode_application_enumerated(&apdu[0], polarity); break; default: - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_UNKNOWN_PROPERTY; + rpdata->error_class = ERROR_CLASS_PROPERTY; + rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY; apdu_len = -1; break; } /* only array properties can have array options */ if ((apdu_len >= 0) && - (array_index != BACNET_ARRAY_ALL)) { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; + (rpdata->array_index != BACNET_ARRAY_ALL)) { + rpdata->error_class = ERROR_CLASS_PROPERTY; + rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; apdu_len = -1; } return apdu_len; } -#ifdef TEST -#include -#include -#include "ctest.h" - -void testBinaryInput( - 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_OUTPUT; - uint32_t decoded_instance = 0; - uint32_t instance = 123; - BACNET_ERROR_CLASS error_class; - BACNET_ERROR_CODE error_code; - - - /* FIXME: we should do a lot more testing here... */ - len = - Binary_Input_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_INPUT); - ct_test(pTest, decoded_instance == instance); - - return; -} - -#ifdef TEST_BINARY_INPUT -int main( - void) -{ - Test *pTest; - bool rc; - - pTest = ct_create("BACnet Binary Input", NULL); - /* individual tests */ - rc = ct_addTestFunction(pTest, testBinaryInput); - assert(rc); - - ct_setStream(pTest, stdout); - ct_run(pTest); - (void) ct_report(pTest); - ct_destroy(pTest); - - return 0; -} -#endif /* TEST_BINARY_INPUT */ -#endif /* TEST */ diff --git a/bacnet-stack/ports/at91sam7s/bi.h b/bacnet-stack/ports/at91sam7s/bi.h deleted file mode 100644 index c87375d5..00000000 --- a/bacnet-stack/ports/at91sam7s/bi.h +++ /dev/null @@ -1,114 +0,0 @@ -/************************************************************************** -* -* 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 BI_H -#define BI_H - -#include -#include -#include "bacdef.h" -#include "cov.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - void Binary_Input_Property_Lists( - const int **pRequired, - const int **pOptional, - const int **pProprietary); - - bool Binary_Input_Valid_Instance( - uint32_t object_instance); - unsigned Binary_Input_Count( - void); - uint32_t Binary_Input_Index_To_Instance( - unsigned index); - unsigned Binary_Input_Instance_To_Index( - uint32_t instance); - bool Binary_Input_Object_Instance_Add( - uint32_t instance); - - char *Binary_Input_Name( - uint32_t object_instance); - bool Binary_Input_Name_Set( - uint32_t object_instance, - char *new_name); - - char *Binary_Input_Description( - uint32_t instance); - bool Binary_Input_Description_Set( - uint32_t instance, - char *new_name); - - char *Binary_Input_Inactive_Text( - uint32_t instance); - bool Binary_Input_Inactive_Text_Set( - uint32_t instance, - char *new_name); - char *Binary_Input_Active_Text( - uint32_t instance); - bool Binary_Input_Active_Text_Set( - uint32_t instance, - char *new_name); - - bool Binary_Input_Change_Of_Value( - uint32_t object_instance); - void Binary_Input_Change_Of_Value_Clear( - uint32_t object_instance); - bool Binary_Input_Encode_Value_List( - uint32_t object_instance, - BACNET_PROPERTY_VALUE * value_list); - - int Binary_Input_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_Input_Write_Property( - BACNET_WRITE_PROPERTY_DATA * wp_data, - BACNET_ERROR_CLASS * error_class, - BACNET_ERROR_CODE * error_code); - void Binary_Input_Init( - void); - BACNET_BINARY_PV Binary_Input_Present_Value( - uint32_t object_instance); - - bool Binary_Input_Present_Value_Set( - uint32_t object_instance, - bool value); - -#ifdef TEST -#include "ctest.h" - void testBinaryInput( - Test * pTest); -#endif - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif diff --git a/bacnet-stack/ports/at91sam7s/bv.c b/bacnet-stack/ports/at91sam7s/bv.c index c42a2caa..6b6b74b1 100644 --- a/bacnet-stack/ports/at91sam7s/bv.c +++ b/bacnet-stack/ports/at91sam7s/bv.c @@ -32,26 +32,61 @@ #include "bacdcode.h" #include "bacenum.h" #include "config.h" /* the custom stuff */ -#include "wp.h" +#include "bv.h" +#include "handlers.h" +#ifndef MAX_BINARY_VALUES #define MAX_BINARY_VALUES 8 +#endif #if (MAX_BINARY_VALUES > 9) #error Modify the Binary_Value_Name to handle multiple digits #endif static BACNET_BINARY_PV Present_Value[MAX_BINARY_VALUES]; -static void Binary_Value_Initialize( +/* These three arrays are used by the ReadPropertyMultiple handler */ +static const int Binary_Value_Properties_Required[] = { + PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, + PROP_OBJECT_TYPE, + PROP_PRESENT_VALUE, + PROP_STATUS_FLAGS, + PROP_EVENT_STATE, + PROP_OUT_OF_SERVICE, + -1 +}; + +static const int Binary_Value_Properties_Optional[] = { + PROP_DESCRIPTION, + -1 +}; + +static const int Binary_Value_Properties_Proprietary[] = { + -1 +}; + +void Binary_Value_Property_Lists( + const int **pRequired, + const int **pOptional, + const int **pProprietary) +{ + if (pRequired) + *pRequired = Binary_Value_Properties_Required; + if (pOptional) + *pOptional = Binary_Value_Properties_Optional; + if (pProprietary) + *pProprietary = Binary_Value_Properties_Proprietary; + + return; +} + +void Binary_Value_Init( void) { - static bool initialized = false; unsigned i; - if (!initialized) { - initialized = true; - for (i = 0; i < MAX_BINARY_VALUES; i++) { - Present_Value[i] = BINARY_INACTIVE; - } + for (i = 0; i < MAX_BINARY_VALUES; i++) { + Present_Value[i] = BINARY_INACTIVE; } } @@ -96,7 +131,6 @@ static BACNET_BINARY_PV Binary_Value_Present_Value( { BACNET_BINARY_PV value = BINARY_INACTIVE; - Binary_Value_Initialize(); if (object_instance < MAX_BINARY_VALUES) { value = Present_Value[object_instance]; } @@ -119,13 +153,8 @@ char *Binary_Value_Name( } /* 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 Binary_Value_Read_Property( + BACNET_READ_PROPERTY_DATA *rpdata) { int apdu_len = 0; /* return value */ BACNET_BIT_STRING bit_string; @@ -133,19 +162,26 @@ int Binary_Value_Encode_Property_APDU( BACNET_BINARY_PV present_value = BINARY_INACTIVE; BACNET_POLARITY polarity = POLARITY_NORMAL; - Binary_Value_Initialize(); - switch (property) { + uint8_t *apdu = NULL; + + if ((rpdata == NULL) || + (rpdata->application_data == NULL) || + (rpdata->application_data_len == 0)) { + return 0; + } + apdu = rpdata->application_data; + switch (rpdata->object_property) { case PROP_OBJECT_IDENTIFIER: apdu_len = encode_application_object_id(&apdu[0], OBJECT_BINARY_VALUE, - object_instance); + rpdata->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)); + Binary_Value_Name(rpdata->object_instance)); apdu_len = encode_application_character_string(&apdu[0], &char_string); break; @@ -154,7 +190,7 @@ int Binary_Value_Encode_Property_APDU( encode_application_enumerated(&apdu[0], OBJECT_BINARY_VALUE); break; case PROP_PRESENT_VALUE: - present_value = Binary_Value_Present_Value(object_instance); + present_value = Binary_Value_Present_Value(rpdata->object_instance); apdu_len = encode_application_enumerated(&apdu[0], present_value); break; case PROP_STATUS_FLAGS: @@ -179,16 +215,16 @@ int Binary_Value_Encode_Property_APDU( apdu_len = encode_application_enumerated(&apdu[0], polarity); break; default: - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_UNKNOWN_PROPERTY; + rpdata->error_class = ERROR_CLASS_PROPERTY; + rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY; apdu_len = -1; break; } /* only array properties can have array options */ if ((apdu_len >= 0) && - (array_index != BACNET_ARRAY_ALL)) { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; + (rpdata->array_index != BACNET_ARRAY_ALL)) { + rpdata->error_class = ERROR_CLASS_PROPERTY; + rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; apdu_len = -1; } @@ -197,9 +233,7 @@ int Binary_Value_Encode_Property_APDU( /* 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) + BACNET_WRITE_PROPERTY_DATA * wp_data) { bool status = false; /* return value */ unsigned int object_index = 0; @@ -209,8 +243,8 @@ bool Binary_Value_Write_Property( BACNET_APPLICATION_DATA_VALUE value; if (!Binary_Value_Valid_Instance(wp_data->object_instance)) { - *error_class = ERROR_CLASS_OBJECT; - *error_code = ERROR_CODE_UNKNOWN_OBJECT; + wp_data->error_class = ERROR_CLASS_OBJECT; + wp_data->error_code = ERROR_CODE_UNKNOWN_OBJECT; return false; } /* decode the some of the request */ @@ -246,40 +280,15 @@ bool Binary_Value_Write_Property( /* 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; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED; } else { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; } - } else if (value.tag == BACNET_APPLICATION_TAG_NULL) { -#if 0 - /* NOTE: this Binary Value has no priority array */ - 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; -#endif } else { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_INVALID_DATA_TYPE; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE; } break; #if 0 @@ -290,71 +299,17 @@ bool Binary_Value_Write_Property( Binary_Value_Out_Of_Service[object_index] = value.type.Boolean; status = true; } else { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_INVALID_DATA_TYPE; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE; } break; #endif default: - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_WRITE_ACCESS_DENIED; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->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/ports/at91sam7s/bv.h b/bacnet-stack/ports/at91sam7s/bv.h deleted file mode 100644 index 784acaff..00000000 --- a/bacnet-stack/ports/at91sam7s/bv.h +++ /dev/null @@ -1,81 +0,0 @@ -/************************************************************************** -* -* 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" - -#ifndef MAX_BINARY_VALUES -#define MAX_BINARY_VALUES 10 -#endif - - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - void Binary_Value_Property_Lists( - const int **pRequired, - const int **pOptional, - const int **pProprietary); - 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); - - void Binary_Value_Init( - void); - - 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/ports/at91sam7s/device.c b/bacnet-stack/ports/at91sam7s/device.c index e07f22fa..f20e285f 100644 --- a/bacnet-stack/ports/at91sam7s/device.c +++ b/bacnet-stack/ports/at91sam7s/device.c @@ -34,6 +34,7 @@ #include "dlmstp.h" #include "rs485.h" #include "version.h" +#include "handlers.h" /* objects */ #include "device.h" #include "ai.h" @@ -48,22 +49,455 @@ The properties that are constant can be hard coded into the read-property encoding. */ static uint32_t Object_Instance_Number = 12345; -static char Object_Name[32] = "ARM7 Device"; +static char My_Object_Name[32] = "ARM7 Device"; static BACNET_DEVICE_STATUS System_Status = STATUS_OPERATIONAL; - -BACNET_REINITIALIZED_STATE_OF_DEVICE Reinitialize_State = +static BACNET_REINITIALIZED_STATE_OF_DEVICE Reinitialize_State = REINITIALIZED_STATE_IDLE; -void Device_Reinit( +static struct object_functions { + BACNET_OBJECT_TYPE Object_Type; + object_init_function Object_Init; + object_count_function Object_Count; + object_index_to_instance_function Object_Index_To_Instance; + object_valid_instance_function Object_Valid_Instance; + object_name_function Object_Name; + read_property_function Object_Read_Property; + write_property_function Object_Write_Property; + rpm_property_lists_function Object_RPM_List; +} Object_Table[] = +{ + {OBJECT_DEVICE, + NULL,/* don't init - recursive! */ + Device_Count, + Device_Index_To_Instance, + Device_Valid_Object_Instance_Number, + Device_Name, + Device_Read_Property, + Device_Write_Property, + Device_Property_Lists}, + {OBJECT_ANALOG_INPUT, + Analog_Input_Init, + Analog_Input_Count, + Analog_Input_Index_To_Instance, + Analog_Input_Valid_Instance, + Analog_Input_Name, + Analog_Input_Read_Property, + NULL, + Analog_Input_Property_Lists}, + {OBJECT_ANALOG_VALUE, + Analog_Value_Init, + Analog_Value_Count, + Analog_Value_Index_To_Instance, + Analog_Value_Valid_Instance, + Analog_Value_Name, + Analog_Value_Read_Property, + Analog_Value_Write_Property, + Analog_Value_Property_Lists}, + {OBJECT_BINARY_INPUT, + Binary_Input_Init, + Binary_Input_Count, + Binary_Input_Index_To_Instance, + Binary_Input_Valid_Instance, + Binary_Input_Name, + Binary_Input_Read_Property, + NULL, + Binary_Input_Property_Lists}, + {OBJECT_BINARY_VALUE, + Binary_Value_Init, + Binary_Value_Count, + Binary_Value_Index_To_Instance, + Binary_Value_Valid_Instance, + Binary_Value_Name, + Binary_Value_Read_Property, + Binary_Value_Write_Property, + Binary_Value_Property_Lists}, + + {MAX_BACNET_OBJECT_TYPE, NULL, NULL, NULL, NULL, NULL, NULL, NULL} +}; + +/* These three arrays are used by the ReadPropertyMultiple handler */ +static const int Device_Properties_Required[] = { + PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, + PROP_OBJECT_TYPE, + PROP_SYSTEM_STATUS, + PROP_VENDOR_NAME, + PROP_VENDOR_IDENTIFIER, + PROP_MODEL_NAME, + PROP_FIRMWARE_REVISION, + PROP_APPLICATION_SOFTWARE_VERSION, + PROP_PROTOCOL_VERSION, + PROP_PROTOCOL_REVISION, + PROP_PROTOCOL_SERVICES_SUPPORTED, + PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED, + PROP_OBJECT_LIST, + PROP_MAX_APDU_LENGTH_ACCEPTED, + PROP_SEGMENTATION_SUPPORTED, + PROP_APDU_TIMEOUT, + PROP_NUMBER_OF_APDU_RETRIES, + PROP_MAX_MASTER, + PROP_MAX_INFO_FRAMES, + PROP_DEVICE_ADDRESS_BINDING, + PROP_DATABASE_REVISION, + -1 +}; + +static const int Device_Properties_Optional[] = { + PROP_DESCRIPTION, + -1 +}; + +static const int Device_Properties_Proprietary[] = { + 9600, + -1 +}; + +void Device_Property_Lists( + const int **pRequired, + const int **pOptional, + const int **pProprietary) +{ + if (pRequired) + *pRequired = Device_Properties_Required; + if (pOptional) + *pOptional = Device_Properties_Optional; + if (pProprietary) + *pProprietary = Device_Properties_Proprietary; + + return; +} + +/* Encodes the property APDU and returns the length, + or sets the error, and returns -1 */ +int Device_Objects_Read_Property( + BACNET_READ_PROPERTY_DATA *rpdata) +{ + int apdu_len = -1; + unsigned index = 0; + struct object_functions *pObject = NULL; + bool found = false; + + /* initialize the default return values */ + rpdata->error_class = ERROR_CLASS_OBJECT; + rpdata->error_code = ERROR_CODE_UNKNOWN_OBJECT; + pObject = &Object_Table[0]; + while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) { + /* handle each object type */ + if (pObject->Object_Type == rpdata->object_type) { + found = true; + if (pObject->Object_Valid_Instance && + pObject->Object_Valid_Instance(rpdata->object_instance)) { + if (pObject->Object_Read_Property) { + apdu_len = pObject->Object_Read_Property(rpdata); + } + } else { + rpdata->error_class = ERROR_CLASS_OBJECT; + rpdata->error_code = ERROR_CODE_UNKNOWN_OBJECT; + } + break; + } + index++; + pObject = &Object_Table[index]; + } + if (!found) { + rpdata->error_class = ERROR_CLASS_OBJECT; + rpdata->error_code = ERROR_CODE_UNSUPPORTED_OBJECT_TYPE; + } + + return apdu_len; +} + +bool Device_Objects_Write_Property( + BACNET_WRITE_PROPERTY_DATA * wp_data) +{ + int apdu_len = -1; + unsigned index = 0; + struct object_functions *pObject = NULL; + bool found = false; + + /* initialize the default return values */ + wp_data->error_class = ERROR_CLASS_OBJECT; + wp_data->error_code = ERROR_CODE_UNKNOWN_OBJECT; + pObject = &Object_Table[0]; + while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) { + /* handle each object type */ + if (pObject->Object_Type == wp_data->object_type) { + found = true; + if (pObject->Object_Valid_Instance && + pObject->Object_Valid_Instance(wp_data->object_instance)) { + if (pObject->Object_Write_Property) { + apdu_len = pObject->Object_Write_Property(wp_data); + } else { + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED; + } + } else { + wp_data->error_class = ERROR_CLASS_OBJECT; + wp_data->error_code = ERROR_CODE_UNKNOWN_OBJECT; + } + break; + } + index++; + pObject = &Object_Table[index]; + } + if (!found) { + wp_data->error_class = ERROR_CLASS_OBJECT; + wp_data->error_code = ERROR_CODE_UNSUPPORTED_OBJECT_TYPE; + } + + return apdu_len; +} + +static unsigned property_list_count( + const int *pList) +{ + unsigned property_count = 0; + + if (pList) { + while (*pList != -1) { + property_count++; + pList++; + } + } + + return property_count; +} + +/* for a given object type, returns the special property list */ +static void Device_Objects_Property_List( + BACNET_OBJECT_TYPE object_type, + struct special_property_list_t *pPropertyList) +{ + rpm_property_lists_function object_property_list = NULL; + unsigned index = 0; + struct object_functions *pObject = NULL; + bool found = false; + + pPropertyList->Required.pList = NULL; + pPropertyList->Optional.pList = NULL; + pPropertyList->Proprietary.pList = NULL; + pObject = &Object_Table[0]; + while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) { + /* handle each object type */ + if (pObject->Object_Type == object_type) { + found = true; + object_property_list = pObject->Object_RPM_List; + break; + } + index++; + pObject = &Object_Table[index]; + } + if (found && object_property_list) { + object_property_list( + &pPropertyList->Required.pList, + &pPropertyList->Optional.pList, + &pPropertyList->Proprietary.pList); + } + /* fill the count */ + if (pPropertyList->Required.pList) { + pPropertyList->Required.count = + property_list_count(pPropertyList->Required.pList); + } else { + pPropertyList->Required.count = 0; + } + if (pPropertyList->Optional.pList) { + pPropertyList->Optional.count = + property_list_count(pPropertyList->Optional.pList); + } else { + pPropertyList->Optional.count = 0; + } + if (pPropertyList->Proprietary.pList) { + pPropertyList->Proprietary.count = + property_list_count(pPropertyList->Proprietary.pList); + } else { + pPropertyList->Proprietary.count = 0; + } + + return; +} + +/* Since many network clients depend on the object list */ +/* for discovery, it must be consistent! */ +unsigned Device_Object_List_Count( void) { - dcc_set_status_duration(COMMUNICATION_ENABLE, 0); - Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE); + unsigned count = 0; /* number of objects */ + unsigned index = 0; /* loop counter */ + struct object_functions *pObject = NULL; + + /* initialize the default return values */ + pObject = &Object_Table[0]; + while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) { + if (pObject->Object_Count) { + count += pObject->Object_Count(); + } + index++; + pObject = &Object_Table[index]; + } + + return count; +} + +bool Device_Object_List_Identifier( + unsigned array_index, + int *object_type, + uint32_t * instance) +{ + bool status = false; + unsigned count = 0; + unsigned object_index = 0; + unsigned index = 0; /* loop counter */ + struct object_functions *pObject = NULL; + + /* array index zero is length - so invalid */ + if (array_index == 0) { + return status; + } + object_index = array_index - 1; + /* initialize the default return values */ + pObject = &Object_Table[0]; + while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) { + if (pObject->Object_Count && + pObject->Object_Index_To_Instance) { + object_index -= count; + count = pObject->Object_Count(); + if (object_index < count) { + *object_type = pObject->Object_Type; + *instance = pObject->Object_Index_To_Instance(object_index); + status = true; + break; + } + } + index++; + pObject = &Object_Table[index]; + } + + return status; +} + +bool Device_Valid_Object_Name( + const char *object_name, + int *object_type, + uint32_t * object_instance) +{ + bool found = false; + int type = 0; + uint32_t instance; + unsigned max_objects = 0, i = 0; + bool check_id = false; + char *name = NULL; + + max_objects = Device_Object_List_Count(); + for (i = 0; i < max_objects; i++) { + check_id = Device_Object_List_Identifier(i, &type, &instance); + if (check_id) { + name = Device_Valid_Object_Id(type, instance); + if (strcmp(name, object_name) == 0) { + found = true; + if (object_type) { + *object_type = type; + } + if (object_instance) { + *object_instance = instance; + } + break; + } + } + } + + return found; +} + +/* returns the name or NULL if not found */ +char *Device_Valid_Object_Id( + int object_type, + uint32_t object_instance) +{ + char *name = NULL; /* return value */ + unsigned index = 0; /* loop counter */ + struct object_functions *pObject = NULL; + + pObject = &Object_Table[0]; + while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) { + if ((pObject->Object_Type == object_type) && + (pObject->Object_Name)) { + name = pObject->Object_Name(object_instance); + break; + } + index++; + pObject = &Object_Table[index]; + } + + return name; +} + +bool Device_Reinitialize( + BACNET_REINITIALIZE_DEVICE_DATA *rd_data) +{ + bool status = false; + + if (characterstring_ansi_same(&rd_data->password, "Jesus")) { + switch (rd_data->state) { + case REINITIALIZED_STATE_COLD_START: + break; + case REINITIALIZED_STATE_WARM_START: + break; + case REINITIALIZED_STATE_START_BACKUP: + break; + case REINITIALIZED_STATE_END_BACKUP: + break; + case REINITIALIZED_STATE_START_RESTORE: + break; + case REINITIALIZED_STATE_END_RESTORE: + break; + case REINITIALIZED_STATE_ABORT_RESTORE: + break; + default: + break; + } + Reinitialize_State = rd_data->state; + /* Note: you could use a mix of state + and password to multiple things */ + /* note: you probably want to restart *after* the + simple ack has been sent from the return handler + so just set a flag from here */ + dcc_set_status_duration(COMMUNICATION_ENABLE, 0); + status = true; + } else { + rd_data->error_class = ERROR_CLASS_SECURITY; + rd_data->error_code = ERROR_CODE_PASSWORD_FAILURE; + } + + return status; +} + +unsigned Device_Count(void) +{ + return 1; +} + +uint32_t Device_Index_To_Instance( + unsigned index) +{ + return Object_Instance_Number; +} + +char *Device_Name( + uint32_t object_instance) +{ + if (object_instance == Object_Instance_Number) { + return My_Object_Name; + } + + return NULL; } void Device_Init( void) { + unsigned index = 0; /* loop counter */ + struct object_functions *pObject = NULL; + Reinitialize_State = REINITIALIZED_STATE_IDLE; dcc_set_status_duration(COMMUNICATION_ENABLE, 0); /* FIXME: Get the data from the eeprom */ @@ -71,6 +505,19 @@ void Device_Init( (char *)&Object_Instance_Number, sizeof(Object_Instance_Number), EEPROM_BACNET_ID_ADDR); */ + handler_read_property_function_set(Device_Objects_Read_Property); + handler_rpm_function_set(Device_Objects_Read_Property); + handler_rpm_list_set(Device_Objects_Property_List); + handler_write_property_function_set(Device_Objects_Write_Property); + handler_reinitialize_device_function_set(Device_Reinitialize); + pObject = &Object_Table[0]; + while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) { + if (pObject->Object_Init) { + pObject->Object_Init(); + } + index++; + pObject = &Object_Table[index]; + } } /* methods to manipulate the data */ @@ -113,11 +560,17 @@ BACNET_DEVICE_STATUS Device_System_Status( return System_Status; } -void Device_Set_System_Status( - BACNET_DEVICE_STATUS status) +int Device_Set_System_Status( + BACNET_DEVICE_STATUS status, + bool local) { - if (status < MAX_DEVICE_STATUS) + int result = 0; /*return value - 0 = ok, -1 = bad value, -2 = not allowed */ + + if (status < MAX_DEVICE_STATUS) { System_Status = status; + } + + return result; } uint16_t Device_Vendor_Identifier( @@ -144,106 +597,15 @@ BACNET_SEGMENTATION Device_Segmentation_Supported( return SEGMENTATION_NONE; } -uint8_t Device_Database_Revision( +uint32_t Device_Database_Revision( void) { return 0; } -unsigned Device_Object_List_Count( - void) -{ - unsigned count = 1; /* at least 1 for device object */ - - /* FIXME: add objects as needed */ - count += Binary_Input_Count(); - count += Binary_Value_Count(); - count += Analog_Input_Count(); - count += Analog_Value_Count(); - - return count; -} - -bool Device_Object_List_Identifier( - unsigned array_index, - int *object_type, - uint32_t * instance) -{ - bool status = false; - unsigned object_index = 0; - unsigned object_count = 0; - - /* device object */ - if (array_index == 1) { - *object_type = OBJECT_DEVICE; - *instance = Object_Instance_Number; - status = true; - } - /* normalize the index since - we know it is not the previous objects */ - /* array index starts at 1 */ - object_index = array_index - 1; - /* 1 for the device object */ - object_count = 1; - /* FIXME: add objects as needed */ - /* binary value objects */ - if (!status) { - object_index -= object_count; - object_count = Binary_Value_Count(); - /* is it a valid index for this object? */ - if (object_index < object_count) { - *object_type = OBJECT_BINARY_VALUE; - *instance = Binary_Value_Index_To_Instance(object_index); - status = true; - } - } - /* analog input objects */ - if (!status) { - /* array index starts at 1, and 1 for the device object */ - object_index -= object_count; - object_count = Analog_Value_Count(); - if (object_index < object_count) { - *object_type = OBJECT_ANALOG_VALUE; - *instance = Analog_Value_Index_To_Instance(object_index); - status = true; - } - } - /* analog input objects */ - if (!status) { - /* array index starts at 1, and 1 for the device object */ - object_index -= object_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; - } - } - /* binary input objects */ - if (!status) { - /* normalize the index since - we know it is not the previous objects */ - object_index -= object_count; - object_count = Binary_Input_Count(); - /* is it a valid index for this object? */ - if (object_index < object_count) { - *object_type = OBJECT_BINARY_INPUT; - *instance = Binary_Input_Index_To_Instance(object_index); - status = true; - } - } - - return status; -} - /* return the length of the apdu encoded or -1 for error */ -int Device_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 Device_Read_Property( + BACNET_READ_PROPERTY_DATA *rpdata) { int apdu_len = 0; /* return value */ int len = 0; /* apdu len intermediate value */ @@ -255,17 +617,24 @@ int Device_Encode_Property_APDU( unsigned count = 0; BACNET_TIME local_time; BACNET_DATE local_date; + uint8_t *apdu = NULL; + struct object_functions *pObject = NULL; + bool found = false; - object_instance = object_instance; - /* FIXME: change the hardcoded names to suit your application */ - switch (property) { + if ((rpdata == NULL) || + (rpdata->application_data == NULL) || + (rpdata->application_data_len == 0)) { + return 0; + } + apdu = rpdata->application_data; + switch (rpdata->object_property) { case PROP_OBJECT_IDENTIFIER: apdu_len = encode_application_object_id(&apdu[0], OBJECT_DEVICE, - Object_Instance_Number); + rpdata->object_instance); break; case PROP_OBJECT_NAME: - characterstring_init_ansi(&char_string, Object_Name); + characterstring_init_ansi(&char_string, My_Object_Name); apdu_len = encode_application_character_string(&apdu[0], &char_string); break; @@ -341,31 +710,36 @@ int Device_Encode_Property_APDU( not a list of objects that this device can access */ bitstring_init(&bit_string); for (i = 0; i < MAX_ASHRAE_OBJECT_TYPE; i++) { - /* FIXME: if ReadProperty used an array of Functions... */ /* initialize all the object types to not-supported */ bitstring_set_bit(&bit_string, (uint8_t) i, false); } - /* FIXME: indicate the objects that YOU support */ - bitstring_set_bit(&bit_string, OBJECT_DEVICE, true); - bitstring_set_bit(&bit_string, OBJECT_ANALOG_VALUE, true); - bitstring_set_bit(&bit_string, OBJECT_BINARY_VALUE, true); - bitstring_set_bit(&bit_string, OBJECT_ANALOG_INPUT, true); - bitstring_set_bit(&bit_string, OBJECT_BINARY_INPUT, true); + /* set the object types with objects to supported */ + i = 0; + pObject = &Object_Table[i]; + while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) { + if ((pObject->Object_Count) && + (pObject->Object_Count() > 0)) { + bitstring_set_bit(&bit_string, pObject->Object_Type, true); + } + i++; + pObject = &Object_Table[i]; + } apdu_len = encode_application_bitstring(&apdu[0], &bit_string); break; case PROP_OBJECT_LIST: count = Device_Object_List_Count(); /* Array element zero is the number of objects in the list */ - if (array_index == 0) + if (rpdata->array_index == 0) apdu_len = encode_application_unsigned(&apdu[0], count); /* if no index was specified, then try to encode the entire list */ /* into one packet. Note that more than likely you will have */ /* to return an error if the number of encoded objects exceeds */ /* your maximum APDU size. */ - else if (array_index == BACNET_ARRAY_ALL) { + else if (rpdata->array_index == BACNET_ARRAY_ALL) { for (i = 1; i <= count; i++) { - if (Device_Object_List_Identifier(i, &object_type, - &instance)) { + found = Device_Object_List_Identifier(i, &object_type, + &instance); + if (found) { len = encode_application_object_id(&apdu[apdu_len], object_type, instance); @@ -373,28 +747,28 @@ int Device_Encode_Property_APDU( /* assume next one is the same size as this one */ /* can we all fit into the APDU? */ if ((apdu_len + len) >= MAX_APDU) { - *error_class = ERROR_CLASS_SERVICES; - *error_code = ERROR_CODE_NO_SPACE_FOR_OBJECT; + rpdata->error_class = ERROR_CLASS_SERVICES; + rpdata->error_code = ERROR_CODE_NO_SPACE_FOR_OBJECT; apdu_len = -1; break; } } else { /* error: internal error? */ - *error_class = ERROR_CLASS_SERVICES; - *error_code = ERROR_CODE_OTHER; + rpdata->error_class = ERROR_CLASS_SERVICES; + rpdata->error_code = ERROR_CODE_OTHER; apdu_len = -1; break; } } } else { - if (Device_Object_List_Identifier(array_index, &object_type, + if (Device_Object_List_Identifier(rpdata->array_index, &object_type, &instance)) apdu_len = encode_application_object_id(&apdu[0], object_type, instance); else { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_INVALID_ARRAY_INDEX; + rpdata->error_class = ERROR_CLASS_PROPERTY; + rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX; apdu_len = -1; } } @@ -460,17 +834,17 @@ int Device_Encode_Property_APDU( encode_application_unsigned(&apdu[0], RS485_Get_Baud_Rate()); break; default: - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_UNKNOWN_PROPERTY; + rpdata->error_class = ERROR_CLASS_PROPERTY; + rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY; apdu_len = -1; break; } /* only array properties can have array options */ if ((apdu_len >= 0) && - (property != PROP_OBJECT_LIST) && - (array_index != BACNET_ARRAY_ALL)) { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; + (rpdata->object_property != PROP_OBJECT_LIST) && + (rpdata->array_index != BACNET_ARRAY_ALL)) { + rpdata->error_class = ERROR_CLASS_PROPERTY; + rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; apdu_len = -1; } @@ -478,17 +852,15 @@ int Device_Encode_Property_APDU( } bool Device_Write_Property( - BACNET_WRITE_PROPERTY_DATA * wp_data, - BACNET_ERROR_CLASS * error_class, - BACNET_ERROR_CODE * error_code) + BACNET_WRITE_PROPERTY_DATA * wp_data) { bool status = false; /* return value */ int len = 0; BACNET_APPLICATION_DATA_VALUE value; if (!Device_Valid_Object_Instance_Number(wp_data->object_instance)) { - *error_class = ERROR_CLASS_OBJECT; - *error_code = ERROR_CODE_UNKNOWN_OBJECT; + wp_data->error_class = ERROR_CLASS_OBJECT; + wp_data->error_code = ERROR_CODE_UNKNOWN_OBJECT; return false; } /* decode the some of the request */ @@ -506,12 +878,12 @@ bool Device_Write_Property( /* we could send an I-Am broadcast to let the world know */ status = true; } else { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; } } else { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_INVALID_DATA_TYPE; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE; } break; case PROP_MAX_INFO_FRAMES: @@ -520,12 +892,12 @@ bool Device_Write_Property( dlmstp_set_max_info_frames(value.type.Unsigned_Int); status = true; } else { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; } } else { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_INVALID_DATA_TYPE; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE; } break; case PROP_MAX_MASTER: @@ -535,12 +907,12 @@ bool Device_Write_Property( dlmstp_set_max_master(value.type.Unsigned_Int); status = true; } else { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; } } else { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_INVALID_DATA_TYPE; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE; } break; case PROP_OBJECT_NAME: @@ -560,16 +932,16 @@ bool Device_Write_Property( Disallow setting the Device Object Name to any objects in the device. */ } else { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY; } } else { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED; } } else { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_INVALID_DATA_TYPE; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE; } break; case 9600: @@ -578,17 +950,17 @@ bool Device_Write_Property( RS485_Set_Baud_Rate(value.type.Unsigned_Int); status = true; } else { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; } } else { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_INVALID_DATA_TYPE; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE; } break; default: - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_WRITE_ACCESS_DENIED; + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED; break; } diff --git a/bacnet-stack/ports/at91sam7s/device.h b/bacnet-stack/ports/at91sam7s/device.h deleted file mode 100644 index 24d6407e..00000000 --- a/bacnet-stack/ports/at91sam7s/device.h +++ /dev/null @@ -1,176 +0,0 @@ -/*####COPYRIGHTBEGIN#### - ------------------------------------------- - Copyright (C) 2005 Steve Karg - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to: - The Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA. - - As a special exception, if other files instantiate templates or - use macros or inline functions from this file, or you compile - this file and link it with other works to produce a work based - on this file, this file does not by itself cause the resulting - work to be covered by the GNU General Public License. However - the source code for this file must still be made available in - accordance with section (3) of the GNU General Public License. - - This exception does not invalidate any other reasons why a work - based on this file might be covered by the GNU General Public - License. - ------------------------------------------- -####COPYRIGHTEND####*/ -#ifndef DEVICE_H -#define DEVICE_H - -#include -#include -#include "bacdef.h" -#include "bacenum.h" -#include "wp.h" -#include "readrange.h" - -typedef unsigned ( - *object_count_function) ( - void); -typedef uint32_t( - *object_index_to_instance_function) - ( - unsigned index); -typedef char *( - *object_name_function) - ( - uint32_t object_instance); - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - void Device_Object_Function_Set( - BACNET_OBJECT_TYPE object_type, - object_count_function count_function, - object_index_to_instance_function index_function, - object_name_function name_function); - - void Device_Init( - void); - - void Device_Property_Lists( - const int **pRequired, - const int **pOptional, - const int **pProprietary); - - uint32_t Device_Object_Instance_Number( - void); - bool Device_Set_Object_Instance_Number( - uint32_t object_id); - bool Device_Valid_Object_Instance_Number( - uint32_t object_id); - unsigned Device_Object_List_Count( - void); - bool Device_Object_List_Identifier( - unsigned array_index, - int *object_type, - uint32_t * instance); - - BACNET_DEVICE_STATUS Device_System_Status( - void); - void Device_Set_System_Status( - BACNET_DEVICE_STATUS status); - - const char *Device_Vendor_Name( - void); - - uint16_t Device_Vendor_Identifier( - void); - - const char *Device_Model_Name( - void); - bool Device_Set_Model_Name( - const char *name, - size_t length); - - const char *Device_Firmware_Revision( - void); - - const char *Device_Application_Software_Version( - void); - bool Device_Set_Application_Software_Version( - const char *name, - size_t length); - - bool Device_Set_Object_Name( - const char *name, - size_t length); - const char *Device_Object_Name( - void); - - const char *Device_Description( - void); - bool Device_Set_Description( - const char *name, - size_t length); - - const char *Device_Location( - void); - bool Device_Set_Location( - const char *name, - size_t length); - - /* some stack-centric constant values - no set methods */ - uint8_t Device_Protocol_Version( - void); - uint8_t Device_Protocol_Revision( - void); - BACNET_SEGMENTATION Device_Segmentation_Supported( - void); - - uint8_t Device_Database_Revision( - void); - void Device_Set_Database_Revision( - uint8_t revision); - - bool Device_Valid_Object_Name( - const char *object_name, - int *object_type, - uint32_t * object_instance); - char *Device_Valid_Object_Id( - int object_type, - uint32_t object_instance); - - int Device_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 Device_Write_Property( - BACNET_WRITE_PROPERTY_DATA * wp_data, - BACNET_ERROR_CLASS * error_class, - BACNET_ERROR_CODE * error_code); - - bool DeviceGetRRInfo( - uint32_t Object, /* Which particular object - obviously not important for device object */ - BACNET_PROPERTY_ID Property, /* Which property */ - RR_PROP_INFO *pInfo, /* Where to put the information */ - BACNET_ERROR_CLASS *error_class, - BACNET_ERROR_CODE *error_code); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif diff --git a/bacnet-stack/ports/at91sam7s/h_rp.c b/bacnet-stack/ports/at91sam7s/h_rp.c deleted file mode 100644 index 23c3188f..00000000 --- a/bacnet-stack/ports/at91sam7s/h_rp.c +++ /dev/null @@ -1,198 +0,0 @@ -/************************************************************************** -* -* Copyright (C) 2005 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. -* -*********************************************************************/ -#include -#include -#include -#include -#include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "bacerror.h" -#include "apdu.h" -#include "npdu.h" -#include "abort.h" -#include "rp.h" -/* demo objects */ -#include "device.h" -#include "ai.h" -#include "av.h" -#include "bi.h" -#include "bv.h" - -static uint8_t Temp_Buf[MAX_APDU] = { 0 }; - -/* Encodes the property APDU and returns the length, - or sets the error, and returns -1 */ -int Encode_Property_APDU( - uint8_t * apdu, - BACNET_OBJECT_TYPE object_type, - uint32_t object_instance, - BACNET_PROPERTY_ID property, - int32_t array_index, - BACNET_ERROR_CLASS * error_class, - BACNET_ERROR_CODE * error_code) -{ - int apdu_len = -1; - - /* initialize the default return values */ - *error_class = ERROR_CLASS_OBJECT; - *error_code = ERROR_CODE_UNKNOWN_OBJECT; - /* handle each object type */ - switch (object_type) { - case OBJECT_DEVICE: - if (Device_Valid_Object_Instance_Number(object_instance)) { - apdu_len = - Device_Encode_Property_APDU(&apdu[0], object_instance, - property, array_index, error_class, error_code); - } - break; - case OBJECT_ANALOG_INPUT: - if (Analog_Input_Valid_Instance(object_instance)) { - apdu_len = - Analog_Input_Encode_Property_APDU(&apdu[0], - object_instance, property, array_index, error_class, - error_code); - } - break; - case OBJECT_ANALOG_VALUE: - if (Analog_Value_Valid_Instance(object_instance)) { - apdu_len = - Analog_Value_Encode_Property_APDU(&apdu[0], - object_instance, property, array_index, error_class, - error_code); - } - break; - case OBJECT_BINARY_INPUT: - if (Binary_Input_Valid_Instance(object_instance)) { - apdu_len = - Binary_Input_Encode_Property_APDU(&apdu[0], - object_instance, property, array_index, error_class, - error_code); - } - break; - case OBJECT_BINARY_VALUE: - if (Binary_Value_Valid_Instance(object_instance)) { - apdu_len = - Binary_Value_Encode_Property_APDU(&apdu[0], - object_instance, property, array_index, error_class, - error_code); - } - break; - default: - *error_class = ERROR_CLASS_OBJECT; - *error_code = ERROR_CODE_UNSUPPORTED_OBJECT_TYPE; - break; - } - - return apdu_len; -} - -void handler_read_property( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src, - BACNET_CONFIRMED_SERVICE_DATA * service_data) -{ - BACNET_READ_PROPERTY_DATA data; - int len = 0; - int pdu_len = 0; - BACNET_NPDU_DATA npdu_data; - bool error = false; - int bytes_sent = 0; - BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT; - BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT; - BACNET_ADDRESS my_address; - - /* encode the NPDU portion of the packet */ - datalink_get_my_address(&my_address); - npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); - pdu_len = - npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address, - &npdu_data); - if (service_data->segmented_message) { - /* we don't support segmentation - send an abort */ - len = - abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, - true); - goto RP_ABORT; - } - len = rp_decode_service_request(service_request, service_len, &data); - if (len < 0) { - /* bad decoding - send an abort */ - len = - abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, ABORT_REASON_OTHER, true); - goto RP_ABORT; - } - /* most cases will be error */ - error = true; - len = - Encode_Property_APDU(&Temp_Buf[0], data.object_type, - data.object_instance, data.object_property, data.array_index, - &error_class, &error_code); - if (len >= 0) { - /* encode the APDU portion of the packet */ - data.application_data = &Temp_Buf[0]; - data.application_data_len = len; - /* FIXME: probably need a length limitation sent with encode */ - len = - rp_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, &data); - if (len > service_data->max_resp) { - /* too big for the sender - send an abort */ - len = - abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, - true); - goto RP_ABORT; - } else { - error = false; - } - } - if (error) { - if (len == -2) { - /* BACnet APDU too small to fit data, so proper response is Abort */ - len = - abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, - ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true); - goto RP_ABORT; - } - len = - bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, SERVICE_CONFIRMED_READ_PROPERTY, - error_class, error_code); - } - RP_ABORT: - pdu_len += len; - bytes_sent = - datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], - pdu_len); - - return; -} diff --git a/bacnet-stack/ports/at91sam7s/h_wp.c b/bacnet-stack/ports/at91sam7s/h_wp.c deleted file mode 100644 index ae4b6aba..00000000 --- a/bacnet-stack/ports/at91sam7s/h_wp.c +++ /dev/null @@ -1,148 +0,0 @@ -/************************************************************************** -* -* Copyright (C) 2005 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. -* -*********************************************************************/ -#include -#include -#include -#include -#include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "bacerror.h" -#include "apdu.h" -#include "npdu.h" -#include "abort.h" -#include "wp.h" -/* demo objects */ -#include "device.h" -#include "ai.h" -#include "av.h" -#include "bi.h" -#include "bv.h" - -/* too big to reside on stack frame for PIC */ -static BACNET_WRITE_PROPERTY_DATA wp_data; - -void handler_write_property( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src, - BACNET_CONFIRMED_SERVICE_DATA * service_data) -{ - int len = 0; - int pdu_len = 0; - BACNET_NPDU_DATA npdu_data; - BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT; - BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT; - int bytes_sent = 0; - BACNET_ADDRESS my_address; - - /* encode the NPDU portion of the packet */ - datalink_get_my_address(&my_address); - npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); - pdu_len = - npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address, - &npdu_data); - if (service_data->segmented_message) { - len = - abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, - true); - goto WP_ABORT; - } - /* decode the service request only */ - len = wp_decode_service_request(service_request, service_len, &wp_data); - /* bad decoding or something we didn't understand - send an abort */ - if (len <= 0) { - len = - abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, ABORT_REASON_OTHER, true); - goto WP_ABORT; - } - /* handle the object type */ - switch (wp_data.object_type) { - case OBJECT_DEVICE: - if (Device_Write_Property(&wp_data, &error_class, &error_code)) { - len = - encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY); - } else { - len = - bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY, - error_class, error_code); - } - break; - case OBJECT_ANALOG_INPUT: - case OBJECT_BINARY_INPUT: - error_class = ERROR_CLASS_PROPERTY; - error_code = ERROR_CODE_WRITE_ACCESS_DENIED; - len = - bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY, - error_class, error_code); - break; - case OBJECT_BINARY_VALUE: - if (Binary_Value_Write_Property(&wp_data, &error_class, - &error_code)) { - len = - encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY); - } else { - len = - bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY, - error_class, error_code); - } - break; - case OBJECT_ANALOG_VALUE: - if (Analog_Value_Write_Property(&wp_data, &error_class, - &error_code)) { - len = - encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY); - } else { - len = - bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY, - error_class, error_code); - } - break; - default: - len = - bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY, - error_class, error_code); - break; - } - WP_ABORT: - pdu_len += len; - bytes_sent = - datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], - pdu_len); - - return; -} diff --git a/bacnet-stack/ports/at91sam7s/main.c b/bacnet-stack/ports/at91sam7s/main.c index 3337f7a9..8010561c 100644 --- a/bacnet-stack/ports/at91sam7s/main.c +++ b/bacnet-stack/ports/at91sam7s/main.c @@ -142,15 +142,21 @@ static inline void bacnet_init( dlmstp_init(NULL); #endif Device_Set_Object_Instance_Number(22222); + /* initialize objects */ + Device_Init(); /* set up our confirmed service unrecognized service handler - required! */ apdu_set_unrecognized_service_handler_handler (handler_unrecognized_service); + apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_HAS, + handler_who_has); /* we need to handle who-is to support dynamic device binding */ apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is); /* Set the handlers for any confirmed services that we support. */ /* We must implement read property - it's required! */ apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); + apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE, + handler_read_property_multiple); apdu_set_confirmed_handler(SERVICE_CONFIRMED_REINITIALIZE_DEVICE, handler_reinitialize_device); apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY,