Corrected ReadPropertyMultiple handler. Tested using VTS with demo/server running under linux.
This commit is contained in:
@@ -10,8 +10,8 @@
|
|||||||
/* 50 is the minimum; adjust to your memory and physical layer constraints */
|
/* 50 is the minimum; adjust to your memory and physical layer constraints */
|
||||||
/* Lon=206, MS/TP=480, ARCNET=480, Ethernet=1476 */
|
/* Lon=206, MS/TP=480, ARCNET=480, Ethernet=1476 */
|
||||||
#ifndef MAX_APDU
|
#ifndef MAX_APDU
|
||||||
#define MAX_APDU 50
|
/* #define MAX_APDU 50 */
|
||||||
/* #define MAX_APDU 480 */
|
#define MAX_APDU 480
|
||||||
/* #define MAX_APDU 1476 */
|
/* #define MAX_APDU 1476 */
|
||||||
#endif
|
#endif
|
||||||
/* for confirmed messages, this is the number of transactions */
|
/* for confirmed messages, this is the number of transactions */
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ static unsigned property_list_count(const int *pList)
|
|||||||
if (pList) {
|
if (pList) {
|
||||||
while (*pList != -1) {
|
while (*pList != -1) {
|
||||||
property_count++;
|
property_count++;
|
||||||
|
pList++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,8 +184,10 @@ static int RPM_Object_Property(
|
|||||||
if (index < required) {
|
if (index < required) {
|
||||||
property = pPropertyList->Required.pList[index];
|
property = pPropertyList->Required.pList[index];
|
||||||
} else if (index < (required + optional)) {
|
} else if (index < (required + optional)) {
|
||||||
|
index -= required;
|
||||||
property = pPropertyList->Optional.pList[index];
|
property = pPropertyList->Optional.pList[index];
|
||||||
} else if (index < (required + optional + proprietary)) {
|
} else if (index < (required + optional + proprietary)) {
|
||||||
|
index -= (required + optional);
|
||||||
property = pPropertyList->Proprietary.pList[index];
|
property = pPropertyList->Proprietary.pList[index];
|
||||||
}
|
}
|
||||||
} else if (special_property == PROP_REQUIRED) {
|
} else if (special_property == PROP_REQUIRED) {
|
||||||
@@ -458,13 +461,15 @@ void handler_read_property_multiple(
|
|||||||
service_data->invoke_id);
|
service_data->invoke_id);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
len = rpm_ack_decode_object_id(
|
len = rpm_decode_object_id(
|
||||||
&service_request[decode_len],
|
&service_request[decode_len],
|
||||||
service_len - decode_len,
|
service_len - decode_len,
|
||||||
&object_type, &object_instance);
|
&object_type, &object_instance);
|
||||||
/* error - end of object? */
|
/* end of object? */
|
||||||
if (len < 0) {
|
if (len > 0) {
|
||||||
len = rpm_ack_decode_object_end(
|
decode_len += len;
|
||||||
|
} else {
|
||||||
|
len = rpm_decode_object_end(
|
||||||
&service_request[decode_len],
|
&service_request[decode_len],
|
||||||
service_len - decode_len);
|
service_len - decode_len);
|
||||||
if (len == 1) {
|
if (len == 1) {
|
||||||
@@ -481,6 +486,8 @@ void handler_read_property_multiple(
|
|||||||
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
|
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
|
||||||
true);
|
true);
|
||||||
goto RPM_ABORT;
|
goto RPM_ABORT;
|
||||||
|
} else {
|
||||||
|
apdu_len += copy_len;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
apdu_len = abort_encode_apdu(
|
apdu_len = abort_encode_apdu(
|
||||||
@@ -490,8 +497,6 @@ void handler_read_property_multiple(
|
|||||||
goto RPM_ABORT;
|
goto RPM_ABORT;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} else {
|
|
||||||
decode_len += len;
|
|
||||||
}
|
}
|
||||||
len = rpm_ack_encode_apdu_object_begin(
|
len = rpm_ack_encode_apdu_object_begin(
|
||||||
&Temp_Buf[0],
|
&Temp_Buf[0],
|
||||||
@@ -507,6 +512,8 @@ void handler_read_property_multiple(
|
|||||||
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
|
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
|
||||||
true);
|
true);
|
||||||
goto RPM_ABORT;
|
goto RPM_ABORT;
|
||||||
|
} else {
|
||||||
|
apdu_len += copy_len;
|
||||||
}
|
}
|
||||||
/* do each property of this object of the RPM request */
|
/* do each property of this object of the RPM request */
|
||||||
do
|
do
|
||||||
@@ -516,11 +523,39 @@ void handler_read_property_multiple(
|
|||||||
service_len - decode_len,
|
service_len - decode_len,
|
||||||
&object_property,
|
&object_property,
|
||||||
&array_index);
|
&array_index);
|
||||||
/* error - end of property list? */
|
/* end of property list? */
|
||||||
if (len < 0) {
|
if (len > 0) {
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
decode_len += len;
|
decode_len += len;
|
||||||
|
} else {
|
||||||
|
len = rpm_decode_object_end(
|
||||||
|
&service_request[decode_len],
|
||||||
|
service_len - decode_len);
|
||||||
|
if (len == 1) {
|
||||||
|
decode_len++;
|
||||||
|
len = rpm_ack_encode_apdu_object_end(&Temp_Buf[0]);
|
||||||
|
copy_len = apdu_copy(
|
||||||
|
&Handler_Transmit_Buffer[npdu_len], &Temp_Buf[0],
|
||||||
|
apdu_len, len,
|
||||||
|
sizeof(Handler_Transmit_Buffer));
|
||||||
|
if (!copy_len) {
|
||||||
|
apdu_len = abort_encode_apdu(
|
||||||
|
&Handler_Transmit_Buffer[npdu_len],
|
||||||
|
service_data->invoke_id,
|
||||||
|
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
|
||||||
|
true);
|
||||||
|
goto RPM_ABORT;
|
||||||
|
} else {
|
||||||
|
apdu_len += copy_len;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
apdu_len = abort_encode_apdu(
|
||||||
|
&Handler_Transmit_Buffer[npdu_len],
|
||||||
|
service_data->invoke_id,
|
||||||
|
ABORT_REASON_OTHER, true);
|
||||||
|
goto RPM_ABORT;
|
||||||
|
}
|
||||||
|
/* stop decoding properties */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
/* handle the special properties */
|
/* handle the special properties */
|
||||||
if ((object_property == PROP_ALL) ||
|
if ((object_property == PROP_ALL) ||
|
||||||
@@ -554,6 +589,8 @@ void handler_read_property_multiple(
|
|||||||
service_data->invoke_id,
|
service_data->invoke_id,
|
||||||
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
|
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
|
||||||
goto RPM_ABORT;
|
goto RPM_ABORT;
|
||||||
|
} else {
|
||||||
|
apdu_len += copy_len;
|
||||||
}
|
}
|
||||||
application_data_len = Encode_Property_APDU(
|
application_data_len = Encode_Property_APDU(
|
||||||
&Application_Buf[0],
|
&Application_Buf[0],
|
||||||
@@ -583,10 +620,29 @@ void handler_read_property_multiple(
|
|||||||
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
|
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
|
||||||
true);
|
true);
|
||||||
goto RPM_ABORT;
|
goto RPM_ABORT;
|
||||||
|
} else {
|
||||||
|
apdu_len += copy_len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* handle an individual property */
|
/* handle an individual property */
|
||||||
|
len = rpm_ack_encode_apdu_object_property(
|
||||||
|
&Temp_Buf[0],
|
||||||
|
object_property,
|
||||||
|
array_index);
|
||||||
|
copy_len = apdu_copy(
|
||||||
|
&Handler_Transmit_Buffer[npdu_len], &Temp_Buf[0],
|
||||||
|
apdu_len, len,
|
||||||
|
sizeof(Handler_Transmit_Buffer));
|
||||||
|
if (!copy_len) {
|
||||||
|
apdu_len = abort_encode_apdu(
|
||||||
|
&Handler_Transmit_Buffer[npdu_len],
|
||||||
|
service_data->invoke_id,
|
||||||
|
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
|
||||||
|
goto RPM_ABORT;
|
||||||
|
} else {
|
||||||
|
apdu_len += copy_len;
|
||||||
|
}
|
||||||
application_data_len = Encode_Property_APDU(
|
application_data_len = Encode_Property_APDU(
|
||||||
&Application_Buf[0],
|
&Application_Buf[0],
|
||||||
object_type,
|
object_type,
|
||||||
@@ -615,6 +671,8 @@ void handler_read_property_multiple(
|
|||||||
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
|
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
|
||||||
true);
|
true);
|
||||||
goto RPM_ABORT;
|
goto RPM_ABORT;
|
||||||
|
} else {
|
||||||
|
apdu_len += copy_len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while(1);
|
} while(1);
|
||||||
|
|||||||
@@ -68,11 +68,11 @@ void Analog_Input_Property_Lists(
|
|||||||
const int **pOptional,
|
const int **pOptional,
|
||||||
const int **pProprietary)
|
const int **pProprietary)
|
||||||
{
|
{
|
||||||
if (*pRequired)
|
if (pRequired)
|
||||||
*pRequired = Analog_Input_Properties_Required;
|
*pRequired = Analog_Input_Properties_Required;
|
||||||
if (*pOptional)
|
if (pOptional)
|
||||||
*pOptional = Analog_Input_Properties_Optional;
|
*pOptional = Analog_Input_Properties_Optional;
|
||||||
if (*pProprietary)
|
if (pProprietary)
|
||||||
*pProprietary = Analog_Input_Properties_Proprietary;
|
*pProprietary = Analog_Input_Properties_Proprietary;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -88,11 +88,11 @@ void Analog_Output_Property_Lists(
|
|||||||
const int **pOptional,
|
const int **pOptional,
|
||||||
const int **pProprietary)
|
const int **pProprietary)
|
||||||
{
|
{
|
||||||
if (*pRequired)
|
if (pRequired)
|
||||||
*pRequired = Analog_Output_Properties_Required;
|
*pRequired = Analog_Output_Properties_Required;
|
||||||
if (*pOptional)
|
if (pOptional)
|
||||||
*pOptional = Analog_Output_Properties_Optional;
|
*pOptional = Analog_Output_Properties_Optional;
|
||||||
if (*pProprietary)
|
if (pProprietary)
|
||||||
*pProprietary = Analog_Output_Properties_Proprietary;
|
*pProprietary = Analog_Output_Properties_Proprietary;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -87,11 +87,11 @@ void Analog_Value_Property_Lists(
|
|||||||
const int **pOptional,
|
const int **pOptional,
|
||||||
const int **pProprietary)
|
const int **pProprietary)
|
||||||
{
|
{
|
||||||
if (*pRequired)
|
if (pRequired)
|
||||||
*pRequired = Analog_Value_Properties_Required;
|
*pRequired = Analog_Value_Properties_Required;
|
||||||
if (*pOptional)
|
if (pOptional)
|
||||||
*pOptional = Analog_Value_Properties_Optional;
|
*pOptional = Analog_Value_Properties_Optional;
|
||||||
if (*pProprietary)
|
if (pProprietary)
|
||||||
*pProprietary = Analog_Value_Properties_Proprietary;
|
*pProprietary = Analog_Value_Properties_Proprietary;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -83,11 +83,11 @@ void BACfile_Property_Lists(
|
|||||||
const int **pOptional,
|
const int **pOptional,
|
||||||
const int **pProprietary)
|
const int **pProprietary)
|
||||||
{
|
{
|
||||||
if (*pRequired)
|
if (pRequired)
|
||||||
*pRequired = bacfile_Properties_Required;
|
*pRequired = bacfile_Properties_Required;
|
||||||
if (*pOptional)
|
if (pOptional)
|
||||||
*pOptional = bacfile_Properties_Optional;
|
*pOptional = bacfile_Properties_Optional;
|
||||||
if (*pProprietary)
|
if (pProprietary)
|
||||||
*pProprietary = bacfile_Properties_Proprietary;
|
*pProprietary = bacfile_Properties_Proprietary;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -67,11 +67,11 @@ void Binary_Input_Property_Lists(
|
|||||||
const int **pOptional,
|
const int **pOptional,
|
||||||
const int **pProprietary)
|
const int **pProprietary)
|
||||||
{
|
{
|
||||||
if (*pRequired)
|
if (pRequired)
|
||||||
*pRequired = Binary_Input_Properties_Required;
|
*pRequired = Binary_Input_Properties_Required;
|
||||||
if (*pOptional)
|
if (pOptional)
|
||||||
*pOptional = Binary_Input_Properties_Optional;
|
*pOptional = Binary_Input_Properties_Optional;
|
||||||
if (*pProprietary)
|
if (pProprietary)
|
||||||
*pProprietary = Binary_Input_Properties_Proprietary;
|
*pProprietary = Binary_Input_Properties_Proprietary;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -79,11 +79,11 @@ void Binary_Output_Property_Lists(
|
|||||||
const int **pOptional,
|
const int **pOptional,
|
||||||
const int **pProprietary)
|
const int **pProprietary)
|
||||||
{
|
{
|
||||||
if (*pRequired)
|
if (pRequired)
|
||||||
*pRequired = Binary_Output_Properties_Required;
|
*pRequired = Binary_Output_Properties_Required;
|
||||||
if (*pOptional)
|
if (pOptional)
|
||||||
*pOptional = Binary_Output_Properties_Optional;
|
*pOptional = Binary_Output_Properties_Optional;
|
||||||
if (*pProprietary)
|
if (pProprietary)
|
||||||
*pProprietary = Binary_Output_Properties_Proprietary;
|
*pProprietary = Binary_Output_Properties_Proprietary;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -78,11 +78,11 @@ void Binary_Value_Property_Lists(
|
|||||||
const int **pOptional,
|
const int **pOptional,
|
||||||
const int **pProprietary)
|
const int **pProprietary)
|
||||||
{
|
{
|
||||||
if (*pRequired)
|
if (pRequired)
|
||||||
*pRequired = Binary_Value_Properties_Required;
|
*pRequired = Binary_Value_Properties_Required;
|
||||||
if (*pOptional)
|
if (pOptional)
|
||||||
*pOptional = Binary_Value_Properties_Optional;
|
*pOptional = Binary_Value_Properties_Optional;
|
||||||
if (*pProprietary)
|
if (pProprietary)
|
||||||
*pProprietary = Binary_Value_Properties_Proprietary;
|
*pProprietary = Binary_Value_Properties_Proprietary;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -97,11 +97,11 @@ void Device_Property_Lists(
|
|||||||
const int **pOptional,
|
const int **pOptional,
|
||||||
const int **pProprietary)
|
const int **pProprietary)
|
||||||
{
|
{
|
||||||
if (*pRequired)
|
if (pRequired)
|
||||||
*pRequired = Device_Properties_Required;
|
*pRequired = Device_Properties_Required;
|
||||||
if (*pOptional)
|
if (pOptional)
|
||||||
*pOptional = Device_Properties_Optional;
|
*pOptional = Device_Properties_Optional;
|
||||||
if (*pProprietary)
|
if (pProprietary)
|
||||||
*pProprietary = Device_Properties_Proprietary;
|
*pProprietary = Device_Properties_Proprietary;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -175,11 +175,11 @@ void Load_Control_Property_Lists(
|
|||||||
const int **pOptional,
|
const int **pOptional,
|
||||||
const int **pProprietary)
|
const int **pProprietary)
|
||||||
{
|
{
|
||||||
if (*pRequired)
|
if (pRequired)
|
||||||
*pRequired = Load_Control_Properties_Required;
|
*pRequired = Load_Control_Properties_Required;
|
||||||
if (*pOptional)
|
if (pOptional)
|
||||||
*pOptional = Load_Control_Properties_Optional;
|
*pOptional = Load_Control_Properties_Optional;
|
||||||
if (*pProprietary)
|
if (pProprietary)
|
||||||
*pProprietary = Load_Control_Properties_Proprietary;
|
*pProprietary = Load_Control_Properties_Proprietary;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -84,11 +84,11 @@ void Life_Safety_Point_Property_Lists(
|
|||||||
const int **pOptional,
|
const int **pOptional,
|
||||||
const int **pProprietary)
|
const int **pProprietary)
|
||||||
{
|
{
|
||||||
if (*pRequired)
|
if (pRequired)
|
||||||
*pRequired = Life_Safety_Point_Properties_Required;
|
*pRequired = Life_Safety_Point_Properties_Required;
|
||||||
if (*pOptional)
|
if (pOptional)
|
||||||
*pOptional = Life_Safety_Point_Properties_Optional;
|
*pOptional = Life_Safety_Point_Properties_Optional;
|
||||||
if (*pProprietary)
|
if (pProprietary)
|
||||||
*pProprietary = Life_Safety_Point_Properties_Proprietary;
|
*pProprietary = Life_Safety_Point_Properties_Proprietary;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -84,11 +84,11 @@ void Multistate_Output_Property_Lists(
|
|||||||
const int **pOptional,
|
const int **pOptional,
|
||||||
const int **pProprietary)
|
const int **pProprietary)
|
||||||
{
|
{
|
||||||
if (*pRequired)
|
if (pRequired)
|
||||||
*pRequired = Multistate_Output_Properties_Required;
|
*pRequired = Multistate_Output_Properties_Required;
|
||||||
if (*pOptional)
|
if (pOptional)
|
||||||
*pOptional = Multistate_Output_Properties_Optional;
|
*pOptional = Multistate_Output_Properties_Optional;
|
||||||
if (*pProprietary)
|
if (pProprietary)
|
||||||
*pProprietary = Multistate_Output_Properties_Proprietary;
|
*pProprietary = Multistate_Output_Properties_Proprietary;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|||||||
+47
-34
@@ -156,6 +156,8 @@ int rpm_decode_object_property(uint8_t * apdu,
|
|||||||
/* check for valid pointers */
|
/* check for valid pointers */
|
||||||
if (apdu && apdu_len && object_property && array_index) {
|
if (apdu && apdu_len && object_property && array_index) {
|
||||||
/* Tag 0: propertyIdentifier */
|
/* Tag 0: propertyIdentifier */
|
||||||
|
if (!decode_is_context_specific(&apdu[len]))
|
||||||
|
return -1;
|
||||||
len += decode_tag_number_and_value(&apdu[len],
|
len += decode_tag_number_and_value(&apdu[len],
|
||||||
&tag_number, &len_value_type);
|
&tag_number, &len_value_type);
|
||||||
if (tag_number != 0)
|
if (tag_number != 0)
|
||||||
@@ -164,7 +166,9 @@ int rpm_decode_object_property(uint8_t * apdu,
|
|||||||
if (object_property)
|
if (object_property)
|
||||||
*object_property = (BACNET_PROPERTY_ID)property;
|
*object_property = (BACNET_PROPERTY_ID)property;
|
||||||
/* Tag 1: Optional propertyArrayIndex */
|
/* Tag 1: Optional propertyArrayIndex */
|
||||||
if (len < apdu_len) {
|
if ((len < apdu_len) &&
|
||||||
|
decode_is_context_specific(&apdu[len]) &&
|
||||||
|
(!decode_is_closing_tag(&apdu[len]))) {
|
||||||
option_len =
|
option_len =
|
||||||
decode_tag_number_and_value(&apdu[len], &tag_number,
|
decode_tag_number_and_value(&apdu[len], &tag_number,
|
||||||
&len_value_type);
|
&len_value_type);
|
||||||
@@ -182,34 +186,6 @@ int rpm_decode_object_property(uint8_t * apdu,
|
|||||||
return (int) len;
|
return (int) len;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rpm_decode_apdu(uint8_t * apdu,
|
|
||||||
unsigned apdu_len,
|
|
||||||
uint8_t * invoke_id,
|
|
||||||
uint8_t ** service_request, unsigned *service_request_len)
|
|
||||||
{
|
|
||||||
unsigned offset = 0;
|
|
||||||
|
|
||||||
if (!apdu)
|
|
||||||
return -1;
|
|
||||||
/* optional checking - most likely was already done prior to this call */
|
|
||||||
if (apdu[0] != PDU_TYPE_CONFIRMED_SERVICE_REQUEST)
|
|
||||||
return -1;
|
|
||||||
/* apdu[1] = encode_max_segs_max_apdu(0, Device_Max_APDU_Length_Accepted()); */
|
|
||||||
*invoke_id = apdu[2]; /* invoke id - filled in by net layer */
|
|
||||||
if (apdu[3] != SERVICE_CONFIRMED_READ_PROPERTY_MULTIPLE)
|
|
||||||
return -1;
|
|
||||||
offset = 4;
|
|
||||||
|
|
||||||
if (apdu_len > offset) {
|
|
||||||
if (service_request)
|
|
||||||
*service_request = &apdu[offset];
|
|
||||||
if (service_request_len)
|
|
||||||
*service_request_len = apdu_len - offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
return offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
int rpm_ack_encode_apdu_init(uint8_t * apdu, uint8_t invoke_id)
|
int rpm_ack_encode_apdu_init(uint8_t * apdu, uint8_t invoke_id)
|
||||||
{
|
{
|
||||||
int apdu_len = 0; /* total length of the apdu, return value */
|
int apdu_len = 0; /* total length of the apdu, return value */
|
||||||
@@ -354,6 +330,8 @@ int rpm_ack_decode_object_property(uint8_t * apdu,
|
|||||||
/* check for valid pointers */
|
/* check for valid pointers */
|
||||||
if (apdu && apdu_len && object_property && array_index) {
|
if (apdu && apdu_len && object_property && array_index) {
|
||||||
/* Tag 2: propertyIdentifier */
|
/* Tag 2: propertyIdentifier */
|
||||||
|
if (!decode_is_context_specific(&apdu[len]))
|
||||||
|
return -1;
|
||||||
len += decode_tag_number_and_value(&apdu[len],
|
len += decode_tag_number_and_value(&apdu[len],
|
||||||
&tag_number, &len_value_type);
|
&tag_number, &len_value_type);
|
||||||
if (tag_number != 2)
|
if (tag_number != 2)
|
||||||
@@ -362,6 +340,9 @@ int rpm_ack_decode_object_property(uint8_t * apdu,
|
|||||||
if (object_property)
|
if (object_property)
|
||||||
*object_property = (BACNET_PROPERTY_ID)property;
|
*object_property = (BACNET_PROPERTY_ID)property;
|
||||||
/* Tag 3: Optional propertyArrayIndex */
|
/* Tag 3: Optional propertyArrayIndex */
|
||||||
|
if ((len < apdu_len) &&
|
||||||
|
decode_is_context_specific(&apdu[len]) &&
|
||||||
|
(!decode_is_closing_tag(&apdu[len]))) {
|
||||||
tag_len = decode_tag_number_and_value(&apdu[len], &tag_number,
|
tag_len = decode_tag_number_and_value(&apdu[len], &tag_number,
|
||||||
&len_value_type);
|
&len_value_type);
|
||||||
if (tag_number == 3) {
|
if (tag_number == 3) {
|
||||||
@@ -369,13 +350,22 @@ int rpm_ack_decode_object_property(uint8_t * apdu,
|
|||||||
len += decode_unsigned(&apdu[len], len_value_type,
|
len += decode_unsigned(&apdu[len], len_value_type,
|
||||||
&array_value);
|
&array_value);
|
||||||
*array_index = array_value;
|
*array_index = array_value;
|
||||||
} else
|
} else {
|
||||||
*array_index = BACNET_ARRAY_ALL;
|
*array_index = BACNET_ARRAY_ALL;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
*array_index = BACNET_ARRAY_ALL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (int) len;
|
return (int) len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "ctest.h"
|
||||||
|
|
||||||
int rpm_ack_decode_apdu(uint8_t * apdu, int apdu_len, /* total length of the apdu */
|
int rpm_ack_decode_apdu(uint8_t * apdu, int apdu_len, /* total length of the apdu */
|
||||||
uint8_t * invoke_id,
|
uint8_t * invoke_id,
|
||||||
uint8_t ** service_request, unsigned *service_request_len)
|
uint8_t ** service_request, unsigned *service_request_len)
|
||||||
@@ -401,10 +391,33 @@ int rpm_ack_decode_apdu(uint8_t * apdu, int apdu_len, /* total length of the a
|
|||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TEST
|
int rpm_decode_apdu(uint8_t * apdu,
|
||||||
#include <assert.h>
|
unsigned apdu_len,
|
||||||
#include <string.h>
|
uint8_t * invoke_id,
|
||||||
#include "ctest.h"
|
uint8_t ** service_request, unsigned *service_request_len)
|
||||||
|
{
|
||||||
|
unsigned offset = 0;
|
||||||
|
|
||||||
|
if (!apdu)
|
||||||
|
return -1;
|
||||||
|
/* optional checking - most likely was already done prior to this call */
|
||||||
|
if (apdu[0] != PDU_TYPE_CONFIRMED_SERVICE_REQUEST)
|
||||||
|
return -1;
|
||||||
|
/* apdu[1] = encode_max_segs_max_apdu(0, Device_Max_APDU_Length_Accepted()); */
|
||||||
|
*invoke_id = apdu[2]; /* invoke id - filled in by net layer */
|
||||||
|
if (apdu[3] != SERVICE_CONFIRMED_READ_PROPERTY_MULTIPLE)
|
||||||
|
return -1;
|
||||||
|
offset = 4;
|
||||||
|
|
||||||
|
if (apdu_len > offset) {
|
||||||
|
if (service_request)
|
||||||
|
*service_request = &apdu[offset];
|
||||||
|
if (service_request_len)
|
||||||
|
*service_request_len = apdu_len - offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
void testReadPropertyMultiple(Test * pTest)
|
void testReadPropertyMultiple(Test * pTest)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user