From 96e5e43938f899d3bfb65377c7631bc350145a72 Mon Sep 17 00:00:00 2001 From: skarg Date: Tue, 24 May 2005 10:47:46 +0000 Subject: [PATCH] refactored and added return error codes to read property functions. --- bacnet-stack/ai.c | 8 +++- bacnet-stack/ai.h | 4 +- bacnet-stack/ao.c | 77 +++++++++++++++++------------- bacnet-stack/ao.h | 4 +- bacnet-stack/device.c | 62 ++++++++++++------------ bacnet-stack/device.h | 4 +- bacnet-stack/handlers.c | 102 ++++++++++++---------------------------- 7 files changed, 122 insertions(+), 139 deletions(-) diff --git a/bacnet-stack/ai.c b/bacnet-stack/ai.c index 1a63698e..d2845e42 100644 --- a/bacnet-stack/ai.c +++ b/bacnet-stack/ai.c @@ -65,7 +65,9 @@ int Analog_Input_Encode_Property_APDU( uint8_t *apdu, uint32_t object_instance, BACNET_PROPERTY_ID property, - int32_t array_index) + int32_t array_index, + BACNET_ERROR_CLASS *error_class, + BACNET_ERROR_CODE *error_code) { int apdu_len = 0; // return value BACNET_BIT_STRING bit_string; @@ -107,7 +109,9 @@ int Analog_Input_Encode_Property_APDU( apdu_len = encode_tagged_enumerated(&apdu[0],UNITS_PERCENT); break; default: - break; + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_UNKNOWN_PROPERTY; + break; } return apdu_len; diff --git a/bacnet-stack/ai.h b/bacnet-stack/ai.h index 2fd4493c..4a2b5343 100644 --- a/bacnet-stack/ai.h +++ b/bacnet-stack/ai.h @@ -37,7 +37,9 @@ int Analog_Input_Encode_Property_APDU( uint8_t *apdu, uint32_t object_instance, BACNET_PROPERTY_ID property, - int32_t array_index); + int32_t array_index, + BACNET_ERROR_CLASS *error_class, + BACNET_ERROR_CODE *error_code); #ifdef TEST #include "ctest.h" diff --git a/bacnet-stack/ao.c b/bacnet-stack/ao.c index 151d5285..d205b3d6 100644 --- a/bacnet-stack/ao.c +++ b/bacnet-stack/ao.c @@ -145,13 +145,15 @@ int Analog_Output_Encode_Property_APDU( uint8_t *apdu, uint32_t object_instance, BACNET_PROPERTY_ID property, - int32_t array_index) + 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; char text_string[32] = {""}; - float value = 1.41421356; + float real_value = 1.41421356; unsigned object_index = 0; unsigned i = 0; @@ -164,7 +166,7 @@ int Analog_Output_Encode_Property_APDU( break; case PROP_OBJECT_NAME: case PROP_DESCRIPTION: - // note: the object name must be unique in this device + // note: the object name must be unique within this device sprintf(text_string,"ANALOG OUTPUT %d",object_instance); apdu_len = encode_tagged_character_string(&apdu[0], text_string); break; @@ -172,8 +174,8 @@ int Analog_Output_Encode_Property_APDU( apdu_len = encode_tagged_enumerated(&apdu[0], OBJECT_ANALOG_OUTPUT); break; case PROP_PRESENT_VALUE: - value = Analog_Output_Present_Value(object_instance); - apdu_len = encode_tagged_real(&apdu[0], value); + real_value = Analog_Output_Present_Value(object_instance); + apdu_len = encode_tagged_real(&apdu[0], real_value); break; case PROP_STATUS_FLAGS: bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false); @@ -202,21 +204,21 @@ int Analog_Output_Encode_Property_APDU( object_index = Analog_Output_Instance_To_Index(object_instance); for (i = 0; i < BACNET_MAX_PRIORITIES; i++) { - // FIXME: check it we have room before adding it to APDU + // FIXME: check if we have room before adding it to APDU if (Analog_Output_Level[object_index][i] == AO_LEVEL_NULL) len = encode_tagged_null(&apdu[apdu_len]); else { - value = Analog_Output_Level[object_index][i]; - len = encode_tagged_real(&apdu[apdu_len], value); + real_value = Analog_Output_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_SERVICES - // ERROR_CODE_NO_SPACE_FOR_OBJECT + *error_class = ERROR_CLASS_SERVICES; + *error_code = ERROR_CODE_NO_SPACE_FOR_OBJECT; apdu_len = 0; break; } @@ -231,24 +233,26 @@ int Analog_Output_Encode_Property_APDU( len = encode_tagged_null(&apdu[apdu_len]); else { - value = Analog_Output_Level[object_index][array_index]; - len = encode_tagged_real(&apdu[apdu_len], value); + real_value = Analog_Output_Level[object_index][array_index]; + len = encode_tagged_real(&apdu[apdu_len], real_value); } } else { - //ERROR_CLASS_PROPERTY - //ERROR_CODE_INVALID_ARRAY_INDEX + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_INVALID_ARRAY_INDEX; } } break; case PROP_RELINQUISH_DEFAULT: - value = AO_RELINQUISH_DEFAULT; - apdu_len = encode_tagged_real(&apdu[0], value); + real_value = AO_RELINQUISH_DEFAULT; + apdu_len = encode_tagged_real(&apdu[0], real_value); break; default: - break; + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_UNKNOWN_PROPERTY; + break; } return apdu_len; @@ -279,29 +283,25 @@ bool Analog_Output_Write_Property( case PROP_PRESENT_VALUE: if (wp_data->value.tag == BACNET_APPLICATION_TAG_REAL) { - if ((wp_data->value.type.Real >= 0.0) && - (wp_data->value.type.Real <= 100.0)) - level = wp_data->value.type.Real; - else - { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; - return false; - } - object_index = Analog_Output_Instance_To_Index( - wp_data->object_instance); priority = wp_data->priority; - if (priority && (priority <= BACNET_MAX_PRIORITIES)) + if (priority && (priority <= BACNET_MAX_PRIORITIES) && + (wp_data->value.type.Real >= 0.0) && + (wp_data->value.type.Real <= 100.0)) { + level = wp_data->value.type.Real; + object_index = Analog_Output_Instance_To_Index( + wp_data->object_instance); priority--; Analog_Output_Level[object_index][priority] = level; + // 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; - return false; } } else if (wp_data->value.tag == BACNET_APPLICATION_TAG_NULL) @@ -320,14 +320,27 @@ bool Analog_Output_Write_Property( { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; - return false; } } else { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_INVALID_DATA_TYPE; - return false; + } + break; + case PROP_OUT_OF_SERVICE: + if (wp_data->value.tag == BACNET_APPLICATION_TAG_BOOLEAN) + { + object_index = Analog_Output_Instance_To_Index( + wp_data->object_instance); + Analog_Output_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: diff --git a/bacnet-stack/ao.h b/bacnet-stack/ao.h index ace0514f..c57b57ff 100644 --- a/bacnet-stack/ao.h +++ b/bacnet-stack/ao.h @@ -39,7 +39,9 @@ int Analog_Output_Encode_Property_APDU( uint8_t *apdu, uint32_t object_instance, BACNET_PROPERTY_ID property, - int32_t array_index); + int32_t array_index, + BACNET_ERROR_CLASS *error_class, + BACNET_ERROR_CODE *error_code); bool Analog_Output_Write_Property( BACNET_WRITE_PROPERTY_DATA *wp_data, diff --git a/bacnet-stack/device.c b/bacnet-stack/device.c index 968798a1..ac27eac6 100644 --- a/bacnet-stack/device.c +++ b/bacnet-stack/device.c @@ -189,11 +189,6 @@ BACNET_SEGMENTATION Device_Segmentation_Supported(void) return SEGMENTATION_NONE; } -//FIXME: Probably return one at a time, or be supported by -// an object module, or encode the APDU here. -//Object_List - - uint16_t Device_APDU_Timeout(void) { return APDU_Timeout; @@ -276,10 +271,13 @@ bool Device_Object_List_Identifier(unsigned array_index, return status; } +// return the length of the apdu encoded int Device_Encode_Property_APDU( uint8_t *apdu, BACNET_PROPERTY_ID property, - int32_t array_index) + int32_t array_index, + BACNET_ERROR_CLASS *error_class, + BACNET_ERROR_CODE *error_code) { int apdu_len = 0; // return value int len = 0; // apdu len intermediate value @@ -324,26 +322,26 @@ int Device_Encode_Property_APDU( Application_Software_Version); break; // if you support time - case PROP_LOCAL_TIME: - //t = time(NULL); - //my_tm = localtime(&t); - //apdu_len = - // encode_tagged_time(&apdu[0], my_tm->tm_hour, my_tm->tm_min, - // my_tm->tm_sec, 0); - break; + //case PROP_LOCAL_TIME: + //t = time(NULL); + //my_tm = localtime(&t); + //apdu_len = + // encode_tagged_time(&apdu[0], my_tm->tm_hour, my_tm->tm_min, + // my_tm->tm_sec, 0); + //break; // if you support date - case PROP_LOCAL_DATE: - //t = time(NULL); - //my_tm = localtime(&t); - // year = years since 1900 - // month 1=Jan - // day = day of month - // wday 1=Monday...7=Sunday - //apdu_len = encode_tagged_date(&apdu[0], - // my_tm->tm_year, - // my_tm->tm_mon + 1, - // my_tm->tm_mday, ((my_tm->tm_wday == 0) ? 7 : my_tm->tm_wday)); - break; + //case PROP_LOCAL_DATE: + //t = time(NULL); + //my_tm = localtime(&t); + // year = years since 1900 + // month 1=Jan + // day = day of month + // wday 1=Monday...7=Sunday + //apdu_len = encode_tagged_date(&apdu[0], + // my_tm->tm_year, + // my_tm->tm_mon + 1, + // my_tm->tm_mday, ((my_tm->tm_wday == 0) ? 7 : my_tm->tm_wday)); + //break; case PROP_PROTOCOL_VERSION: apdu_len = encode_tagged_unsigned(&apdu[0], Device_Protocol_Version()); break; @@ -398,8 +396,8 @@ int Device_Encode_Property_APDU( // can we all fit into the APDU? if ((apdu_len + len) >= MAX_APDU) { - // ERROR_CLASS_SERVICES - // ERROR_CODE_NO_SPACE_FOR_OBJECT + *error_class = ERROR_CLASS_SERVICES; + *error_code = ERROR_CODE_NO_SPACE_FOR_OBJECT; apdu_len = 0; break; } @@ -407,6 +405,8 @@ int Device_Encode_Property_APDU( else { // error: internal error? + *error_class = ERROR_CLASS_SERVICES; + *error_code = ERROR_CODE_OTHER; apdu_len = 0; break; } @@ -418,8 +418,8 @@ int Device_Encode_Property_APDU( apdu_len = encode_tagged_object_id(&apdu[0], object_type, instance); else { - //ERROR_CLASS_PROPERTY - //ERROR_CODE_INVALID_ARRAY_INDEX + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_INVALID_ARRAY_INDEX; } } break; @@ -438,7 +438,9 @@ int Device_Encode_Property_APDU( apdu_len = encode_tagged_unsigned(&apdu[0], Number_Of_APDU_Retries); break; default: - break; + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_UNKNOWN_PROPERTY; + break; } return apdu_len; diff --git a/bacnet-stack/device.h b/bacnet-stack/device.h index faa23471..46282420 100644 --- a/bacnet-stack/device.h +++ b/bacnet-stack/device.h @@ -87,7 +87,9 @@ void Device_Set_Database_Revision(uint8_t revision); int Device_Encode_Property_APDU( uint8_t *apdu, BACNET_PROPERTY_ID property, - int32_t array_index); + int32_t array_index, + BACNET_ERROR_CLASS *error_class, + BACNET_ERROR_CODE *error_code); bool Device_Write_Property( BACNET_WRITE_PROPERTY_DATA *wp_data, diff --git a/bacnet-stack/handlers.c b/bacnet-stack/handlers.c index d183c844..1dfe83e3 100644 --- a/bacnet-stack/handlers.c +++ b/bacnet-stack/handlers.c @@ -221,7 +221,10 @@ void ReadPropertyHandler( int32_t array_index; BACNET_ADDRESS my_address; bool send = false; + bool error = false; int bytes_sent = 0; + BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT; + BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT; len = rp_decode_service_request( service_request, @@ -273,13 +276,14 @@ void ReadPropertyHandler( { case OBJECT_DEVICE: // FIXME: probably need a length limitation sent with encode - // FIXME: might need to return error codes if (object_instance == Device_Object_Instance_Number()) { len = Device_Encode_Property_APDU( &Temp_Buf[0], object_property, - array_index); + array_index, + &error_class, + &error_code); if (len > 0) { // encode the APDU portion of the packet @@ -298,28 +302,10 @@ void ReadPropertyHandler( send = true; } else - { - pdu_len += bacerror_encode_apdu( - &Tx_Buf[pdu_len], - service_data->invoke_id, - SERVICE_CONFIRMED_READ_PROPERTY, - ERROR_CLASS_PROPERTY, - ERROR_CODE_UNKNOWN_PROPERTY); - fprintf(stderr,"Sending Unknown Property Error!\n"); - send = true; - } + error = true; } else - { - pdu_len += bacerror_encode_apdu( - &Tx_Buf[pdu_len], - service_data->invoke_id, - SERVICE_CONFIRMED_READ_PROPERTY, - ERROR_CLASS_OBJECT, - ERROR_CODE_UNKNOWN_OBJECT); - fprintf(stderr,"Sending Unknown Object Error!\n"); - send = true; - } + error = true; break; case OBJECT_ANALOG_INPUT: if (Analog_Input_Valid_Instance(object_instance)) @@ -328,7 +314,9 @@ void ReadPropertyHandler( &Temp_Buf[0], object_instance, object_property, - array_index); + array_index, + &error_class, + &error_code); if (len > 0) { // encode the APDU portion of the packet @@ -347,28 +335,10 @@ void ReadPropertyHandler( send = true; } else - { - pdu_len += bacerror_encode_apdu( - &Tx_Buf[pdu_len], - service_data->invoke_id, - SERVICE_CONFIRMED_READ_PROPERTY, - ERROR_CLASS_PROPERTY, - ERROR_CODE_UNKNOWN_PROPERTY); - fprintf(stderr,"Sending Unknown Property Error!\n"); - send = true; - } + error = true; } else - { - pdu_len += bacerror_encode_apdu( - &Tx_Buf[pdu_len], - service_data->invoke_id, - SERVICE_CONFIRMED_READ_PROPERTY, - ERROR_CLASS_OBJECT, - ERROR_CODE_UNKNOWN_OBJECT); - fprintf(stderr,"Sending Unknown Object Error!\n"); - send = true; - } + error = true; break; case OBJECT_ANALOG_OUTPUT: if (Analog_Output_Valid_Instance(object_instance)) @@ -377,7 +347,9 @@ void ReadPropertyHandler( &Temp_Buf[0], object_instance, object_property, - array_index); + array_index, + &error_class, + &error_code); if (len > 0) { // encode the APDU portion of the packet @@ -396,41 +368,27 @@ void ReadPropertyHandler( send = true; } else - { - pdu_len += bacerror_encode_apdu( - &Tx_Buf[pdu_len], - service_data->invoke_id, - SERVICE_CONFIRMED_READ_PROPERTY, - ERROR_CLASS_PROPERTY, - ERROR_CODE_UNKNOWN_PROPERTY); - fprintf(stderr,"Sending Unknown Property Error!\n"); - send = true; - } + error = true; } else - { - pdu_len += bacerror_encode_apdu( - &Tx_Buf[pdu_len], - service_data->invoke_id, - SERVICE_CONFIRMED_READ_PROPERTY, - ERROR_CLASS_OBJECT, - ERROR_CODE_UNKNOWN_OBJECT); - fprintf(stderr,"Sending Unknown Object Error!\n"); - send = true; - } + error = true; break; default: - pdu_len += bacerror_encode_apdu( - &Tx_Buf[pdu_len], - service_data->invoke_id, - SERVICE_CONFIRMED_READ_PROPERTY, - ERROR_CLASS_OBJECT, - ERROR_CODE_UNKNOWN_OBJECT); - fprintf(stderr,"Sending Unknown Object Error!\n"); - send = true; + error = true; break; } } + if (error) + { + pdu_len += bacerror_encode_apdu( + &Tx_Buf[pdu_len], + service_data->invoke_id, + SERVICE_CONFIRMED_READ_PROPERTY, + error_class, + error_code); + fprintf(stderr,"Sending Read Property Error!\n"); + send = true; + } if (send) { bytes_sent = bacdl_send_pdu(