diff --git a/bacnet-stack/demo/handler/h_rpm_a.c b/bacnet-stack/demo/handler/h_rpm_a.c index b30932df..dc742454 100644 --- a/bacnet-stack/demo/handler/h_rpm_a.c +++ b/bacnet-stack/demo/handler/h_rpm_a.c @@ -51,12 +51,14 @@ static int rpm_ack_decode_service_request( { int decoded_len = 0; /* return value */ int len = 0; /* number of bytes returned from decoding */ + uint8_t tag_number = 0; /* decoded tag number */ + uint32_t len_value = 0; /* decoded length value */ BACNET_READ_ACCESS_DATA *rpm_object; BACNET_READ_ACCESS_DATA *old_rpm_object; BACNET_PROPERTY_REFERENCE *rpm_property; BACNET_PROPERTY_REFERENCE *old_rpm_property; BACNET_APPLICATION_DATA_VALUE *value; - BACNET_APPLICATION_DATA_VALUE *old_value; + BACNET_APPLICATION_DATA_VALUE *old_value; rpm_object = read_access_data; old_rpm_object = rpm_object; @@ -88,10 +90,11 @@ static int rpm_ack_decode_service_request( decoded_len += len; apdu_len -= len; apdu += len; - if (apdu_len && decode_is_opening_tag_number(apdu, 4)) { + if (apdu_len && decode_is_opening_tag_number(apdu, 4)) { + /* propertyValue */ decoded_len++; apdu_len--; - apdu++; + apdu++; /* note: if this is an array, there will be more than one element to decode */ value = calloc(1, sizeof(BACNET_APPLICATION_DATA_VALUE)); @@ -99,7 +102,7 @@ static int rpm_ack_decode_service_request( old_value = value; while (value && (apdu_len > 0)) { len = - bacapp_decode_application_data(apdu, apdu_len, value); + bacapp_decode_application_data(apdu, apdu_len, value); decoded_len += len; apdu_len -= len; apdu += len; @@ -115,7 +118,42 @@ static int rpm_ack_decode_service_request( old_value->next = value; } } - } + } else if (apdu_len && decode_is_opening_tag_number(apdu, 5)) { + /* propertyAccessError */ + decoded_len++; + apdu_len--; + apdu++; + /* decode the class and code sequence */ + len = + decode_tag_number_and_value(apdu, &tag_number, + &len_value); + decoded_len += len; + apdu_len -= len; + apdu += len; + /* FIXME: we could validate that the tag is enumerated... */ + len = decode_enumerated(apdu, len_value, + (int *)&rpm_property->error.error_class); + decoded_len += len; + apdu_len -= len; + apdu += len; + len = + decode_tag_number_and_value(apdu, &tag_number, + &len_value); + decoded_len += len; + apdu_len -= len; + apdu += len; + /* FIXME: we could validate that the tag is enumerated... */ + len = decode_enumerated(apdu, len_value, + (int *)&rpm_property->error.error_code); + decoded_len += len; + apdu_len -= len; + apdu += len; + if (apdu_len && decode_is_closing_tag_number(apdu, 5)) { + decoded_len++; + apdu_len--; + apdu++; + } + } old_rpm_property = rpm_property; rpm_property = calloc(1, sizeof(BACNET_PROPERTY_REFERENCE)); old_rpm_property->next = rpm_property; @@ -162,31 +200,42 @@ static void PrintReadPropertyMultipleData( fprintf(stdout, "[%d]", listOfProperties->propertyArrayIndex); #endif } - value = listOfProperties->value; -#if PRINT_ENABLED - if (value->next) { - fprintf(stdout, "{"); - array_value = true; - } else { - array_value = false; - } -#endif - while (value) { - bacapp_print_value(stdout, value, - listOfProperties->propertyIdentifier); + value = listOfProperties->value; + if (value) { #if PRINT_ENABLED if (value->next) { - fprintf(stdout, ",\r\n "); + fprintf(stdout, "{"); + array_value = true; } else { - if (array_value) { - fprintf(stdout, "}\r\n"); - } else { - fprintf(stdout, "\r\n"); - } + array_value = false; } #endif - value = value->next; - } + while (value) { + bacapp_print_value(stdout, value, + listOfProperties->propertyIdentifier); +#if PRINT_ENABLED + if (value->next) { + fprintf(stdout, ",\r\n "); + } else { + if (array_value) { + fprintf(stdout, "}\r\n"); + } else { + fprintf(stdout, "\r\n"); + } + } +#endif + value = value->next; + } + } else { +#if PRINT_ENABLED + /* AccessError */ + fprintf(stdout, "BACnet Error: %s: %s\r\n", + bactext_error_class_name( + (int)listOfProperties->error.error_class), + bactext_error_code_name( + (int)listOfProperties->error.error_code)); +#endif + } listOfProperties = listOfProperties->next; } #if PRINT_ENABLED diff --git a/bacnet-stack/include/bacapp.h b/bacnet-stack/include/bacapp.h index a34c2922..4f9ccc32 100644 --- a/bacnet-stack/include/bacapp.h +++ b/bacnet-stack/include/bacapp.h @@ -89,11 +89,20 @@ typedef struct BACnet_Application_Data_Value { struct BACnet_Application_Data_Value *next; } BACNET_APPLICATION_DATA_VALUE; +struct BACnet_Access_Error; +typedef struct BACnet_Access_Error { + BACNET_ERROR_CLASS error_class; + BACNET_ERROR_CODE error_code; +} BACNET_ACCESS_ERROR; + struct BACnet_Property_Reference; typedef struct BACnet_Property_Reference { BACNET_PROPERTY_ID propertyIdentifier; int32_t propertyArrayIndex; /* optional */ + /* either value or error, but not both. + Use NULL value to indicate error */ BACNET_APPLICATION_DATA_VALUE *value; + BACNET_ACCESS_ERROR error; /* simple linked list */ struct BACnet_Property_Reference *next; } BACNET_PROPERTY_REFERENCE;