diff --git a/src/bacnet/event.c b/src/bacnet/event.c index 33e918a0..170a9bdb 100644 --- a/src/bacnet/event.c +++ b/src/bacnet/event.c @@ -36,6 +36,7 @@ #include "bacnet/bacdcode.h" #include "bacnet/npdu.h" #include "bacnet/timestamp.h" +#include "bacnet/authentication_factor.h" /** @file event.c Encode/Decode Event Notifications */ @@ -252,6 +253,79 @@ int event_notify_encode_service_request( apdu_len += len; break; + case EVENT_COMMAND_FAILURE: + + len = encode_opening_tag(&apdu[apdu_len], 3); + apdu_len += len; + + len = encode_opening_tag(&apdu[apdu_len], 0); + apdu_len += len; + + switch (data->notificationParams.commandFailure.tag) { + case COMMAND_FAILURE_BINARY_PV: + len = + encode_application_enumerated(&apdu + [apdu_len], + data->notificationParams.commandFailure. + commandValue.binaryValue); + apdu_len += len; + break; + + case COMMAND_FAILURE_UNSIGNED: + len = + encode_application_unsigned(&apdu + [apdu_len], + data->notificationParams.commandFailure. + commandValue.unsignedValue); + apdu_len += len; + break; + + default: + return 0; + } + + len = encode_closing_tag(&apdu[apdu_len], 0); + apdu_len += len; + + len = + encode_context_bitstring(&apdu[apdu_len], 1, + &data->notificationParams.commandFailure. + statusFlags); + apdu_len += len; + + len = encode_opening_tag(&apdu[apdu_len], 2); + apdu_len += len; + + switch (data->notificationParams.commandFailure.tag) { + case COMMAND_FAILURE_BINARY_PV: + len = + encode_application_enumerated(&apdu + [apdu_len], + data->notificationParams.commandFailure. + feedbackValue.binaryValue); + apdu_len += len; + break; + + case COMMAND_FAILURE_UNSIGNED: + len = + encode_application_unsigned(&apdu + [apdu_len], + data->notificationParams.commandFailure. + feedbackValue.unsignedValue); + apdu_len += len; + break; + + default: + return 0; + } + + len = encode_closing_tag(&apdu[apdu_len], 2); + apdu_len += len; + + len = encode_closing_tag(&apdu[apdu_len], 3); + apdu_len += len; + break; + case EVENT_FLOATING_LIMIT: len = encode_opening_tag(&apdu[apdu_len], 4); apdu_len += len; @@ -376,8 +450,54 @@ int event_notify_encode_service_request( len = encode_closing_tag(&apdu[apdu_len], 11); apdu_len += len; break; + case EVENT_ACCESS_EVENT: + len = encode_opening_tag(&apdu[apdu_len], 13); + apdu_len += len; + + len = + encode_context_enumerated(&apdu[apdu_len], 0, + data->notificationParams.accessEvent.accessEvent); + apdu_len += len; + + len = + encode_context_bitstring(&apdu[apdu_len], 1, + &data->notificationParams.accessEvent.statusFlags); + apdu_len += len; + + len = + encode_context_unsigned(&apdu[apdu_len], 2, + data->notificationParams. + accessEvent.accessEventTag); + apdu_len += len; + + len = + bacapp_encode_context_timestamp(&apdu[apdu_len], 3, + &data->notificationParams. + accessEvent.accessEventTime); + apdu_len += len; + + len = + bacapp_encode_context_device_obj_ref(&apdu + [apdu_len], 4, + &data->notificationParams. + accessEvent.accessCredential); + apdu_len += len; + + if (data->notificationParams. + accessEvent.authenticationFactor.format_type < + AUTHENTICATION_FACTOR_MAX) { + len = + bacapp_encode_context_authentication_factor + (&apdu[apdu_len], 5, + &data->notificationParams. + accessEvent.authenticationFactor); + apdu_len += len; + } + + len = encode_closing_tag(&apdu[apdu_len], 13); + apdu_len += len; + break; case EVENT_EXTENDED: - case EVENT_COMMAND_FAILURE: default: assert(0); break; @@ -401,6 +521,8 @@ int event_notify_decode_service_request( int section_length = 0; BACNET_UNSIGNED_INTEGER unsigned_value = 0; uint32_t enum_value = 0; + uint32_t len_value = 0; + uint8_t tag_number = 0; if (apdu_len && data) { /* tag 0 - processIdentifier */ @@ -646,6 +768,105 @@ int event_notify_decode_service_request( len += section_length; break; + case EVENT_COMMAND_FAILURE: + if (!decode_is_opening_tag_number(&apdu[len], 0)) { + return -1; + } + len++; + + if (-1 == (section_length = + decode_tag_number_and_value(&apdu[len], + &tag_number, &len_value))) { + return -1; + } + len += section_length; + + switch (tag_number) { + case BACNET_APPLICATION_TAG_ENUMERATED: + if (-1 == (section_length = + decode_enumerated(&apdu[len], + len_value, + &data-> + notificationParams.commandFailure. + commandValue.binaryValue))) { + return -1; + } + break; + + case BACNET_APPLICATION_TAG_UNSIGNED_INT: + if (-1 == (section_length = + decode_unsigned(&apdu[len], len_value, + &data-> + notificationParams.commandFailure. + commandValue.unsignedValue))) { + return -1; + } + break; + + default: + return 0; + } + len += section_length; + + if (!decode_is_closing_tag_number(&apdu[len], 0)) { + return -1; + } + len++; + + if (-1 == (section_length = + decode_context_bitstring(&apdu[len], 1, + &data->notificationParams.commandFailure. + statusFlags))) { + return -1; + } + len += section_length; + + if (!decode_is_opening_tag_number(&apdu[len], 2)) { + return -1; + } + len++; + + if (-1 == (section_length = + decode_tag_number_and_value(&apdu[len], + &tag_number, &len_value))) { + return -1; + } + len += section_length; + + switch (tag_number) { + case BACNET_APPLICATION_TAG_ENUMERATED: + if (-1 == (section_length = + decode_enumerated(&apdu[len], + len_value, + &data-> + notificationParams.commandFailure. + feedbackValue.binaryValue))) { + return -1; + } + break; + + case BACNET_APPLICATION_TAG_UNSIGNED_INT: + if (-1 == (section_length = + decode_unsigned(&apdu[len], len_value, + &data-> + notificationParams.commandFailure. + feedbackValue.unsignedValue))) { + return -1; + } + break; + + default: + return 0; + } + len += section_length; + + if (!decode_is_closing_tag_number(&apdu[len], 2)) { + return -1; + } + len++; + + break; + case EVENT_FLOATING_LIMIT: if (-1 == (section_length = decode_context_real(&apdu[len], 0, @@ -836,6 +1057,60 @@ int event_notify_decode_service_request( } break; + case EVENT_ACCESS_EVENT: + if (-1 == (section_length = + decode_context_enumerated(&apdu[len], 0, + &data->notificationParams. + accessEvent.accessEvent))) { + return -1; + } + len += section_length; + + if (-1 == (section_length = + decode_context_bitstring(&apdu[len], 1, + &data->notificationParams. + accessEvent.statusFlags))) { + return -1; + } + len += section_length; + + if (-1 == (section_length = + decode_context_unsigned(&apdu[len], 2, + &data->notificationParams. + accessEvent.accessEventTag))) { + return -1; + } + len += section_length; + + if (-1 == (section_length = + bacapp_decode_context_timestamp(&apdu[len], 3, + &data->notificationParams. + accessEvent.accessEventTime))) { + return -1; + } + len += section_length; + + if (-1 == (section_length = + bacapp_decode_context_device_obj_ref(&apdu + [len], 4, + &data->notificationParams. + accessEvent.accessCredential))) { + return -1; + } + len += section_length; + + if (!decode_is_closing_tag(&apdu[len])) { + if (-1 == (section_length = + bacapp_decode_context_authentication_factor + (&apdu[len], 5, + &data->notificationParams. + accessEvent.authenticationFactor))) { + return -1; + } + len += section_length; + } + break; + default: return -1; } @@ -1204,6 +1479,102 @@ void testEventEventState(Test *pTest) &data.notificationParams.changeOfValue.newValue.changedBits, &data2.notificationParams.changeOfValue.newValue.changedBits)); + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /* + ** Event Type = EVENT_COMMAND_FAILURE + */ + + + /* + ** commandValue = enumerated + */ + data.eventType = EVENT_COMMAND_FAILURE; + data.notificationParams.commandFailure.tag = COMMAND_FAILURE_BINARY_PV; + data.notificationParams.commandFailure.commandValue.binaryValue = + BINARY_INACTIVE; + data.notificationParams.commandFailure.feedbackValue.binaryValue = + BINARY_ACTIVE; + + bitstring_init(&data.notificationParams.commandFailure.statusFlags); + + bitstring_set_bit(&data.notificationParams.commandFailure.statusFlags, + STATUS_FLAG_IN_ALARM, true); + bitstring_set_bit(&data.notificationParams.commandFailure.statusFlags, + STATUS_FLAG_FAULT, false); + bitstring_set_bit(&data.notificationParams.commandFailure.statusFlags, + STATUS_FLAG_OVERRIDDEN, false); + bitstring_set_bit(&data.notificationParams.commandFailure.statusFlags, + STATUS_FLAG_OUT_OF_SERVICE, false); + + memset(buffer, 0, MAX_APDU); + inLen = event_notify_encode_service_request(&buffer[0], &data); + + memset(&data2, 0, sizeof(data2)); + data2.messageText = &messageText2; + outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2); + + ct_test(pTest, inLen == outLen); + testBaseEventState(pTest); + + ct_test(pTest, + data.notificationParams.commandFailure.commandValue.binaryValue == + data2.notificationParams.commandFailure.commandValue.binaryValue); + + ct_test(pTest, + data.notificationParams.commandFailure.feedbackValue.binaryValue == + data2.notificationParams.commandFailure.feedbackValue.binaryValue); + + ct_test(pTest, + bitstring_same(&data.notificationParams.commandFailure.statusFlags, + &data2.notificationParams.commandFailure.statusFlags)); + + /* + ** commandValue = unsigned + */ + data.eventType = EVENT_COMMAND_FAILURE; + data.notificationParams.commandFailure.tag = COMMAND_FAILURE_UNSIGNED; + data.notificationParams.commandFailure.commandValue.unsignedValue = 10; + data.notificationParams.commandFailure.feedbackValue.unsignedValue = 2; + + bitstring_init(&data.notificationParams.commandFailure.statusFlags); + + bitstring_set_bit(&data.notificationParams.commandFailure.statusFlags, + STATUS_FLAG_IN_ALARM, true); + bitstring_set_bit(&data.notificationParams.commandFailure.statusFlags, + STATUS_FLAG_FAULT, false); + bitstring_set_bit(&data.notificationParams.commandFailure.statusFlags, + STATUS_FLAG_OVERRIDDEN, false); + bitstring_set_bit(&data.notificationParams.commandFailure.statusFlags, + STATUS_FLAG_OUT_OF_SERVICE, false); + + memset(buffer, 0, MAX_APDU); + inLen = event_notify_encode_service_request(&buffer[0], &data); + + memset(&data2, 0, sizeof(data2)); + data2.messageText = &messageText2; + outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2); + + ct_test(pTest, inLen == outLen); + testBaseEventState(pTest); + + ct_test(pTest, + data.notificationParams.commandFailure.commandValue.unsignedValue == + data2.notificationParams.commandFailure.commandValue.unsignedValue); + + ct_test(pTest, + data.notificationParams.commandFailure.feedbackValue.unsignedValue == + data2.notificationParams.commandFailure.feedbackValue.unsignedValue); + + ct_test(pTest, + bitstring_same(&data.notificationParams.commandFailure.statusFlags, + &data2.notificationParams.commandFailure.statusFlags)); + /**********************************************************************************/ /**********************************************************************************/ /**********************************************************************************/ @@ -1482,6 +1853,207 @@ void testEventEventState(Test *pTest) ct_test(pTest, data.notificationParams.bufferReady.bufferProperty.arrayIndex == data2.notificationParams.bufferReady.bufferProperty.arrayIndex); + + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /* + ** Event Type = EVENT_ACCESS_EVENT + */ + + // OPTIONAL authenticationFactor omitted + data.eventType = EVENT_ACCESS_EVENT; + data.notificationParams.accessEvent.accessEvent = + ACCESS_EVENT_LOCKED_BY_HIGHER_AUTHORITY; + data.notificationParams.accessEvent.accessEventTag = 7; + data.notificationParams.accessEvent.accessEventTime.tag = + TIME_STAMP_SEQUENCE; + data.notificationParams.accessEvent.accessEventTime.value.sequenceNum = 17; + data.notificationParams.accessEvent.accessCredential. + deviceIdentifier.instance = 1234; + data.notificationParams.accessEvent.accessCredential. + deviceIdentifier.type = OBJECT_DEVICE; + data.notificationParams.accessEvent.accessCredential. + objectIdentifier.instance = 17; + data.notificationParams.accessEvent.accessCredential. + objectIdentifier.type = OBJECT_ACCESS_POINT; + data.notificationParams.accessEvent.authenticationFactor.format_type = AUTHENTICATION_FACTOR_MAX; // omit authenticationFactor + + bitstring_init(&data.notificationParams.accessEvent.statusFlags); + bitstring_set_bit(&data.notificationParams.accessEvent.statusFlags, + STATUS_FLAG_IN_ALARM, true); + bitstring_set_bit(&data.notificationParams.accessEvent.statusFlags, + STATUS_FLAG_FAULT, false); + bitstring_set_bit(&data.notificationParams.accessEvent.statusFlags, + STATUS_FLAG_OVERRIDDEN, false); + bitstring_set_bit(&data.notificationParams.accessEvent.statusFlags, + STATUS_FLAG_OUT_OF_SERVICE, false); + + memset(buffer, 0, MAX_APDU); + inLen = event_notify_encode_service_request(&buffer[0], &data); + + memset(&data2, 0, sizeof(data2)); + data2.messageText = &messageText2; + outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2); + + ct_test(pTest, inLen == outLen); + testBaseEventState(pTest); + + ct_test(pTest, + data.notificationParams.accessEvent.accessEvent == + data2.notificationParams.accessEvent.accessEvent); + + ct_test(pTest, + bitstring_same(&data.notificationParams.accessEvent.statusFlags, + &data2.notificationParams.accessEvent.statusFlags)); + + ct_test(pTest, + data.notificationParams.accessEvent.accessEventTag == + data2.notificationParams.accessEvent.accessEventTag); + + ct_test(pTest, + data.notificationParams.accessEvent.accessEventTime.tag == + data2.notificationParams.accessEvent.accessEventTime.tag); + + ct_test(pTest, + data.notificationParams.accessEvent.accessEventTime. + value.sequenceNum == + data2.notificationParams.accessEvent.accessEventTime. + value.sequenceNum); + + ct_test(pTest, + data.notificationParams.accessEvent.accessCredential. + deviceIdentifier.instance == + data2.notificationParams.accessEvent.accessCredential. + deviceIdentifier.instance); + + ct_test(pTest, + data.notificationParams.accessEvent.accessCredential. + deviceIdentifier.type == + data2.notificationParams.accessEvent.accessCredential. + deviceIdentifier.type); + + ct_test(pTest, + data.notificationParams.accessEvent.accessCredential. + objectIdentifier.instance == + data2.notificationParams.accessEvent.accessCredential. + objectIdentifier.instance); + + ct_test(pTest, + data.notificationParams.accessEvent.accessCredential. + objectIdentifier.type == + data2.notificationParams.accessEvent.accessCredential. + objectIdentifier.type); + + // OPTIONAL authenticationFactor included + data.eventType = EVENT_ACCESS_EVENT; + data.notificationParams.accessEvent.accessEvent = + ACCESS_EVENT_LOCKED_BY_HIGHER_AUTHORITY; + data.notificationParams.accessEvent.accessEventTag = 7; + data.notificationParams.accessEvent.accessEventTime.tag = + TIME_STAMP_SEQUENCE; + data.notificationParams.accessEvent.accessEventTime.value.sequenceNum = 17; + data.notificationParams.accessEvent.accessCredential. + deviceIdentifier.instance = 1234; + data.notificationParams.accessEvent.accessCredential. + deviceIdentifier.type = OBJECT_DEVICE; + data.notificationParams.accessEvent.accessCredential. + objectIdentifier.instance = 17; + data.notificationParams.accessEvent.accessCredential. + objectIdentifier.type = OBJECT_ACCESS_POINT; + data.notificationParams.accessEvent.authenticationFactor.format_type = + AUTHENTICATION_FACTOR_SIMPLE_NUMBER16; + data.notificationParams.accessEvent.authenticationFactor.format_class = + 215; + uint8_t octetstringValue[2] = { 0x00, 0x10 }; + + octetstring_init(&data.notificationParams.accessEvent. + authenticationFactor.value, octetstringValue, 2); + + bitstring_init(&data.notificationParams.accessEvent.statusFlags); + bitstring_set_bit(&data.notificationParams.accessEvent.statusFlags, + STATUS_FLAG_IN_ALARM, true); + bitstring_set_bit(&data.notificationParams.accessEvent.statusFlags, + STATUS_FLAG_FAULT, false); + bitstring_set_bit(&data.notificationParams.accessEvent.statusFlags, + STATUS_FLAG_OVERRIDDEN, false); + bitstring_set_bit(&data.notificationParams.accessEvent.statusFlags, + STATUS_FLAG_OUT_OF_SERVICE, false); + + memset(buffer, 0, MAX_APDU); + inLen = event_notify_encode_service_request(&buffer[0], &data); + + memset(&data2, 0, sizeof(data2)); + data2.messageText = &messageText2; + outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2); + + ct_test(pTest, inLen == outLen); + testBaseEventState(pTest); + + ct_test(pTest, + data.notificationParams.accessEvent.accessEvent == + data2.notificationParams.accessEvent.accessEvent); + + ct_test(pTest, + bitstring_same(&data.notificationParams.accessEvent.statusFlags, + &data2.notificationParams.accessEvent.statusFlags)); + + ct_test(pTest, + data.notificationParams.accessEvent.accessEventTag == + data2.notificationParams.accessEvent.accessEventTag); + + ct_test(pTest, + data.notificationParams.accessEvent.accessEventTime.tag == + data2.notificationParams.accessEvent.accessEventTime.tag); + + ct_test(pTest, + data.notificationParams.accessEvent.accessEventTime. + value.sequenceNum == + data2.notificationParams.accessEvent.accessEventTime. + value.sequenceNum); + + ct_test(pTest, + data.notificationParams.accessEvent.accessCredential. + deviceIdentifier.instance == + data2.notificationParams.accessEvent.accessCredential. + deviceIdentifier.instance); + + ct_test(pTest, + data.notificationParams.accessEvent.accessCredential. + deviceIdentifier.type == + data2.notificationParams.accessEvent.accessCredential. + deviceIdentifier.type); + + ct_test(pTest, + data.notificationParams.accessEvent.accessCredential. + objectIdentifier.instance == + data2.notificationParams.accessEvent.accessCredential. + objectIdentifier.instance); + + ct_test(pTest, + data.notificationParams.accessEvent.accessCredential. + objectIdentifier.type == + data2.notificationParams.accessEvent.accessCredential. + objectIdentifier.type); + + ct_test(pTest, + data.notificationParams.accessEvent.authenticationFactor.format_type == + data2.notificationParams.accessEvent.authenticationFactor.format_type); + + ct_test(pTest, + data.notificationParams.accessEvent. + authenticationFactor.format_class == + data2.notificationParams.accessEvent. + authenticationFactor.format_class); + + ct_test(pTest, + octetstring_value_same(&data.notificationParams. + accessEvent.authenticationFactor.value, + &data2.notificationParams.accessEvent.authenticationFactor.value)); } #ifdef TEST_EVENT diff --git a/src/bacnet/event.h b/src/bacnet/event.h index 0966d256..f4175806 100644 --- a/src/bacnet/event.h +++ b/src/bacnet/event.h @@ -32,12 +32,18 @@ #include "bacnet/timestamp.h" #include "bacnet/bacpropstates.h" #include "bacnet/bacdevobjpropref.h" +#include "bacnet/authentication_factor.h" typedef enum { CHANGE_OF_VALUE_BITS, CHANGE_OF_VALUE_REAL } CHANGE_OF_VALUE_TYPE; +typedef enum { + COMMAND_FAILURE_BINARY_PV, + COMMAND_FAILURE_UNSIGNED +} COMMAND_FAILURE_TYPE; + /* ** Based on UnconfirmedEventNotification-Request */ @@ -87,10 +93,20 @@ typedef struct BACnet_Event_Notification_Data { BACNET_BIT_STRING statusFlags; } changeOfValue; /* - ** EVENT_COMMAND_FAILURE - ** - ** Not Supported! - */ + ** EVENT_COMMAND_FAILURE + */ + struct { + union { + BACNET_BINARY_PV binaryValue; + BACNET_UNSIGNED_INTEGER unsignedValue; + } commandValue; + COMMAND_FAILURE_TYPE tag; + BACNET_BIT_STRING statusFlags; + union { + BACNET_BINARY_PV binaryValue; + BACNET_UNSIGNED_INTEGER unsignedValue; + } feedbackValue; + } commandFailure; /* ** EVENT_FLOATING_LIMIT */ @@ -139,6 +155,19 @@ typedef struct BACnet_Event_Notification_Data { BACNET_BIT_STRING statusFlags; uint32_t exceededLimit; } unsignedRange; + /* + ** EVENT_ACCESS_EVENT + */ + struct { + BACNET_ACCESS_EVENT accessEvent; + BACNET_BIT_STRING statusFlags; + BACNET_UNSIGNED_INTEGER accessEventTag; + BACNET_TIMESTAMP accessEventTime; + BACNET_DEVICE_OBJECT_REFERENCE accessCredential; + BACNET_AUTHENTICATION_FACTOR authenticationFactor; + /* OPTIONAL - Set authenticationFactor.format_type to + AUTHENTICATION_FACTOR_MAX if not being used */ + } accessEvent; } notificationParams; } BACNET_EVENT_NOTIFICATION_DATA; diff --git a/test/bacnet/event/CMakeLists.txt b/test/bacnet/event/CMakeLists.txt index 0b73fd82..b1792732 100644 --- a/test/bacnet/event/CMakeLists.txt +++ b/test/bacnet/event/CMakeLists.txt @@ -34,6 +34,7 @@ add_executable(${PROJECT_NAME} # File(s) under test ${SRC_DIR}/bacnet/event.c # Support files and stubs (pathname alphabetical) + ${SRC_DIR}/bacnet/authentication_factor.c ${SRC_DIR}/bacnet/bacdcode.c ${SRC_DIR}/bacnet/bacint.c ${SRC_DIR}/bacnet/bacreal.c diff --git a/test/bacnet/event/src/main.c b/test/bacnet/event/src/main.c index d163ef5c..db09589c 100644 --- a/test/bacnet/event/src/main.c +++ b/test/bacnet/event/src/main.c @@ -356,6 +356,106 @@ static void testEventEventState(void) &data.notificationParams.changeOfValue.newValue.changedBits, &data2.notificationParams.changeOfValue.newValue.changedBits), NULL); + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /* + ** Event Type = EVENT_COMMAND_FAILURE + */ + + + /* + ** commandValue = enumerated + */ + data.eventType = EVENT_COMMAND_FAILURE; + data.notificationParams.commandFailure.tag = COMMAND_FAILURE_BINARY_PV; + data.notificationParams.commandFailure.commandValue.binaryValue = + BINARY_INACTIVE; + data.notificationParams.commandFailure.feedbackValue.binaryValue = + BINARY_ACTIVE; + + bitstring_init(&data.notificationParams.commandFailure.statusFlags); + + bitstring_set_bit(&data.notificationParams.commandFailure.statusFlags, + STATUS_FLAG_IN_ALARM, true); + bitstring_set_bit(&data.notificationParams.commandFailure.statusFlags, + STATUS_FLAG_FAULT, false); + bitstring_set_bit(&data.notificationParams.commandFailure.statusFlags, + STATUS_FLAG_OVERRIDDEN, false); + bitstring_set_bit(&data.notificationParams.commandFailure.statusFlags, + STATUS_FLAG_OUT_OF_SERVICE, false); + + memset(buffer, 0, MAX_APDU); + inLen = event_notify_encode_service_request(&buffer[0], &data); + + memset(&data2, 0, sizeof(data2)); + data2.messageText = &messageText2; + outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2); + + zassert_equal(inLen, outLen, NULL); + verifyBaseEventState(); + + zassert_equal( + data.notificationParams.commandFailure.commandValue.binaryValue, + data2.notificationParams.commandFailure.commandValue.binaryValue, + NULL); + + zassert_equal( + data.notificationParams.commandFailure.feedbackValue.binaryValue, + data2.notificationParams.commandFailure.feedbackValue.binaryValue, + NULL); + + zassert_true( + bitstring_same(&data.notificationParams.commandFailure.statusFlags, + &data2.notificationParams.commandFailure.statusFlags), NULL); + + /* + ** commandValue = unsigned + */ + data.eventType = EVENT_COMMAND_FAILURE; + data.notificationParams.commandFailure.tag = COMMAND_FAILURE_UNSIGNED; + data.notificationParams.commandFailure.commandValue.unsignedValue = 10; + data.notificationParams.commandFailure.feedbackValue.unsignedValue = 2; + + bitstring_init(&data.notificationParams.commandFailure.statusFlags); + + bitstring_set_bit(&data.notificationParams.commandFailure.statusFlags, + STATUS_FLAG_IN_ALARM, true); + bitstring_set_bit(&data.notificationParams.commandFailure.statusFlags, + STATUS_FLAG_FAULT, false); + bitstring_set_bit(&data.notificationParams.commandFailure.statusFlags, + STATUS_FLAG_OVERRIDDEN, false); + bitstring_set_bit(&data.notificationParams.commandFailure.statusFlags, + STATUS_FLAG_OUT_OF_SERVICE, false); + + memset(buffer, 0, MAX_APDU); + inLen = event_notify_encode_service_request(&buffer[0], &data); + + memset(&data2, 0, sizeof(data2)); + data2.messageText = &messageText2; + outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2); + + zassert_equal(inLen, outLen, NULL); + verifyBaseEventState(); + + zassert_equal( + data.notificationParams.commandFailure.commandValue.unsignedValue, + data2.notificationParams.commandFailure.commandValue.unsignedValue, + NULL); + + zassert_equal( + data.notificationParams.commandFailure.feedbackValue.unsignedValue, + data2.notificationParams.commandFailure.feedbackValue.unsignedValue, + NULL); + + zassert_true( + bitstring_same(&data.notificationParams.commandFailure.statusFlags, + &data2.notificationParams.commandFailure.statusFlags), NULL); + /**********************************************************************************/ /**********************************************************************************/ /**********************************************************************************/ @@ -634,6 +734,208 @@ static void testEventEventState(void) zassert_equal( data.notificationParams.bufferReady.bufferProperty.arrayIndex, data2.notificationParams.bufferReady.bufferProperty.arrayIndex, NULL); + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /* + ** Event Type = EVENT_ACCESS_EVENT + */ + + // OPTIONAL authenticationFactor omitted + data.eventType = EVENT_ACCESS_EVENT; + data.notificationParams.accessEvent.accessEvent = + ACCESS_EVENT_LOCKED_BY_HIGHER_AUTHORITY; + data.notificationParams.accessEvent.accessEventTag = 7; + data.notificationParams.accessEvent.accessEventTime.tag = + TIME_STAMP_SEQUENCE; + data.notificationParams.accessEvent.accessEventTime.value.sequenceNum = 17; + data.notificationParams.accessEvent.accessCredential. + deviceIdentifier.instance = 1234; + data.notificationParams.accessEvent.accessCredential. + deviceIdentifier.type = OBJECT_DEVICE; + data.notificationParams.accessEvent.accessCredential. + objectIdentifier.instance = 17; + data.notificationParams.accessEvent.accessCredential. + objectIdentifier.type = OBJECT_ACCESS_POINT; + data.notificationParams.accessEvent.authenticationFactor.format_type = AUTHENTICATION_FACTOR_MAX; // omit authenticationFactor + + bitstring_init(&data.notificationParams.accessEvent.statusFlags); + bitstring_set_bit(&data.notificationParams.accessEvent.statusFlags, + STATUS_FLAG_IN_ALARM, true); + bitstring_set_bit(&data.notificationParams.accessEvent.statusFlags, + STATUS_FLAG_FAULT, false); + bitstring_set_bit(&data.notificationParams.accessEvent.statusFlags, + STATUS_FLAG_OVERRIDDEN, false); + bitstring_set_bit(&data.notificationParams.accessEvent.statusFlags, + STATUS_FLAG_OUT_OF_SERVICE, false); + + memset(buffer, 0, MAX_APDU); + inLen = event_notify_encode_service_request(&buffer[0], &data); + + memset(&data2, 0, sizeof(data2)); + data2.messageText = &messageText2; + outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2); + + zassert_equal(inLen, outLen, NULL); + verifyBaseEventState(); + + zassert_equal( + data.notificationParams.accessEvent.accessEvent, + data2.notificationParams.accessEvent.accessEvent, NULL); + + zassert_true( + bitstring_same(&data.notificationParams.accessEvent.statusFlags, + &data2.notificationParams.accessEvent.statusFlags), NULL); + + zassert_equal( + data.notificationParams.accessEvent.accessEventTag, + data2.notificationParams.accessEvent.accessEventTag, NULL); + + zassert_equal( + data.notificationParams.accessEvent.accessEventTime.tag, + data2.notificationParams.accessEvent.accessEventTime.tag, NULL); + + zassert_equal( + data.notificationParams.accessEvent.accessEventTime. + value.sequenceNum, + data2.notificationParams.accessEvent.accessEventTime. + value.sequenceNum, NULL); + + zassert_equal( + data.notificationParams.accessEvent.accessCredential. + deviceIdentifier.instance, + data2.notificationParams.accessEvent.accessCredential. + deviceIdentifier.instance, NULL); + + zassert_equal( + data.notificationParams.accessEvent.accessCredential. + deviceIdentifier.type, + data2.notificationParams.accessEvent.accessCredential. + deviceIdentifier.type, NULL); + + zassert_equal( + data.notificationParams.accessEvent.accessCredential. + objectIdentifier.instance, + data2.notificationParams.accessEvent.accessCredential. + objectIdentifier.instance, NULL); + + zassert_equal( + data.notificationParams.accessEvent.accessCredential. + objectIdentifier.type, + data2.notificationParams.accessEvent.accessCredential. + objectIdentifier.type, NULL); + + // OPTIONAL authenticationFactor included + data.eventType = EVENT_ACCESS_EVENT; + data.notificationParams.accessEvent.accessEvent = + ACCESS_EVENT_LOCKED_BY_HIGHER_AUTHORITY; + data.notificationParams.accessEvent.accessEventTag = 7; + data.notificationParams.accessEvent.accessEventTime.tag = + TIME_STAMP_SEQUENCE; + data.notificationParams.accessEvent.accessEventTime.value.sequenceNum = 17; + data.notificationParams.accessEvent.accessCredential. + deviceIdentifier.instance = 1234; + data.notificationParams.accessEvent.accessCredential. + deviceIdentifier.type = OBJECT_DEVICE; + data.notificationParams.accessEvent.accessCredential. + objectIdentifier.instance = 17; + data.notificationParams.accessEvent.accessCredential. + objectIdentifier.type = OBJECT_ACCESS_POINT; + data.notificationParams.accessEvent.authenticationFactor.format_type = + AUTHENTICATION_FACTOR_SIMPLE_NUMBER16; + data.notificationParams.accessEvent.authenticationFactor.format_class = + 215; + uint8_t octetstringValue[2] = { 0x00, 0x10 }; + + octetstring_init(&data.notificationParams.accessEvent. + authenticationFactor.value, octetstringValue, 2); + + bitstring_init(&data.notificationParams.accessEvent.statusFlags); + bitstring_set_bit(&data.notificationParams.accessEvent.statusFlags, + STATUS_FLAG_IN_ALARM, true); + bitstring_set_bit(&data.notificationParams.accessEvent.statusFlags, + STATUS_FLAG_FAULT, false); + bitstring_set_bit(&data.notificationParams.accessEvent.statusFlags, + STATUS_FLAG_OVERRIDDEN, false); + bitstring_set_bit(&data.notificationParams.accessEvent.statusFlags, + STATUS_FLAG_OUT_OF_SERVICE, false); + + memset(buffer, 0, MAX_APDU); + inLen = event_notify_encode_service_request(&buffer[0], &data); + + memset(&data2, 0, sizeof(data2)); + data2.messageText = &messageText2; + outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2); + + zassert_equal(inLen, outLen, NULL); + verifyBaseEventState(); + + zassert_equal( + data.notificationParams.accessEvent.accessEvent, + data2.notificationParams.accessEvent.accessEvent, NULL); + + zassert_true( + bitstring_same(&data.notificationParams.accessEvent.statusFlags, + &data2.notificationParams.accessEvent.statusFlags), NULL); + + zassert_equal( + data.notificationParams.accessEvent.accessEventTag, + data2.notificationParams.accessEvent.accessEventTag, NULL); + + zassert_equal( + data.notificationParams.accessEvent.accessEventTime.tag, + data2.notificationParams.accessEvent.accessEventTime.tag, NULL); + + zassert_equal( + data.notificationParams.accessEvent.accessEventTime. + value.sequenceNum, + data2.notificationParams.accessEvent.accessEventTime. + value.sequenceNum, NULL); + + zassert_equal( + data.notificationParams.accessEvent.accessCredential. + deviceIdentifier.instance, + data2.notificationParams.accessEvent.accessCredential. + deviceIdentifier.instance, NULL); + + zassert_equal( + data.notificationParams.accessEvent.accessCredential. + deviceIdentifier.type, + data2.notificationParams.accessEvent.accessCredential. + deviceIdentifier.type, NULL); + + zassert_equal( + data.notificationParams.accessEvent.accessCredential. + objectIdentifier.instance, + data2.notificationParams.accessEvent.accessCredential. + objectIdentifier.instance, NULL); + + zassert_equal( + data.notificationParams.accessEvent.accessCredential. + objectIdentifier.type, + data2.notificationParams.accessEvent.accessCredential. + objectIdentifier.type, NULL); + + zassert_equal( + data.notificationParams.accessEvent.authenticationFactor.format_type, + data2.notificationParams.accessEvent.authenticationFactor.format_type, + NULL); + + zassert_equal( + data.notificationParams.accessEvent. + authenticationFactor.format_class, + data2.notificationParams.accessEvent. + authenticationFactor.format_class, NULL); + + zassert_true( + octetstring_value_same(&data.notificationParams. + accessEvent.authenticationFactor.value, + &data2.notificationParams.accessEvent.authenticationFactor.value), + NULL); } /** * @} diff --git a/test/event.mak b/test/event.mak index 383efad9..14b2f495 100644 --- a/test/event.mak +++ b/test/event.mak @@ -21,6 +21,7 @@ SRCS = $(SRC_DIR)/bacnet/bacdcode.c \ $(SRC_DIR)/bacnet/bacpropstates.c \ $(SRC_DIR)/bacnet/bacdevobjpropref.c \ $(SRC_DIR)/bacnet/event.c \ + $(SRC_DIR)/bacnet/authentication_factor.c \ ctest.c TARGET_NAME = event