diff --git a/bacnet-stack/include/bacdevobjpropref.h b/bacnet-stack/include/bacdevobjpropref.h index 3c4e8e22..27f57bd5 100644 --- a/bacnet-stack/include/bacdevobjpropref.h +++ b/bacnet-stack/include/bacdevobjpropref.h @@ -43,6 +43,16 @@ typedef struct { BACNET_OBJECT_ID deviceIndentifier; } BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE; +/** BACnetDeviceObjectReference structure. + * If the optional deviceIdentifier is not provided, then this refers + * to an object inside this Device. + */ +typedef struct { + BACNET_OBJECT_ID deviceIndentifier; /**< Optional, for external device. */ + BACNET_OBJECT_ID objectIdentifier; +} BACNET_DEVICE_OBJECT_REFERENCE; + + #ifdef __cplusplus extern "C" { @@ -66,6 +76,26 @@ extern "C" { uint8_t tag_number, BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE * value); + + int bacapp_encode_device_obj_ref( + uint8_t * apdu, + BACNET_DEVICE_OBJECT_REFERENCE * value); + + int bacapp_encode_context_device_obj_ref( + uint8_t * apdu, + uint8_t tag_number, + BACNET_DEVICE_OBJECT_REFERENCE * value); + + int bacapp_decode_device_obj_ref( + uint8_t * apdu, + BACNET_DEVICE_OBJECT_REFERENCE * value); + + int bacapp_decode_context_device_obj_ref( + uint8_t * apdu, + uint8_t tag_number, + BACNET_DEVICE_OBJECT_REFERENCE * value); + + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/bacnet-stack/src/bacdevobjpropref.c b/bacnet-stack/src/bacdevobjpropref.c index 8c257c98..3c65a386 100644 --- a/bacnet-stack/src/bacdevobjpropref.c +++ b/bacnet-stack/src/bacdevobjpropref.c @@ -38,7 +38,7 @@ #include "timestamp.h" #include "bacdevobjpropref.h" -/** @file bacdevobjpropref.c BACnet Application Device Object Property Reference */ +/** @file bacdevobjpropref.c BACnet Application Device Object (Property) Reference */ int bacapp_encode_context_device_obj_property_ref( uint8_t * apdu, @@ -174,6 +174,116 @@ int bacapp_decode_context_device_obj_property_ref( return len; } + +/* Functions for BACnetDeviceObjectReference: */ +int bacapp_encode_context_device_obj_ref( + uint8_t * apdu, + uint8_t tag_number, + BACNET_DEVICE_OBJECT_REFERENCE * value) +{ + int len; + int apdu_len = 0; + + len = encode_opening_tag(&apdu[apdu_len], tag_number); + apdu_len += len; + + len = bacapp_encode_device_obj_ref(&apdu[apdu_len], value); + apdu_len += len; + + len = encode_closing_tag(&apdu[apdu_len], tag_number); + apdu_len += len; + + return apdu_len; +} + +int bacapp_encode_device_obj_ref( + uint8_t * apdu, + BACNET_DEVICE_OBJECT_REFERENCE * value) +{ + int len; + int apdu_len = 0; + + /* Device id is optional so see if needed + * (set type to non device to omit */ + + if(value->deviceIndentifier.type == OBJECT_DEVICE) { + len = + encode_context_object_id(&apdu[apdu_len], 0, + (int) value->deviceIndentifier.type, + value->deviceIndentifier.instance); + apdu_len += len; + } + + len = + encode_context_object_id(&apdu[apdu_len], 1, + (int) value->objectIdentifier.type, value->objectIdentifier.instance); + apdu_len += len; + + return apdu_len; +} + +int bacapp_decode_device_obj_ref( + uint8_t * apdu, + BACNET_DEVICE_OBJECT_REFERENCE * value) +{ + int len; + int apdu_len = 0; + + /* Device ID is optional */ + if (decode_is_context_tag(&apdu[apdu_len], 0)) { + if (-1 == (len = + decode_context_object_id(&apdu[apdu_len], 0, + &value->deviceIndentifier.type, + &value->deviceIndentifier.instance))) { + return -1; + } + apdu_len += len; + } else { + value->deviceIndentifier.instance = 0; + value->deviceIndentifier.type = 0; + } + + if (-1 == (len = + decode_context_object_id(&apdu[apdu_len], 1, + &value->objectIdentifier.type, + &value->objectIdentifier.instance))) { + return -1; + } + apdu_len += len; + + return apdu_len; +} + +int bacapp_decode_context_device_obj_ref( + uint8_t * apdu, + uint8_t tag_number, + BACNET_DEVICE_OBJECT_REFERENCE * value) +{ + int len = 0; + int section_length; + + if (decode_is_opening_tag_number(&apdu[len], tag_number)) { + len++; + section_length = + bacapp_decode_device_obj_ref(&apdu[len], value); + + if (section_length == -1) { + len = -1; + } else { + len += section_length; + if (decode_is_closing_tag_number(&apdu[len], tag_number)) { + len++; + } else { + len = -1; + } + } + } else { + len = -1; + } + return len; +} + + #ifdef TEST void testDevIdPropRef( @@ -217,6 +327,40 @@ void testDevIdPropRef( inData.deviceIndentifier.type == outData.deviceIndentifier.type); } +void testDevIdRef( + Test * pTest) +{ + BACNET_DEVICE_OBJECT_REFERENCE inData; + BACNET_DEVICE_OBJECT_REFERENCE outData; + uint8_t buffer[MAX_APDU]; + int inLen; + int outLen; + + + inData.objectIdentifier.instance = 0x1234; + inData.objectIdentifier.type = 15; + + inData.deviceIndentifier.instance = 0x4343; + inData.deviceIndentifier.type = 28; + + inLen = bacapp_encode_device_obj_property_ref(buffer, &inData); + outLen = bacapp_decode_device_obj_property_ref(buffer, &outData); + + ct_test(pTest, outLen == inLen); + + ct_test(pTest, + inData.objectIdentifier.instance == outData.objectIdentifier.instance); + ct_test(pTest, + inData.objectIdentifier.type == outData.objectIdentifier.type); + + ct_test(pTest, + inData.deviceIndentifier.instance == + outData.deviceIndentifier.instance); + ct_test(pTest, + inData.deviceIndentifier.type == outData.deviceIndentifier.type); +} + + #ifdef TEST_DEV_ID_PROP_REF #include int main( @@ -229,6 +373,8 @@ int main( /* individual tests */ rc = ct_addTestFunction(pTest, testDevIdPropRef); assert(rc); + rc = ct_addTestFunction(pTest, testDevIdRef); + assert(rc); ct_setStream(pTest, stdout); ct_run(pTest);