Corrected RPM client handling - missed the AccessError tag. Thanks, Kevin!

This commit is contained in:
skarg
2008-12-02 06:57:14 +00:00
parent 16ce2b615f
commit c2fdccb2df
2 changed files with 83 additions and 25 deletions
+67 -18
View File
@@ -51,6 +51,8 @@ static int rpm_ack_decode_service_request(
{ {
int decoded_len = 0; /* return value */ int decoded_len = 0; /* return value */
int len = 0; /* number of bytes returned from decoding */ 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 *rpm_object;
BACNET_READ_ACCESS_DATA *old_rpm_object; BACNET_READ_ACCESS_DATA *old_rpm_object;
BACNET_PROPERTY_REFERENCE *rpm_property; BACNET_PROPERTY_REFERENCE *rpm_property;
@@ -89,6 +91,7 @@ static int rpm_ack_decode_service_request(
apdu_len -= len; apdu_len -= len;
apdu += 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++; decoded_len++;
apdu_len--; apdu_len--;
apdu++; apdu++;
@@ -115,6 +118,41 @@ static int rpm_ack_decode_service_request(
old_value->next = value; 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; old_rpm_property = rpm_property;
rpm_property = calloc(1, sizeof(BACNET_PROPERTY_REFERENCE)); rpm_property = calloc(1, sizeof(BACNET_PROPERTY_REFERENCE));
@@ -163,29 +201,40 @@ static void PrintReadPropertyMultipleData(
#endif #endif
} }
value = listOfProperties->value; value = listOfProperties->value;
#if PRINT_ENABLED if (value) {
if (value->next) {
fprintf(stdout, "{");
array_value = true;
} else {
array_value = false;
}
#endif
while (value) {
bacapp_print_value(stdout, value,
listOfProperties->propertyIdentifier);
#if PRINT_ENABLED #if PRINT_ENABLED
if (value->next) { if (value->next) {
fprintf(stdout, ",\r\n "); fprintf(stdout, "{");
array_value = true;
} else { } else {
if (array_value) { array_value = false;
fprintf(stdout, "}\r\n");
} else {
fprintf(stdout, "\r\n");
}
} }
#endif #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; listOfProperties = listOfProperties->next;
} }
+9
View File
@@ -89,11 +89,20 @@ typedef struct BACnet_Application_Data_Value {
struct BACnet_Application_Data_Value *next; struct BACnet_Application_Data_Value *next;
} BACNET_APPLICATION_DATA_VALUE; } 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; struct BACnet_Property_Reference;
typedef struct BACnet_Property_Reference { typedef struct BACnet_Property_Reference {
BACNET_PROPERTY_ID propertyIdentifier; BACNET_PROPERTY_ID propertyIdentifier;
int32_t propertyArrayIndex; /* optional */ int32_t propertyArrayIndex; /* optional */
/* either value or error, but not both.
Use NULL value to indicate error */
BACNET_APPLICATION_DATA_VALUE *value; BACNET_APPLICATION_DATA_VALUE *value;
BACNET_ACCESS_ERROR error;
/* simple linked list */ /* simple linked list */
struct BACnet_Property_Reference *next; struct BACnet_Property_Reference *next;
} BACNET_PROPERTY_REFERENCE; } BACNET_PROPERTY_REFERENCE;