Bugfix/read property multiple client errors (#765)
* Fixed variable data type for boolean in RPM structure. * Fixed RPM error handling to use callback. * Fixed bacrpm app example when not enough command line parameters are used * Fixed empty-list EPICS printing. * Fixed RPM-Ack processing for end of list-of-results * Added minimal handling for segmentation-not-supported during RPM of object properties.
This commit is contained in:
@@ -677,16 +677,20 @@ static void bacnet_device_object_property_add(
|
||||
/**
|
||||
* @brief Handle the error from a ReadProperty or ReadPropertyMultiple
|
||||
* @param device_id - device instance number where data originated
|
||||
* @param error_code - BACnet Error code
|
||||
* @param rp_data - ReadProperty data structure
|
||||
* @param device_data - Pointer to the device data structure
|
||||
*/
|
||||
static void Device_Error_Handler(
|
||||
uint32_t device_id,
|
||||
BACNET_ERROR_CODE error_code,
|
||||
BACNET_READ_PROPERTY_DATA *rp_data,
|
||||
BACNET_DEVICE_DATA *device_data)
|
||||
{
|
||||
bool status = false;
|
||||
|
||||
if (device_data) {
|
||||
debug_printf(
|
||||
"%u - %s\n", device_id, bactext_error_code_name((int)error_code));
|
||||
"%u - %s\n", device_id,
|
||||
bactext_error_code_name((int)rp_data->error_code));
|
||||
switch (device_data->Discovery_State) {
|
||||
case BACNET_DISCOVER_STATE_OBJECT_LIST_REQUEST:
|
||||
/* resend request */
|
||||
@@ -697,12 +701,38 @@ static void Device_Error_Handler(
|
||||
BACNET_DISCOVER_STATE_OBJECT_LIST_RESPONSE;
|
||||
break;
|
||||
case BACNET_DISCOVER_STATE_OBJECT_GET_PROPERTY_REQUEST:
|
||||
/* resend request */
|
||||
if (device_data->Object_List_Index != 0) {
|
||||
device_data->Object_List_Index--;
|
||||
if (rp_data->error_code == ERROR_CODE_TIMEOUT) {
|
||||
/* resend request */
|
||||
if (device_data->Object_List_Index != 0) {
|
||||
device_data->Object_List_Index--;
|
||||
}
|
||||
device_data->Discovery_State =
|
||||
BACNET_DISCOVER_STATE_OBJECT_GET_PROPERTY_RESPONSE;
|
||||
} else if (
|
||||
(rp_data->error_code ==
|
||||
ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED) &&
|
||||
(rp_data->object_property == PROP_ALL)) {
|
||||
/* fallback to ReadProperty required properties */
|
||||
/* FIXME: fill a property-list with properties
|
||||
and use FSM to ReadProperty of each.
|
||||
For now, read the object-name property */
|
||||
status = bacnet_read_property_queue(
|
||||
device_id, rp_data->object_type,
|
||||
rp_data->object_instance, PROP_OBJECT_NAME,
|
||||
BACNET_ARRAY_ALL);
|
||||
if (status) {
|
||||
device_data->Discovery_State =
|
||||
BACNET_DISCOVER_STATE_OBJECT_GET_PROPERTY_REQUEST;
|
||||
} else {
|
||||
/* skip */
|
||||
device_data->Discovery_State =
|
||||
BACNET_DISCOVER_STATE_OBJECT_GET_PROPERTY_RESPONSE;
|
||||
}
|
||||
} else {
|
||||
/* skip */
|
||||
device_data->Discovery_State =
|
||||
BACNET_DISCOVER_STATE_OBJECT_GET_PROPERTY_RESPONSE;
|
||||
}
|
||||
device_data->Discovery_State =
|
||||
BACNET_DISCOVER_STATE_OBJECT_GET_PROPERTY_RESPONSE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -733,7 +763,7 @@ static void bacnet_read_property_reply(
|
||||
return;
|
||||
}
|
||||
if (rp_data->error_code != ERROR_CODE_SUCCESS) {
|
||||
Device_Error_Handler(device_id, rp_data->error_code, device_data);
|
||||
Device_Error_Handler(device_id, rp_data, device_data);
|
||||
} else if (value) {
|
||||
bacnet_device_object_property_add(
|
||||
device_id, rp_data, value, device_data);
|
||||
|
||||
@@ -211,15 +211,29 @@ static void bacnet_read_property_ack_process(
|
||||
BACNET_ARRAY_INDEX array_index = 0;
|
||||
|
||||
if (rp_data) {
|
||||
value = &Target_Decoded_Property_Value;
|
||||
/* check for property error */
|
||||
if (rp_data->error_code != ERROR_CODE_SUCCESS) {
|
||||
if (bacnet_read_write_value_callback) {
|
||||
bacnet_read_write_value_callback(device_id, rp_data, NULL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* check for empty list */
|
||||
if (rp_data->application_data_len == 0) {
|
||||
bacapp_value_list_init(value, 1);
|
||||
value->tag = BACNET_APPLICATION_TAG_EMPTYLIST;
|
||||
rp_data->error_class = ERROR_CLASS_SERVICES;
|
||||
rp_data->error_code = ERROR_CODE_SUCCESS;
|
||||
if (bacnet_read_write_value_callback) {
|
||||
bacnet_read_write_value_callback(device_id, rp_data, value);
|
||||
}
|
||||
return;
|
||||
}
|
||||
apdu = rp_data->application_data;
|
||||
apdu_len = rp_data->application_data_len;
|
||||
while (apdu_len) {
|
||||
value = &Target_Decoded_Property_Value;
|
||||
bacapp_value_list_init(value, 1);
|
||||
len = bacapp_decode_known_property(
|
||||
apdu, (unsigned)apdu_len, value, rp_data->object_type,
|
||||
rp_data->object_property);
|
||||
@@ -251,7 +265,11 @@ static void bacnet_read_property_ack_process(
|
||||
}
|
||||
} else {
|
||||
rp_data->error_class = ERROR_CLASS_SERVICES;
|
||||
rp_data->error_code = ERROR_CODE_SUCCESS;
|
||||
if (len < 0) {
|
||||
rp_data->error_code = ERROR_CODE_OTHER;
|
||||
} else {
|
||||
rp_data->error_code = ERROR_CODE_SUCCESS;
|
||||
}
|
||||
if (bacnet_read_write_value_callback) {
|
||||
bacnet_read_write_value_callback(device_id, rp_data, NULL);
|
||||
}
|
||||
|
||||
@@ -103,18 +103,19 @@ int rpm_ack_decode_service_request(
|
||||
decoded_len++;
|
||||
apdu_len--;
|
||||
apdu++;
|
||||
/* note: if this is an array, there will be
|
||||
more than one element to decode */
|
||||
value = calloc(1, sizeof(BACNET_APPLICATION_DATA_VALUE));
|
||||
rpm_property->value = value;
|
||||
|
||||
/* Special case for an empty array - we decode it as null */
|
||||
if (apdu_len && decode_is_closing_tag_number(apdu, 4)) {
|
||||
bacapp_value_list_init(value, 1);
|
||||
/* Special case for an empty array or list */
|
||||
if (value) {
|
||||
bacapp_value_list_init(value, 1);
|
||||
value->tag = BACNET_APPLICATION_TAG_EMPTYLIST;
|
||||
}
|
||||
decoded_len++;
|
||||
apdu_len--;
|
||||
apdu++;
|
||||
} else {
|
||||
/* one or more (array or list) elements to decode */
|
||||
while (value && (apdu_len > 0)) {
|
||||
len = bacapp_decode_known_property(
|
||||
apdu, (unsigned)apdu_len, value,
|
||||
|
||||
Reference in New Issue
Block a user