Bugfix/service request refactor size check (#553)
* refactor service requests from service header * add APDU size checking and length feature * add unit tests to check for length when passing NULL buffer --------- Co-authored-by: Steve Karg <skarg@users.sourceforge.net>
This commit is contained in:
@@ -121,6 +121,28 @@ int arf_service_encode_apdu(uint8_t *apdu, BACNET_ATOMIC_READ_FILE_DATA *data)
|
|||||||
return apdu_len;
|
return apdu_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Encode the AtomicReadFile service request
|
||||||
|
* @param apdu Pointer to the buffer for encoded values
|
||||||
|
* @param apdu_size number of bytes available in the buffer
|
||||||
|
* @param data Pointer to the service data used for encoding values
|
||||||
|
* @return number of bytes encoded, or zero if unable to encode or too large
|
||||||
|
*/
|
||||||
|
size_t atomicreadfile_service_request_encode(
|
||||||
|
uint8_t *apdu, size_t apdu_size, BACNET_ATOMIC_READ_FILE_DATA *data)
|
||||||
|
{
|
||||||
|
size_t apdu_len = 0; /* total length of the apdu, return value */
|
||||||
|
|
||||||
|
apdu_len = arf_service_encode_apdu(NULL, data);
|
||||||
|
if (apdu_len > apdu_size) {
|
||||||
|
apdu_len = 0;
|
||||||
|
} else {
|
||||||
|
apdu_len = arf_service_encode_apdu(apdu, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return apdu_len;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Encode the AtomicReadFile service request
|
* @brief Encode the AtomicReadFile service request
|
||||||
* @param apdu Pointer to the buffer for decoding.
|
* @param apdu Pointer to the buffer for decoding.
|
||||||
|
|||||||
@@ -69,6 +69,11 @@ extern "C" {
|
|||||||
int arf_service_encode_apdu(
|
int arf_service_encode_apdu(
|
||||||
uint8_t *apdu,
|
uint8_t *apdu,
|
||||||
BACNET_ATOMIC_READ_FILE_DATA *data);
|
BACNET_ATOMIC_READ_FILE_DATA *data);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
size_t atomicreadfile_service_request_encode(
|
||||||
|
uint8_t *apdu,
|
||||||
|
size_t apdu_size,
|
||||||
|
BACNET_ATOMIC_READ_FILE_DATA *data);
|
||||||
|
|
||||||
/* decode the service request only */
|
/* decode the service request only */
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
|
|||||||
@@ -26,27 +26,37 @@
|
|||||||
#include "bacnet/authentication_factor.h"
|
#include "bacnet/authentication_factor.h"
|
||||||
#include "bacnet/bacdcode.h"
|
#include "bacnet/bacdcode.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Encode the BACnetAuthenticationFactor complex data
|
||||||
|
* @param apdu Pointer to the buffer for encoding into, or NULL for length
|
||||||
|
* @param data Pointer used for encoding the value
|
||||||
|
* @return number of bytes encoded, or zero if unable to encode
|
||||||
|
*/
|
||||||
int bacapp_encode_authentication_factor(
|
int bacapp_encode_authentication_factor(
|
||||||
uint8_t *apdu, BACNET_AUTHENTICATION_FACTOR *af)
|
uint8_t *apdu, BACNET_AUTHENTICATION_FACTOR *af)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
int apdu_len = 0;
|
int apdu_len = 0;
|
||||||
|
|
||||||
len = encode_context_enumerated(&apdu[apdu_len], 0, af->format_type);
|
len = encode_context_enumerated(apdu, 0, af->format_type);
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
len = encode_context_unsigned(&apdu[apdu_len], 1, af->format_class);
|
len = encode_context_unsigned(apdu, 1, af->format_class);
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
len = encode_context_octet_string(&apdu[apdu_len], 2, &af->value);
|
len = encode_context_octet_string(apdu, 2, &af->value);
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
@@ -56,24 +66,40 @@ int bacapp_encode_authentication_factor(
|
|||||||
return apdu_len;
|
return apdu_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Encode the BACnetAuthenticationFactor context tagged complex data
|
||||||
|
* @param apdu Pointer to the buffer for encoding into, or NULL for length
|
||||||
|
* @param data Pointer used for encoding the value
|
||||||
|
* @return number of bytes encoded, or zero if unable to encode
|
||||||
|
*/
|
||||||
int bacapp_encode_context_authentication_factor(
|
int bacapp_encode_context_authentication_factor(
|
||||||
uint8_t *apdu, uint8_t tag, BACNET_AUTHENTICATION_FACTOR *af)
|
uint8_t *apdu, uint8_t tag, BACNET_AUTHENTICATION_FACTOR *af)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
int apdu_len = 0;
|
int apdu_len = 0;
|
||||||
|
|
||||||
len = encode_opening_tag(&apdu[apdu_len], tag);
|
len = encode_opening_tag(apdu, tag);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = bacapp_encode_authentication_factor(&apdu[apdu_len], af);
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = bacapp_encode_authentication_factor(apdu, af);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_closing_tag(&apdu[apdu_len], tag);
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_closing_tag(apdu, tag);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
|
||||||
return apdu_len;
|
return apdu_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Decode the BACnetAuthenticationFactor complex data
|
||||||
|
* @param apdu Pointer to the buffer for decoding.
|
||||||
|
* @param af Pointer to the property decoded data to be stored
|
||||||
|
* @return Bytes decoded or BACNET_STATUS_REJECT on error.
|
||||||
|
*/
|
||||||
int bacapp_decode_authentication_factor(
|
int bacapp_decode_authentication_factor(
|
||||||
uint8_t *apdu, BACNET_AUTHENTICATION_FACTOR *af)
|
uint8_t *apdu, BACNET_AUTHENTICATION_FACTOR *af)
|
||||||
{
|
{
|
||||||
@@ -123,6 +149,13 @@ int bacapp_decode_authentication_factor(
|
|||||||
return apdu_len;
|
return apdu_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Decode the context tagged BACnetAuthenticationFactor complex data
|
||||||
|
* @param apdu Pointer to the buffer for decoding.
|
||||||
|
* @param tag context tag number wrapping the complex data
|
||||||
|
* @param af Pointer to the property decoded data to be stored
|
||||||
|
* @return Bytes decoded or BACNET_STATUS_REJECT on error.
|
||||||
|
*/
|
||||||
int bacapp_decode_context_authentication_factor(
|
int bacapp_decode_context_authentication_factor(
|
||||||
uint8_t *apdu, uint8_t tag, BACNET_AUTHENTICATION_FACTOR *af)
|
uint8_t *apdu, uint8_t tag, BACNET_AUTHENTICATION_FACTOR *af)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -129,6 +129,28 @@ int awf_service_encode_apdu(uint8_t *apdu, BACNET_ATOMIC_WRITE_FILE_DATA *data)
|
|||||||
return apdu_len;
|
return apdu_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Encode the AtomicWriteFile service request
|
||||||
|
* @param apdu Pointer to the buffer for encoded values
|
||||||
|
* @param apdu_size number of bytes available in the buffer
|
||||||
|
* @param data Pointer to the service data used for encoding values
|
||||||
|
* @return number of bytes encoded, or zero if unable to encode or too large
|
||||||
|
*/
|
||||||
|
int atomicwritefile_service_request_encode(
|
||||||
|
uint8_t *apdu, size_t apdu_size, BACNET_ATOMIC_WRITE_FILE_DATA *data)
|
||||||
|
{
|
||||||
|
size_t apdu_len = 0; /* total length of the apdu, return value */
|
||||||
|
|
||||||
|
apdu_len = awf_service_encode_apdu(NULL, data);
|
||||||
|
if (apdu_len > apdu_size) {
|
||||||
|
apdu_len = 0;
|
||||||
|
} else {
|
||||||
|
apdu_len = awf_service_encode_apdu(apdu, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return apdu_len;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Encode the AtomicWriteFile service request
|
* @brief Encode the AtomicWriteFile service request
|
||||||
* @param apdu Pointer to the buffer for decoding.
|
* @param apdu Pointer to the buffer for decoding.
|
||||||
|
|||||||
@@ -58,6 +58,12 @@ extern "C" {
|
|||||||
uint8_t *apdu,
|
uint8_t *apdu,
|
||||||
BACNET_ATOMIC_WRITE_FILE_DATA *data);
|
BACNET_ATOMIC_WRITE_FILE_DATA *data);
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
|
int atomicwritefile_service_request_encode(
|
||||||
|
uint8_t *apdu,
|
||||||
|
size_t apdu_size,
|
||||||
|
BACNET_ATOMIC_WRITE_FILE_DATA *data);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
int awf_encode_apdu(
|
int awf_encode_apdu(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
uint8_t invoke_id,
|
uint8_t invoke_id,
|
||||||
|
|||||||
+22
-17
@@ -210,83 +210,88 @@ int bacapp_decode_context_property_state(
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Encode the BACnetPropertyState
|
||||||
|
* @param apdu Pointer to the buffer for encoding into, or NULL for length
|
||||||
|
* @param value Pointer to the value used for encoding
|
||||||
|
* @return number of bytes encoded, or zero if unable to encode
|
||||||
|
*/
|
||||||
int bacapp_encode_property_state(uint8_t *apdu, BACNET_PROPERTY_STATE *value)
|
int bacapp_encode_property_state(uint8_t *apdu, BACNET_PROPERTY_STATE *value)
|
||||||
{
|
{
|
||||||
int len = 0; /* length of each encoding */
|
int len = 0; /* length of each encoding */
|
||||||
if (value && apdu) {
|
|
||||||
|
if (value) {
|
||||||
switch (value->tag) {
|
switch (value->tag) {
|
||||||
case BOOLEAN_VALUE:
|
case BOOLEAN_VALUE:
|
||||||
len = encode_context_boolean(
|
len = encode_context_boolean(
|
||||||
&apdu[0], 0, value->state.booleanValue);
|
apdu, 0, value->state.booleanValue);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BINARY_VALUE:
|
case BINARY_VALUE:
|
||||||
len = encode_context_enumerated(
|
len = encode_context_enumerated(
|
||||||
&apdu[0], 1, value->state.binaryValue);
|
apdu, 1, value->state.binaryValue);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EVENT_TYPE:
|
case EVENT_TYPE:
|
||||||
len = encode_context_enumerated(
|
len = encode_context_enumerated(
|
||||||
&apdu[0], 2, value->state.eventType);
|
apdu, 2, value->state.eventType);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case POLARITY:
|
case POLARITY:
|
||||||
len = encode_context_enumerated(
|
len = encode_context_enumerated(
|
||||||
&apdu[0], 3, value->state.polarity);
|
apdu, 3, value->state.polarity);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROGRAM_CHANGE:
|
case PROGRAM_CHANGE:
|
||||||
len = encode_context_enumerated(
|
len = encode_context_enumerated(
|
||||||
&apdu[0], 4, value->state.programChange);
|
apdu, 4, value->state.programChange);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROGRAM_STATE:
|
case PROGRAM_STATE:
|
||||||
len = encode_context_enumerated(
|
len = encode_context_enumerated(
|
||||||
&apdu[0], 5, value->state.programState);
|
apdu, 5, value->state.programState);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case REASON_FOR_HALT:
|
case REASON_FOR_HALT:
|
||||||
len = encode_context_enumerated(
|
len = encode_context_enumerated(
|
||||||
&apdu[0], 6, value->state.programError);
|
apdu, 6, value->state.programError);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RELIABILITY:
|
case RELIABILITY:
|
||||||
len = encode_context_enumerated(
|
len = encode_context_enumerated(
|
||||||
&apdu[0], 7, value->state.reliability);
|
apdu, 7, value->state.reliability);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STATE:
|
case STATE:
|
||||||
len =
|
len =
|
||||||
encode_context_enumerated(&apdu[0], 8, value->state.state);
|
encode_context_enumerated(apdu, 8, value->state.state);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SYSTEM_STATUS:
|
case SYSTEM_STATUS:
|
||||||
len = encode_context_enumerated(
|
len = encode_context_enumerated(
|
||||||
&apdu[0], 9, value->state.systemStatus);
|
apdu, 9, value->state.systemStatus);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UNITS:
|
case UNITS:
|
||||||
len =
|
len =
|
||||||
encode_context_enumerated(&apdu[0], 10, value->state.units);
|
encode_context_enumerated(apdu, 10, value->state.units);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UNSIGNED_VALUE:
|
case UNSIGNED_VALUE:
|
||||||
len = encode_context_unsigned(
|
len = encode_context_unsigned(
|
||||||
&apdu[0], 11, value->state.unsignedValue);
|
apdu, 11, value->state.unsignedValue);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIFE_SAFETY_MODE:
|
case LIFE_SAFETY_MODE:
|
||||||
len = encode_context_enumerated(
|
len = encode_context_enumerated(
|
||||||
&apdu[0], 12, value->state.lifeSafetyMode);
|
apdu, 12, value->state.lifeSafetyMode);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIFE_SAFETY_STATE:
|
case LIFE_SAFETY_STATE:
|
||||||
len = encode_context_enumerated(
|
len = encode_context_enumerated(
|
||||||
&apdu[0], 13, value->state.lifeSafetyState);
|
apdu, 13, value->state.lifeSafetyState);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* FIXME: assert(0); - return a negative len? */
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,6 +46,16 @@
|
|||||||
# include <strings.h>
|
# include <strings.h>
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
/* some common min/max as defined in windef.h */
|
||||||
|
#ifndef NOMINMAX
|
||||||
|
#ifndef max
|
||||||
|
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||||
|
#endif
|
||||||
|
#ifndef min
|
||||||
|
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||||
|
#endif
|
||||||
|
#endif /* NOMINMAX */
|
||||||
|
|
||||||
#if defined(__MINGW32__)
|
#if defined(__MINGW32__)
|
||||||
#define BACNET_STACK_FALLTHROUGH() /* fall through */
|
#define BACNET_STACK_FALLTHROUGH() /* fall through */
|
||||||
#elif defined(__GNUC__)
|
#elif defined(__GNUC__)
|
||||||
|
|||||||
+245
-112
@@ -36,7 +36,6 @@
|
|||||||
#include "bacnet/bacdcode.h"
|
#include "bacnet/bacdcode.h"
|
||||||
#include "bacnet/bacdef.h"
|
#include "bacnet/bacdef.h"
|
||||||
#include "bacnet/bacapp.h"
|
#include "bacnet/bacapp.h"
|
||||||
#include "bacnet/memcopy.h"
|
|
||||||
/* me! */
|
/* me! */
|
||||||
#include "bacnet/cov.h"
|
#include "bacnet/cov.h"
|
||||||
|
|
||||||
@@ -53,7 +52,7 @@ Unconfirmed COV Notification
|
|||||||
* @brief Encode APDU for COV Notification.
|
* @brief Encode APDU for COV Notification.
|
||||||
* @param apdu Pointer to the buffer, or NULL for length
|
* @param apdu Pointer to the buffer, or NULL for length
|
||||||
* @param data Pointer to the data to encode.
|
* @param data Pointer to the data to encode.
|
||||||
* @return bytes encoded or zero on error.
|
* @return number of bytes encoded, or zero on error.
|
||||||
*/
|
*/
|
||||||
int cov_notify_encode_apdu(uint8_t *apdu, BACNET_COV_DATA *data)
|
int cov_notify_encode_apdu(uint8_t *apdu, BACNET_COV_DATA *data)
|
||||||
{
|
{
|
||||||
@@ -61,7 +60,9 @@ int cov_notify_encode_apdu(uint8_t *apdu, BACNET_COV_DATA *data)
|
|||||||
int apdu_len = 0; /* total length of the apdu, return value */
|
int apdu_len = 0; /* total length of the apdu, return value */
|
||||||
BACNET_PROPERTY_VALUE *value = NULL; /* value in list */
|
BACNET_PROPERTY_VALUE *value = NULL; /* value in list */
|
||||||
|
|
||||||
if (apdu) {
|
if (!data) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
/* tag 0 - subscriberProcessIdentifier */
|
/* tag 0 - subscriberProcessIdentifier */
|
||||||
len =
|
len =
|
||||||
encode_context_unsigned(apdu, 0, data->subscriberProcessIdentifier);
|
encode_context_unsigned(apdu, 0, data->subscriberProcessIdentifier);
|
||||||
@@ -109,24 +110,21 @@ int cov_notify_encode_apdu(uint8_t *apdu, BACNET_COV_DATA *data)
|
|||||||
}
|
}
|
||||||
len = encode_closing_tag(apdu, 4);
|
len = encode_closing_tag(apdu, 4);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
}
|
|
||||||
|
|
||||||
return apdu_len;
|
return apdu_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encode APDU for notification.
|
* @brief Encode the COVNotification service request
|
||||||
*
|
|
||||||
* @param apdu Pointer to the buffer for encoding into
|
* @param apdu Pointer to the buffer for encoding into
|
||||||
* @param apdu_size number of bytes available in the buffer
|
* @param apdu_size number of bytes available in the buffer
|
||||||
* @param data Pointer to the data to encode.
|
* @param data Pointer to the service data used for encoding values
|
||||||
*
|
* @return number of bytes encoded, or zero if unable to encode or too large
|
||||||
* @return bytes encoded or zero if unable to encode
|
|
||||||
*/
|
*/
|
||||||
static int notify_encode_apdu(
|
size_t cov_notify_service_request_encode(
|
||||||
uint8_t *apdu, unsigned apdu_size, BACNET_COV_DATA *data)
|
uint8_t *apdu, size_t apdu_size, BACNET_COV_DATA *data)
|
||||||
{
|
{
|
||||||
int apdu_len = 0; /* total length of the apdu, return value */
|
size_t apdu_len = 0; /* total length of the apdu, return value */
|
||||||
|
|
||||||
apdu_len = cov_notify_encode_apdu(NULL, data);
|
apdu_len = cov_notify_encode_apdu(NULL, data);
|
||||||
if (apdu_len > apdu_size) {
|
if (apdu_len > apdu_size) {
|
||||||
@@ -141,67 +139,71 @@ static int notify_encode_apdu(
|
|||||||
/**
|
/**
|
||||||
* Encode APDU for confirmed notification.
|
* Encode APDU for confirmed notification.
|
||||||
*
|
*
|
||||||
* @param apdu Pointer to the buffer.
|
* @param apdu Pointer to the buffer, or NULL for length
|
||||||
* @param max_apdu_len Buffer size.
|
* @param apdu_size number of bytes available in the buffer
|
||||||
* @param invoke_id ID to invoke for notification
|
* @param invoke_id ID to invoke for notification
|
||||||
* @param data Pointer to the data to encode.
|
* @param data Pointer to the data to encode.
|
||||||
*
|
*
|
||||||
* @return bytes encoded or zero on error.
|
* @return bytes encoded or zero on error.
|
||||||
*/
|
*/
|
||||||
int ccov_notify_encode_apdu(uint8_t *apdu,
|
int ccov_notify_encode_apdu(uint8_t *apdu,
|
||||||
unsigned max_apdu_len,
|
unsigned apdu_size,
|
||||||
uint8_t invoke_id,
|
uint8_t invoke_id,
|
||||||
BACNET_COV_DATA *data)
|
BACNET_COV_DATA *data)
|
||||||
{
|
{
|
||||||
int len = 0; /* length of each encoding */
|
int len = 0; /* length of each encoding */
|
||||||
int apdu_len = BACNET_STATUS_ERROR; /* return value */
|
int apdu_len = 0; /* return value */
|
||||||
|
|
||||||
if (apdu && data && memcopylen(0, max_apdu_len, 4)) {
|
if (apdu && (apdu_size > 4)) {
|
||||||
apdu[0] = PDU_TYPE_CONFIRMED_SERVICE_REQUEST;
|
apdu[0] = PDU_TYPE_CONFIRMED_SERVICE_REQUEST;
|
||||||
apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU);
|
apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU);
|
||||||
apdu[2] = invoke_id;
|
apdu[2] = invoke_id;
|
||||||
apdu[3] = SERVICE_CONFIRMED_COV_NOTIFICATION;
|
apdu[3] = SERVICE_CONFIRMED_COV_NOTIFICATION;
|
||||||
apdu_len = 4;
|
|
||||||
len =
|
|
||||||
notify_encode_apdu(&apdu[apdu_len], max_apdu_len - apdu_len, data);
|
|
||||||
if (len <= 0) {
|
|
||||||
/* return the error */
|
|
||||||
apdu_len = len;
|
|
||||||
} else {
|
|
||||||
apdu_len += len;
|
|
||||||
}
|
}
|
||||||
|
len = 4;
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = cov_notify_service_request_encode(
|
||||||
|
apdu, apdu_size - apdu_len, data);
|
||||||
|
if (len > 0) {
|
||||||
|
apdu_len += len;
|
||||||
|
} else {
|
||||||
|
apdu_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return apdu_len;
|
return apdu_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encode APDU for unconfirmed notification.
|
* @brief Encode APDU for unconfirmed notification.
|
||||||
*
|
* @param apdu Pointer to the buffer for encoding into, or NULL for length
|
||||||
* @param apdu Pointer to the buffer.
|
* @param apdu_size number of bytes available in the buffer
|
||||||
* @param max_apdu_len Buffer size.
|
* @param data Pointer to the service data used for encoding values
|
||||||
* @param data Pointer to the data to encode.
|
* @return number of bytes encoded, or zero if unable to encode or too large
|
||||||
*
|
|
||||||
* @return bytes encoded or zero on error.
|
|
||||||
*/
|
*/
|
||||||
int ucov_notify_encode_apdu(
|
int ucov_notify_encode_apdu(
|
||||||
uint8_t *apdu, unsigned max_apdu_len, BACNET_COV_DATA *data)
|
uint8_t *apdu, unsigned apdu_size, BACNET_COV_DATA *data)
|
||||||
{
|
{
|
||||||
int len = 0; /* length of each encoding */
|
int len = 0; /* length of each encoding */
|
||||||
int apdu_len = BACNET_STATUS_ERROR; /* return value */
|
int apdu_len = 0; /* return value */
|
||||||
|
|
||||||
if (apdu && data && memcopylen(0, max_apdu_len, 2)) {
|
if (apdu && (apdu_size > 2)) {
|
||||||
apdu[0] = PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST;
|
apdu[0] = PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST;
|
||||||
apdu[1] = SERVICE_UNCONFIRMED_COV_NOTIFICATION; /* service choice */
|
apdu[1] = SERVICE_UNCONFIRMED_COV_NOTIFICATION;
|
||||||
apdu_len = 2;
|
|
||||||
len =
|
|
||||||
notify_encode_apdu(&apdu[apdu_len], max_apdu_len - apdu_len, data);
|
|
||||||
if (len <= 0) {
|
|
||||||
/* return the error */
|
|
||||||
apdu_len = len;
|
|
||||||
} else {
|
|
||||||
apdu_len += len;
|
|
||||||
}
|
}
|
||||||
|
len = 2;
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = cov_notify_service_request_encode(
|
||||||
|
apdu, apdu_size - apdu_len, data);
|
||||||
|
if (len > 0) {
|
||||||
|
apdu_len += len;
|
||||||
|
} else {
|
||||||
|
apdu_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return apdu_len;
|
return apdu_len;
|
||||||
@@ -351,39 +353,32 @@ SubscribeCOV-Request ::= SEQUENCE {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encode the COV-service request.
|
* @brief Encode APDU for SubscribeCOV-Request
|
||||||
* Note: COV and Unconfirmed COV are the same.
|
* @note COV and Unconfirmed COV are the same encodings
|
||||||
*
|
* @param apdu Pointer to the buffer, or NULL for length
|
||||||
* @param apdu Pointer to the buffer.
|
* @param data Pointer to the data to encode.
|
||||||
* @param invoke_id Invoke ID
|
* @return number of bytes encoded, or zero on error.
|
||||||
* @param data Pointer to the data to store the decoded values.
|
|
||||||
*
|
|
||||||
* @return Bytes encoded or zero on error.
|
|
||||||
*/
|
*/
|
||||||
int cov_subscribe_encode_apdu(uint8_t *apdu,
|
int cov_subscribe_apdu_encode(uint8_t *apdu, BACNET_SUBSCRIBE_COV_DATA *data)
|
||||||
unsigned max_apdu_len,
|
|
||||||
uint8_t invoke_id,
|
|
||||||
BACNET_SUBSCRIBE_COV_DATA *data)
|
|
||||||
{
|
{
|
||||||
int len = 0; /* length of each encoding */
|
int len = 0; /* length of each encoding */
|
||||||
int apdu_len = 0; /* total length of the apdu, return value */
|
int apdu_len = 0; /* total length of the apdu, return value */
|
||||||
|
|
||||||
(void)max_apdu_len;
|
|
||||||
if (apdu && data) {
|
|
||||||
apdu[0] = PDU_TYPE_CONFIRMED_SERVICE_REQUEST;
|
|
||||||
apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU);
|
|
||||||
apdu[2] = invoke_id;
|
|
||||||
apdu[3] = SERVICE_CONFIRMED_SUBSCRIBE_COV;
|
|
||||||
apdu_len = 4;
|
|
||||||
/* tag 0 - subscriberProcessIdentifier */
|
/* tag 0 - subscriberProcessIdentifier */
|
||||||
len = encode_context_unsigned(
|
len = encode_context_unsigned(apdu, 0, data->subscriberProcessIdentifier);
|
||||||
&apdu[apdu_len], 0, data->subscriberProcessIdentifier);
|
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
|
||||||
/* tag 1 - monitoredObjectIdentifier */
|
/* tag 1 - monitoredObjectIdentifier */
|
||||||
len = encode_context_object_id(&apdu[apdu_len], 1,
|
len =
|
||||||
data->monitoredObjectIdentifier.type,
|
encode_context_object_id(apdu, 1, data->monitoredObjectIdentifier.type,
|
||||||
data->monitoredObjectIdentifier.instance);
|
data->monitoredObjectIdentifier.instance);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
If both the 'Issue Confirmed Notifications' and
|
If both the 'Issue Confirmed Notifications' and
|
||||||
'Lifetime' parameters are absent, then this shall
|
'Lifetime' parameters are absent, then this shall
|
||||||
@@ -391,13 +386,77 @@ int cov_subscribe_encode_apdu(uint8_t *apdu,
|
|||||||
*/
|
*/
|
||||||
if (!data->cancellationRequest) {
|
if (!data->cancellationRequest) {
|
||||||
/* tag 2 - issueConfirmedNotifications */
|
/* tag 2 - issueConfirmedNotifications */
|
||||||
len = encode_context_boolean(
|
len =
|
||||||
&apdu[apdu_len], 2, data->issueConfirmedNotifications);
|
encode_context_boolean(apdu, 2, data->issueConfirmedNotifications);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
/* tag 3 - lifetime */
|
/* tag 3 - lifetime */
|
||||||
len = encode_context_unsigned(&apdu[apdu_len], 3, data->lifetime);
|
len = encode_context_unsigned(apdu, 3, data->lifetime);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return apdu_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Encode the SubscribeCOV service request
|
||||||
|
* @note COV and Unconfirmed COV are the same encodings
|
||||||
|
* @param apdu Pointer to the buffer for encoding into
|
||||||
|
* @param apdu_size number of bytes available in the buffer
|
||||||
|
* @param data Pointer to the service data used for encoding values
|
||||||
|
* @return number of bytes encoded, or zero if unable to encode or too large
|
||||||
|
*/
|
||||||
|
size_t cov_subscribe_service_request_encode(
|
||||||
|
uint8_t *apdu, size_t apdu_size, BACNET_SUBSCRIBE_COV_DATA *data)
|
||||||
|
{
|
||||||
|
size_t apdu_len = 0; /* total length of the apdu, return value */
|
||||||
|
|
||||||
|
apdu_len = cov_subscribe_apdu_encode(NULL, data);
|
||||||
|
if (apdu_len > apdu_size) {
|
||||||
|
apdu_len = 0;
|
||||||
|
} else {
|
||||||
|
apdu_len = cov_subscribe_apdu_encode(apdu, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return apdu_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Encode the COV-service request.
|
||||||
|
* @note COV and Unconfirmed COV are the same encodings
|
||||||
|
* @param apdu Pointer to the buffer.
|
||||||
|
* @param apdu_size number of bytes available in the buffer
|
||||||
|
* @param invoke_id Invoke ID
|
||||||
|
* @param data Pointer to the data to store the decoded values.
|
||||||
|
* @return number of bytes encoded, or zero if unable to encode or too large
|
||||||
|
*/
|
||||||
|
int cov_subscribe_encode_apdu(uint8_t *apdu,
|
||||||
|
unsigned apdu_size,
|
||||||
|
uint8_t invoke_id,
|
||||||
|
BACNET_SUBSCRIBE_COV_DATA *data)
|
||||||
|
{
|
||||||
|
int len = 0; /* length of each encoding */
|
||||||
|
int apdu_len = 0; /* total length of the apdu, return value */
|
||||||
|
|
||||||
|
if (apdu && (apdu_size > 4)) {
|
||||||
|
apdu[0] = PDU_TYPE_CONFIRMED_SERVICE_REQUEST;
|
||||||
|
apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU);
|
||||||
|
apdu[2] = invoke_id;
|
||||||
|
apdu[3] = SERVICE_CONFIRMED_SUBSCRIBE_COV;
|
||||||
|
}
|
||||||
|
len = 4;
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
len =
|
||||||
|
cov_subscribe_service_request_encode(apdu, apdu_size - apdu_len, data);
|
||||||
|
if (len > 0) {
|
||||||
|
apdu_len += len;
|
||||||
|
} else {
|
||||||
|
apdu_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return apdu_len;
|
return apdu_len;
|
||||||
@@ -534,67 +593,141 @@ BACnetPropertyReference ::= SEQUENCE {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encode the properties for subscription into the APDU.
|
* @brief Encode APDU for SubscribeCOVProperty request
|
||||||
*
|
* @param apdu Pointer to the buffer, or NULL for length
|
||||||
|
* @param data Pointer to the data to encode.
|
||||||
|
* @return bytes encoded or zero on error.
|
||||||
|
*/
|
||||||
|
int cov_subscribe_property_apdu_encode(
|
||||||
|
uint8_t *apdu, BACNET_SUBSCRIBE_COV_DATA *data)
|
||||||
|
{
|
||||||
|
int len = 0; /* length of each encoding */
|
||||||
|
int apdu_len = 0; /* total length of the apdu, return value */
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* tag 0 - subscriberProcessIdentifier */
|
||||||
|
len = encode_context_unsigned(apdu, 0, data->subscriberProcessIdentifier);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
/* tag 1 - monitoredObjectIdentifier */
|
||||||
|
len =
|
||||||
|
encode_context_object_id(apdu, 1, data->monitoredObjectIdentifier.type,
|
||||||
|
data->monitoredObjectIdentifier.instance);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
if (!data->cancellationRequest) {
|
||||||
|
/* tag 2 - issueConfirmedNotifications */
|
||||||
|
len =
|
||||||
|
encode_context_boolean(apdu, 2, data->issueConfirmedNotifications);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
/* tag 3 - lifetime */
|
||||||
|
len = encode_context_unsigned(apdu, 3, data->lifetime);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* tag 4 - monitoredPropertyIdentifier */
|
||||||
|
len = encode_opening_tag(apdu, 4);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_context_enumerated(
|
||||||
|
apdu, 0, data->monitoredProperty.propertyIdentifier);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
if (data->monitoredProperty.propertyArrayIndex != BACNET_ARRAY_ALL) {
|
||||||
|
len = encode_context_unsigned(
|
||||||
|
apdu, 1, data->monitoredProperty.propertyArrayIndex);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
len = encode_closing_tag(apdu, 4);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
/* tag 5 - covIncrement */
|
||||||
|
if (data->covIncrementPresent) {
|
||||||
|
len = encode_context_real(apdu, 5, data->covIncrement);
|
||||||
|
apdu_len += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return apdu_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Encode the SubscribeCOVProperty service request
|
||||||
|
* @param apdu Pointer to the buffer for encoding into
|
||||||
|
* @param apdu_size number of bytes available in the buffer
|
||||||
|
* @param data Pointer to the service data used for encoding values
|
||||||
|
* @return number of bytes encoded, or zero if unable to encode or too large
|
||||||
|
*/
|
||||||
|
size_t cov_subscribe_property_service_request_encode(
|
||||||
|
uint8_t *apdu, size_t apdu_size, BACNET_SUBSCRIBE_COV_DATA *data)
|
||||||
|
{
|
||||||
|
size_t apdu_len = 0; /* total length of the apdu, return value */
|
||||||
|
|
||||||
|
apdu_len = cov_subscribe_property_apdu_encode(NULL, data);
|
||||||
|
if (apdu_len > apdu_size) {
|
||||||
|
apdu_len = 0;
|
||||||
|
} else {
|
||||||
|
apdu_len = cov_subscribe_property_apdu_encode(apdu, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return apdu_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Encode SubscribeCOVProperty request
|
||||||
* @param apdu Pointer to the buffer.
|
* @param apdu Pointer to the buffer.
|
||||||
* @param max_apdu_len Buffer size.
|
* @param apdu_size number of bytes available in the buffer
|
||||||
* @param invoke_id Invoke Id.
|
* @param invoke_id Invoke Id.
|
||||||
* @param data Pointer to the data to encode.
|
* @param data Pointer to the data to encode.
|
||||||
*
|
* @return number of bytes encoded, or zero on error.
|
||||||
* @return Bytes decoded or Zero/BACNET_STATUS_ERROR on error.
|
|
||||||
*/
|
*/
|
||||||
int cov_subscribe_property_encode_apdu(uint8_t *apdu,
|
int cov_subscribe_property_encode_apdu(uint8_t *apdu,
|
||||||
unsigned max_apdu_len,
|
unsigned apdu_size,
|
||||||
uint8_t invoke_id,
|
uint8_t invoke_id,
|
||||||
BACNET_SUBSCRIBE_COV_DATA *data)
|
BACNET_SUBSCRIBE_COV_DATA *data)
|
||||||
{
|
{
|
||||||
int len = 0; /* length of each encoding */
|
int len = 0; /* length of each encoding */
|
||||||
int apdu_len = 0; /* total length of the apdu, return value */
|
int apdu_len = 0; /* total length of the apdu, return value */
|
||||||
|
|
||||||
(void)max_apdu_len;
|
if (!data) {
|
||||||
if (apdu && data) {
|
return 0;
|
||||||
|
}
|
||||||
|
if (apdu && (apdu_size > 4)) {
|
||||||
apdu[0] = PDU_TYPE_CONFIRMED_SERVICE_REQUEST;
|
apdu[0] = PDU_TYPE_CONFIRMED_SERVICE_REQUEST;
|
||||||
apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU);
|
apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU);
|
||||||
apdu[2] = invoke_id;
|
apdu[2] = invoke_id;
|
||||||
apdu[3] = SERVICE_CONFIRMED_SUBSCRIBE_COV_PROPERTY;
|
apdu[3] = SERVICE_CONFIRMED_SUBSCRIBE_COV_PROPERTY;
|
||||||
apdu_len = 4;
|
|
||||||
/* tag 0 - subscriberProcessIdentifier */
|
|
||||||
len = encode_context_unsigned(
|
|
||||||
&apdu[apdu_len], 0, data->subscriberProcessIdentifier);
|
|
||||||
apdu_len += len;
|
|
||||||
/* tag 1 - monitoredObjectIdentifier */
|
|
||||||
len = encode_context_object_id(&apdu[apdu_len], 1,
|
|
||||||
data->monitoredObjectIdentifier.type,
|
|
||||||
data->monitoredObjectIdentifier.instance);
|
|
||||||
apdu_len += len;
|
|
||||||
if (!data->cancellationRequest) {
|
|
||||||
/* tag 2 - issueConfirmedNotifications */
|
|
||||||
len = encode_context_boolean(
|
|
||||||
&apdu[apdu_len], 2, data->issueConfirmedNotifications);
|
|
||||||
apdu_len += len;
|
|
||||||
/* tag 3 - lifetime */
|
|
||||||
len = encode_context_unsigned(&apdu[apdu_len], 3, data->lifetime);
|
|
||||||
apdu_len += len;
|
|
||||||
}
|
}
|
||||||
/* tag 4 - monitoredPropertyIdentifier */
|
len = 4;
|
||||||
len = encode_opening_tag(&apdu[apdu_len], 4);
|
|
||||||
apdu_len += len;
|
|
||||||
len = encode_context_enumerated(
|
|
||||||
&apdu[apdu_len], 0, data->monitoredProperty.propertyIdentifier);
|
|
||||||
apdu_len += len;
|
|
||||||
if (data->monitoredProperty.propertyArrayIndex != BACNET_ARRAY_ALL) {
|
|
||||||
len = encode_context_unsigned(
|
|
||||||
&apdu[apdu_len], 1, data->monitoredProperty.propertyArrayIndex);
|
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
}
|
}
|
||||||
len = encode_closing_tag(&apdu[apdu_len], 4);
|
len = cov_subscribe_property_service_request_encode(
|
||||||
|
apdu, apdu_size - apdu_len, data);
|
||||||
|
if (len > 0) {
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
} else {
|
||||||
/* tag 5 - covIncrement */
|
apdu_len = 0;
|
||||||
if (data->covIncrementPresent) {
|
|
||||||
len = encode_context_real(&apdu[apdu_len], 5, data->covIncrement);
|
|
||||||
apdu_len += len;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return apdu_len;
|
return apdu_len;
|
||||||
|
|||||||
+37
-37
@@ -55,8 +55,7 @@ typedef struct BACnet_Subscribe_COV_Data {
|
|||||||
} BACNET_SUBSCRIBE_COV_DATA;
|
} BACNET_SUBSCRIBE_COV_DATA;
|
||||||
|
|
||||||
/* generic callback for COV notifications */
|
/* generic callback for COV notifications */
|
||||||
typedef void (*BACnet_COV_Notification_Callback)
|
typedef void (*BACnet_COV_Notification_Callback)(BACNET_COV_DATA *cov_data);
|
||||||
(BACNET_COV_DATA *cov_data);
|
|
||||||
struct BACnet_COV_Notification;
|
struct BACnet_COV_Notification;
|
||||||
typedef struct BACnet_COV_Notification {
|
typedef struct BACnet_COV_Notification {
|
||||||
struct BACnet_COV_Notification *next;
|
struct BACnet_COV_Notification *next;
|
||||||
@@ -68,37 +67,32 @@ extern "C" {
|
|||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
int cov_notify_encode_apdu(
|
size_t cov_notify_service_request_encode(
|
||||||
uint8_t *apdu, BACNET_COV_DATA *data);
|
uint8_t *apdu, size_t apdu_size, BACNET_COV_DATA *data);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
int cov_notify_encode_apdu(uint8_t *apdu, BACNET_COV_DATA *data);
|
||||||
|
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
int ucov_notify_encode_apdu(
|
int ucov_notify_encode_apdu(
|
||||||
uint8_t * apdu,
|
uint8_t *apdu, unsigned max_apdu_len, BACNET_COV_DATA *data);
|
||||||
unsigned max_apdu_len,
|
|
||||||
BACNET_COV_DATA * data);
|
|
||||||
|
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
int ucov_notify_decode_apdu(
|
int ucov_notify_decode_apdu(
|
||||||
uint8_t * apdu,
|
uint8_t *apdu, unsigned apdu_len, BACNET_COV_DATA *data);
|
||||||
unsigned apdu_len,
|
|
||||||
BACNET_COV_DATA * data);
|
|
||||||
|
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
int ucov_notify_send(
|
int ucov_notify_send(
|
||||||
uint8_t * apdu,
|
uint8_t *apdu, unsigned max_apdu_len, BACNET_COV_DATA *data);
|
||||||
unsigned max_apdu_len,
|
|
||||||
BACNET_COV_DATA * data);
|
|
||||||
|
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
int ccov_notify_encode_apdu(
|
int ccov_notify_encode_apdu(uint8_t *apdu,
|
||||||
uint8_t * apdu,
|
|
||||||
unsigned max_apdu_len,
|
unsigned max_apdu_len,
|
||||||
uint8_t invoke_id,
|
uint8_t invoke_id,
|
||||||
BACNET_COV_DATA *data);
|
BACNET_COV_DATA *data);
|
||||||
|
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
int ccov_notify_decode_apdu(
|
int ccov_notify_decode_apdu(uint8_t *apdu,
|
||||||
uint8_t * apdu,
|
|
||||||
unsigned apdu_len,
|
unsigned apdu_len,
|
||||||
uint8_t *invoke_id,
|
uint8_t *invoke_id,
|
||||||
BACNET_COV_DATA *data);
|
BACNET_COV_DATA *data);
|
||||||
@@ -106,19 +100,22 @@ extern "C" {
|
|||||||
/* common for both confirmed and unconfirmed */
|
/* common for both confirmed and unconfirmed */
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
int cov_notify_decode_service_request(
|
int cov_notify_decode_service_request(
|
||||||
uint8_t * apdu,
|
uint8_t *apdu, unsigned apdu_len, BACNET_COV_DATA *data);
|
||||||
unsigned apdu_len,
|
|
||||||
BACNET_COV_DATA * data);
|
|
||||||
|
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
int cov_subscribe_property_decode_service_request(
|
int cov_subscribe_property_decode_service_request(
|
||||||
uint8_t * apdu,
|
uint8_t *apdu, unsigned apdu_len, BACNET_SUBSCRIBE_COV_DATA *data);
|
||||||
unsigned apdu_len,
|
|
||||||
BACNET_SUBSCRIBE_COV_DATA * data);
|
|
||||||
|
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
int cov_subscribe_property_encode_apdu(
|
int cov_subscribe_property_apdu_encode(
|
||||||
uint8_t * apdu,
|
uint8_t *apdu, BACNET_SUBSCRIBE_COV_DATA *data);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
size_t cov_subscribe_property_service_request_encode(
|
||||||
|
uint8_t *apdu, size_t apdu_size, BACNET_SUBSCRIBE_COV_DATA *data);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
int cov_subscribe_property_encode_apdu(uint8_t *apdu,
|
||||||
unsigned max_apdu_len,
|
unsigned max_apdu_len,
|
||||||
uint8_t invoke_id,
|
uint8_t invoke_id,
|
||||||
BACNET_SUBSCRIBE_COV_DATA *data);
|
BACNET_SUBSCRIBE_COV_DATA *data);
|
||||||
@@ -130,45 +127,48 @@ extern "C" {
|
|||||||
BACNET_SUBSCRIBE_COV_DATA *data);
|
BACNET_SUBSCRIBE_COV_DATA *data);
|
||||||
|
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
int cov_subscribe_encode_apdu(
|
int cov_subscribe_apdu_encode(uint8_t *apdu,
|
||||||
|
BACNET_SUBSCRIBE_COV_DATA *data);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
size_t cov_subscribe_service_request_encode(
|
||||||
uint8_t *apdu,
|
uint8_t *apdu,
|
||||||
|
size_t apdu_size,
|
||||||
|
BACNET_SUBSCRIBE_COV_DATA *data);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
int cov_subscribe_encode_apdu(uint8_t *apdu,
|
||||||
unsigned max_apdu_len,
|
unsigned max_apdu_len,
|
||||||
uint8_t invoke_id,
|
uint8_t invoke_id,
|
||||||
BACNET_SUBSCRIBE_COV_DATA *data);
|
BACNET_SUBSCRIBE_COV_DATA *data);
|
||||||
|
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
void cov_data_value_list_link(
|
void cov_data_value_list_link(
|
||||||
BACNET_COV_DATA *data,
|
BACNET_COV_DATA *data, BACNET_PROPERTY_VALUE *value_list, size_t count);
|
||||||
BACNET_PROPERTY_VALUE *value_list,
|
|
||||||
size_t count);
|
|
||||||
|
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
bool cov_value_list_encode_real(
|
bool cov_value_list_encode_real(BACNET_PROPERTY_VALUE *value_list,
|
||||||
BACNET_PROPERTY_VALUE * value_list,
|
|
||||||
float value,
|
float value,
|
||||||
bool in_alarm,
|
bool in_alarm,
|
||||||
bool fault,
|
bool fault,
|
||||||
bool overridden,
|
bool overridden,
|
||||||
bool out_of_service);
|
bool out_of_service);
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
bool cov_value_list_encode_enumerated(
|
bool cov_value_list_encode_enumerated(BACNET_PROPERTY_VALUE *value_list,
|
||||||
BACNET_PROPERTY_VALUE * value_list,
|
|
||||||
uint32_t value,
|
uint32_t value,
|
||||||
bool in_alarm,
|
bool in_alarm,
|
||||||
bool fault,
|
bool fault,
|
||||||
bool overridden,
|
bool overridden,
|
||||||
bool out_of_service);
|
bool out_of_service);
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
bool cov_value_list_encode_unsigned(
|
bool cov_value_list_encode_unsigned(BACNET_PROPERTY_VALUE *value_list,
|
||||||
BACNET_PROPERTY_VALUE * value_list,
|
|
||||||
uint32_t value,
|
uint32_t value,
|
||||||
bool in_alarm,
|
bool in_alarm,
|
||||||
bool fault,
|
bool fault,
|
||||||
bool overridden,
|
bool overridden,
|
||||||
bool out_of_service);
|
bool out_of_service);
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
bool cov_value_list_encode_character_string(
|
bool cov_value_list_encode_character_string(BACNET_PROPERTY_VALUE *value_list,
|
||||||
BACNET_PROPERTY_VALUE * value_list,
|
|
||||||
BACNET_CHARACTER_STRING *value,
|
BACNET_CHARACTER_STRING *value,
|
||||||
bool in_alarm,
|
bool in_alarm,
|
||||||
bool fault,
|
bool fault,
|
||||||
|
|||||||
@@ -95,6 +95,28 @@ int create_object_encode_service_request(
|
|||||||
return apdu_len;
|
return apdu_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Encode the CreateObject service request
|
||||||
|
* @param apdu Pointer to the buffer for encoding into
|
||||||
|
* @param apdu_size number of bytes available in the buffer
|
||||||
|
* @param data Pointer to the service data used for encoding values
|
||||||
|
* @return number of bytes encoded, or zero if unable to encode or too large
|
||||||
|
*/
|
||||||
|
size_t create_object_service_request_encode(
|
||||||
|
uint8_t *apdu, size_t apdu_size, BACNET_CREATE_OBJECT_DATA *data)
|
||||||
|
{
|
||||||
|
size_t apdu_len = 0; /* total length of the apdu, return value */
|
||||||
|
|
||||||
|
apdu_len = create_object_encode_service_request(NULL, data);
|
||||||
|
if (apdu_len > apdu_size) {
|
||||||
|
apdu_len = 0;
|
||||||
|
} else {
|
||||||
|
apdu_len = create_object_encode_service_request(apdu, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return apdu_len;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Decode the CreateObject service request
|
* @brief Decode the CreateObject service request
|
||||||
*
|
*
|
||||||
@@ -351,7 +373,6 @@ int create_object_error_ack_encode(
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !BACNET_SVC_SERVER
|
|
||||||
/**
|
/**
|
||||||
* @brief Decode a CreateObject-Error ACK APDU
|
* @brief Decode a CreateObject-Error ACK APDU
|
||||||
*
|
*
|
||||||
@@ -420,4 +441,3 @@ int create_object_error_ack_service_decode(
|
|||||||
|
|
||||||
return apdu_len;
|
return apdu_len;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -51,6 +51,9 @@ typedef uint32_t (*create_object_function)(uint32_t object_instance);
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
size_t create_object_service_request_encode(
|
||||||
|
uint8_t *apdu, size_t apdu_size, BACNET_CREATE_OBJECT_DATA *data);
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
int create_object_encode_service_request(
|
int create_object_encode_service_request(
|
||||||
uint8_t *apdu, BACNET_CREATE_OBJECT_DATA *data);
|
uint8_t *apdu, BACNET_CREATE_OBJECT_DATA *data);
|
||||||
|
|||||||
+82
-22
@@ -160,22 +160,91 @@ bool dcc_set_status_duration(
|
|||||||
|
|
||||||
#if BACNET_SVC_DCC_A
|
#if BACNET_SVC_DCC_A
|
||||||
/**
|
/**
|
||||||
* Encode service
|
* @brief Encode DeviceCommunicationControl service
|
||||||
*
|
|
||||||
* @param apdu Pointer to the APDU buffer used for encoding.
|
* @param apdu Pointer to the APDU buffer used for encoding.
|
||||||
* @param invoke_id Invoke-Id
|
|
||||||
* @param timeDuration Optional time duration in minutes.
|
* @param timeDuration Optional time duration in minutes.
|
||||||
* @param enable_disable Enable/disable communication
|
* @param enable_disable Enable/disable communication
|
||||||
* @param password Pointer to an optional password.
|
* @param password Pointer to an optional password.
|
||||||
*
|
*
|
||||||
* @return Bytes encoded or zero on an error.
|
* @return Bytes encoded or zero on an error.
|
||||||
*/
|
*/
|
||||||
int dcc_encode_apdu(uint8_t *apdu,
|
int dcc_apdu_encode(uint8_t *apdu,
|
||||||
uint8_t invoke_id,
|
uint16_t timeDuration,
|
||||||
uint16_t timeDuration, /* 0=optional */
|
|
||||||
BACNET_COMMUNICATION_ENABLE_DISABLE enable_disable,
|
BACNET_COMMUNICATION_ENABLE_DISABLE enable_disable,
|
||||||
BACNET_CHARACTER_STRING *password)
|
BACNET_CHARACTER_STRING *password)
|
||||||
{ /* NULL=optional */
|
{
|
||||||
|
int len = 0; /* length of each encoding */
|
||||||
|
int apdu_len = 0; /* total length of the apdu, return value */
|
||||||
|
|
||||||
|
/* optional timeDuration */
|
||||||
|
if (timeDuration) {
|
||||||
|
len = encode_context_unsigned(apdu, 0, timeDuration);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* enable disable */
|
||||||
|
len = encode_context_enumerated(apdu, 1, enable_disable);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
/* optional password */
|
||||||
|
if (password) {
|
||||||
|
if ((password->length >= 1) && (password->length <= 20)) {
|
||||||
|
len = encode_context_character_string(apdu, 2, password);
|
||||||
|
apdu_len += len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return apdu_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Encode the COVNotification service request
|
||||||
|
* @param apdu Pointer to the buffer for encoding into
|
||||||
|
* @param apdu_size number of bytes available in the buffer
|
||||||
|
* @param timeDuration Optional time duration in minutes.
|
||||||
|
* @param enable_disable Enable/disable communication
|
||||||
|
* @param password Pointer to an optional password.
|
||||||
|
* @return number of bytes encoded, or zero if unable to encode or too large
|
||||||
|
*/
|
||||||
|
size_t dcc_service_request_encode(uint8_t *apdu,
|
||||||
|
size_t apdu_size,
|
||||||
|
uint16_t timeDuration,
|
||||||
|
BACNET_COMMUNICATION_ENABLE_DISABLE enable_disable,
|
||||||
|
BACNET_CHARACTER_STRING *password)
|
||||||
|
{
|
||||||
|
size_t apdu_len = 0; /* total length of the apdu, return value */
|
||||||
|
|
||||||
|
apdu_len = dcc_apdu_encode(NULL, timeDuration, enable_disable, password);
|
||||||
|
if (apdu_len > apdu_size) {
|
||||||
|
apdu_len = 0;
|
||||||
|
} else {
|
||||||
|
apdu_len =
|
||||||
|
dcc_apdu_encode(apdu, timeDuration, enable_disable, password);
|
||||||
|
}
|
||||||
|
|
||||||
|
return apdu_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode service
|
||||||
|
*
|
||||||
|
* @param apdu Pointer to the APDU buffer used for encoding.
|
||||||
|
* @param invoke_id Invoke-Id
|
||||||
|
* @param timeDuration Optional time duration in minutes, 0=optional
|
||||||
|
* @param enable_disable Enable/disable communication
|
||||||
|
* @param password Pointer to an optional password, NULL=optional
|
||||||
|
* @return Bytes encoded or zero on an error.
|
||||||
|
*/
|
||||||
|
int dcc_encode_apdu(uint8_t *apdu,
|
||||||
|
uint8_t invoke_id,
|
||||||
|
uint16_t timeDuration,
|
||||||
|
BACNET_COMMUNICATION_ENABLE_DISABLE enable_disable,
|
||||||
|
BACNET_CHARACTER_STRING *password)
|
||||||
|
{
|
||||||
int len = 0; /* length of each encoding */
|
int len = 0; /* length of each encoding */
|
||||||
int apdu_len = 0; /* total length of the apdu, return value */
|
int apdu_len = 0; /* total length of the apdu, return value */
|
||||||
|
|
||||||
@@ -184,24 +253,15 @@ int dcc_encode_apdu(uint8_t *apdu,
|
|||||||
apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU);
|
apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU);
|
||||||
apdu[2] = invoke_id;
|
apdu[2] = invoke_id;
|
||||||
apdu[3] = SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL;
|
apdu[3] = SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL;
|
||||||
apdu_len = 4;
|
}
|
||||||
/* optional timeDuration */
|
len = 4;
|
||||||
if (timeDuration) {
|
|
||||||
len = encode_context_unsigned(&apdu[apdu_len], 0, timeDuration);
|
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
}
|
}
|
||||||
/* enable disable */
|
len = dcc_apdu_encode(
|
||||||
len = encode_context_enumerated(&apdu[apdu_len], 1, enable_disable);
|
apdu, timeDuration, enable_disable, password);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
/* optional password */
|
|
||||||
if (password) {
|
|
||||||
if ((password->length >= 1) && (password->length <= 20)) {
|
|
||||||
len = encode_context_character_string(
|
|
||||||
&apdu[apdu_len], 2, password);
|
|
||||||
apdu_len += len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return apdu_len;
|
return apdu_len;
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-4
@@ -62,16 +62,25 @@ extern "C" {
|
|||||||
BACNET_COMMUNICATION_ENABLE_DISABLE status,
|
BACNET_COMMUNICATION_ENABLE_DISABLE status,
|
||||||
uint16_t minutes);
|
uint16_t minutes);
|
||||||
|
|
||||||
/* encode service */
|
BACNET_STACK_EXPORT
|
||||||
|
int dcc_apdu_encode(uint8_t *apdu,
|
||||||
|
uint16_t timeDuration,
|
||||||
|
BACNET_COMMUNICATION_ENABLE_DISABLE enable_disable,
|
||||||
|
BACNET_CHARACTER_STRING *password);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
size_t dcc_service_request_encode(uint8_t *apdu,
|
||||||
|
size_t apdu_size,
|
||||||
|
uint16_t timeDuration,
|
||||||
|
BACNET_COMMUNICATION_ENABLE_DISABLE enable_disable,
|
||||||
|
BACNET_CHARACTER_STRING *password);
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
int dcc_encode_apdu(
|
int dcc_encode_apdu(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
uint8_t invoke_id,
|
uint8_t invoke_id,
|
||||||
uint16_t timeDuration, /* 0=optional */
|
uint16_t timeDuration,
|
||||||
BACNET_COMMUNICATION_ENABLE_DISABLE enable_disable,
|
BACNET_COMMUNICATION_ENABLE_DISABLE enable_disable,
|
||||||
BACNET_CHARACTER_STRING * password); /* NULL=optional */
|
BACNET_CHARACTER_STRING * password);
|
||||||
|
|
||||||
/* decode the service request only */
|
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
int dcc_decode_service_request(
|
int dcc_decode_service_request(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
|
|||||||
@@ -44,6 +44,33 @@ int delete_object_encode_service_request(
|
|||||||
return apdu_len;
|
return apdu_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Encode the DeleteObject service request
|
||||||
|
*
|
||||||
|
* DeleteObject-Request ::= SEQUENCE {
|
||||||
|
* object-identifier BACnetObjectIdentifier
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* @param apdu Pointer to the buffer for encoded values
|
||||||
|
* @param apdu_size number of bytes available in the buffer
|
||||||
|
* @param data Pointer to the service data used for encoding values
|
||||||
|
* @return number of bytes encoded, or zero if unable to encode or too large
|
||||||
|
*/
|
||||||
|
int delete_object_service_request_encode(
|
||||||
|
uint8_t *apdu, size_t apdu_size, BACNET_DELETE_OBJECT_DATA *data)
|
||||||
|
{
|
||||||
|
size_t apdu_len = 0; /* total length of the apdu, return value */
|
||||||
|
|
||||||
|
apdu_len = delete_object_encode_service_request(NULL, data);
|
||||||
|
if (apdu_len > apdu_size) {
|
||||||
|
apdu_len = 0;
|
||||||
|
} else {
|
||||||
|
apdu_len = delete_object_encode_service_request(apdu, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return apdu_len;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Decode the DeleteObject service request
|
* @brief Decode the DeleteObject service request
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -45,6 +45,11 @@ extern "C" {
|
|||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
int delete_object_encode_service_request(
|
int delete_object_encode_service_request(
|
||||||
uint8_t *apdu, BACNET_DELETE_OBJECT_DATA *data);
|
uint8_t *apdu, BACNET_DELETE_OBJECT_DATA *data);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
int delete_object_service_request_encode(
|
||||||
|
uint8_t *apdu, size_t apdu_size, BACNET_DELETE_OBJECT_DATA *data);
|
||||||
|
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
int delete_object_decode_service_request(
|
int delete_object_decode_service_request(
|
||||||
uint8_t *apdu, uint32_t apdu_size, BACNET_DELETE_OBJECT_DATA *data);
|
uint8_t *apdu, uint32_t apdu_size, BACNET_DELETE_OBJECT_DATA *data);
|
||||||
|
|||||||
+399
-221
@@ -91,6 +91,12 @@ static int complex_event_type_values_decode(
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Encode the unconfirmed COVNotification service request
|
||||||
|
* @param apdu Pointer to the buffer for encoding into
|
||||||
|
* @param data Pointer to the service data used for encoding values
|
||||||
|
* @return number of bytes encoded, or zero if unable to encode
|
||||||
|
*/
|
||||||
int uevent_notify_encode_apdu(
|
int uevent_notify_encode_apdu(
|
||||||
uint8_t *apdu, BACNET_EVENT_NOTIFICATION_DATA *data)
|
uint8_t *apdu, BACNET_EVENT_NOTIFICATION_DATA *data)
|
||||||
{
|
{
|
||||||
@@ -100,20 +106,29 @@ int uevent_notify_encode_apdu(
|
|||||||
if (apdu) {
|
if (apdu) {
|
||||||
apdu[0] = PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST;
|
apdu[0] = PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST;
|
||||||
apdu[1] = SERVICE_UNCONFIRMED_EVENT_NOTIFICATION; /* service choice */
|
apdu[1] = SERVICE_UNCONFIRMED_EVENT_NOTIFICATION; /* service choice */
|
||||||
apdu_len = 2;
|
}
|
||||||
|
len = 2;
|
||||||
len += event_notify_encode_service_request(&apdu[apdu_len], data);
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = event_notify_encode_service_request(apdu, data);
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
} else {
|
} else {
|
||||||
apdu_len = 0;
|
apdu_len = 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return apdu_len;
|
return apdu_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Encode the confirmed COVNotification service request
|
||||||
|
* @param apdu Pointer to the buffer for encoding into
|
||||||
|
* @param invoke_id ID to invoke for notification
|
||||||
|
* @param data Pointer to the service data used for encoding values
|
||||||
|
* @return number of bytes encoded, or zero if unable to encode
|
||||||
|
*/
|
||||||
int cevent_notify_encode_apdu(
|
int cevent_notify_encode_apdu(
|
||||||
uint8_t *apdu, uint8_t invoke_id, BACNET_EVENT_NOTIFICATION_DATA *data)
|
uint8_t *apdu, uint8_t invoke_id, BACNET_EVENT_NOTIFICATION_DATA *data)
|
||||||
{
|
{
|
||||||
@@ -125,425 +140,558 @@ int cevent_notify_encode_apdu(
|
|||||||
apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU);
|
apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU);
|
||||||
apdu[2] = invoke_id;
|
apdu[2] = invoke_id;
|
||||||
apdu[3] = SERVICE_CONFIRMED_EVENT_NOTIFICATION; /* service choice */
|
apdu[3] = SERVICE_CONFIRMED_EVENT_NOTIFICATION; /* service choice */
|
||||||
apdu_len = 4;
|
}
|
||||||
|
len = 4;
|
||||||
len += event_notify_encode_service_request(&apdu[apdu_len], data);
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = event_notify_encode_service_request(apdu, data);
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
} else {
|
} else {
|
||||||
apdu_len = 0;
|
apdu_len = 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return apdu_len;
|
return apdu_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Encode the COVNotification service request
|
||||||
|
* @param apdu Pointer to the buffer for encoding into
|
||||||
|
* @param data Pointer to the service data used for encoding values
|
||||||
|
* @return number of bytes encoded, or zero if unable to encode
|
||||||
|
*/
|
||||||
int event_notify_encode_service_request(
|
int event_notify_encode_service_request(
|
||||||
uint8_t *apdu, BACNET_EVENT_NOTIFICATION_DATA *data)
|
uint8_t *apdu, BACNET_EVENT_NOTIFICATION_DATA *data)
|
||||||
{
|
{
|
||||||
int len = 0; /* length of each encoding */
|
int len = 0; /* length of each encoding */
|
||||||
int apdu_len = 0; /* total length of the apdu, return value */
|
int apdu_len = 0; /* total length of the apdu, return value */
|
||||||
|
|
||||||
if (apdu) {
|
if (!data) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
/* tag 0 - processIdentifier */
|
/* tag 0 - processIdentifier */
|
||||||
len = encode_context_unsigned(
|
len = encode_context_unsigned(apdu, 0, data->processIdentifier);
|
||||||
&apdu[apdu_len], 0, data->processIdentifier);
|
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
/* tag 1 - initiatingObjectIdentifier */
|
/* tag 1 - initiatingObjectIdentifier */
|
||||||
len = encode_context_object_id(&apdu[apdu_len], 1,
|
len =
|
||||||
data->initiatingObjectIdentifier.type,
|
encode_context_object_id(apdu, 1, data->initiatingObjectIdentifier.type,
|
||||||
data->initiatingObjectIdentifier.instance);
|
data->initiatingObjectIdentifier.instance);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
/* tag 2 - eventObjectIdentifier */
|
/* tag 2 - eventObjectIdentifier */
|
||||||
len = encode_context_object_id(&apdu[apdu_len], 2,
|
len = encode_context_object_id(apdu, 2, data->eventObjectIdentifier.type,
|
||||||
data->eventObjectIdentifier.type,
|
|
||||||
data->eventObjectIdentifier.instance);
|
data->eventObjectIdentifier.instance);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
/* tag 3 - timeStamp */
|
/* tag 3 - timeStamp */
|
||||||
|
len = bacapp_encode_context_timestamp(apdu, 3, &data->timeStamp);
|
||||||
len = bacapp_encode_context_timestamp(
|
|
||||||
&apdu[apdu_len], 3, &data->timeStamp);
|
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
/* tag 4 - noticicationClass */
|
/* tag 4 - noticicationClass */
|
||||||
|
len = encode_context_unsigned(apdu, 4, data->notificationClass);
|
||||||
len = encode_context_unsigned(
|
|
||||||
&apdu[apdu_len], 4, data->notificationClass);
|
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
/* tag 5 - priority */
|
/* tag 5 - priority */
|
||||||
|
len = encode_context_unsigned(apdu, 5, data->priority);
|
||||||
len = encode_context_unsigned(&apdu[apdu_len], 5, data->priority);
|
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
/* tag 6 - eventType */
|
/* tag 6 - eventType */
|
||||||
len = encode_context_enumerated(&apdu[apdu_len], 6, data->eventType);
|
len = encode_context_enumerated(apdu, 6, data->eventType);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
/* tag 7 - messageText */
|
/* tag 7 - messageText */
|
||||||
if (data->messageText) {
|
if (data->messageText) {
|
||||||
len = encode_context_character_string(
|
len = encode_context_character_string(apdu, 7, data->messageText);
|
||||||
&apdu[apdu_len], 7, data->messageText);
|
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* tag 8 - notifyType */
|
/* tag 8 - notifyType */
|
||||||
len = encode_context_enumerated(&apdu[apdu_len], 8, data->notifyType);
|
len = encode_context_enumerated(apdu, 8, data->notifyType);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
switch (data->notifyType) {
|
switch (data->notifyType) {
|
||||||
case NOTIFY_ALARM:
|
case NOTIFY_ALARM:
|
||||||
case NOTIFY_EVENT:
|
case NOTIFY_EVENT:
|
||||||
/* tag 9 - ackRequired */
|
/* tag 9 - ackRequired */
|
||||||
|
len = encode_context_boolean(apdu, 9, data->ackRequired);
|
||||||
len = encode_context_boolean(
|
|
||||||
&apdu[apdu_len], 9, data->ackRequired);
|
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
/* tag 10 - fromState */
|
/* tag 10 - fromState */
|
||||||
len = encode_context_enumerated(
|
len = encode_context_enumerated(apdu, 10, data->fromState);
|
||||||
&apdu[apdu_len], 10, data->fromState);
|
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* tag 11 - toState */
|
/* tag 11 - toState */
|
||||||
len = encode_context_enumerated(&apdu[apdu_len], 11, data->toState);
|
len = encode_context_enumerated(apdu, 11, data->toState);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
switch (data->notifyType) {
|
switch (data->notifyType) {
|
||||||
case NOTIFY_ALARM:
|
case NOTIFY_ALARM:
|
||||||
case NOTIFY_EVENT:
|
case NOTIFY_EVENT:
|
||||||
/* tag 12 - event values */
|
/* tag 12 - event values */
|
||||||
len = encode_opening_tag(&apdu[apdu_len], 12);
|
len = encode_opening_tag(apdu, 12);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
switch (data->eventType) {
|
switch (data->eventType) {
|
||||||
case EVENT_CHANGE_OF_BITSTRING:
|
case EVENT_CHANGE_OF_BITSTRING:
|
||||||
len = encode_opening_tag(&apdu[apdu_len], 0);
|
len = encode_opening_tag(apdu, 0);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_context_bitstring(&apdu[apdu_len], 0,
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_context_bitstring(apdu, 0,
|
||||||
&data->notificationParams.changeOfBitstring
|
&data->notificationParams.changeOfBitstring
|
||||||
.referencedBitString);
|
.referencedBitString);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_context_bitstring(&apdu[apdu_len], 1,
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_context_bitstring(apdu, 1,
|
||||||
&data->notificationParams.changeOfBitstring
|
&data->notificationParams.changeOfBitstring
|
||||||
.statusFlags);
|
.statusFlags);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_closing_tag(&apdu[apdu_len], 0);
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_closing_tag(apdu, 0);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EVENT_CHANGE_OF_STATE:
|
case EVENT_CHANGE_OF_STATE:
|
||||||
len = encode_opening_tag(&apdu[apdu_len], 1);
|
len = encode_opening_tag(apdu, 1);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_opening_tag(&apdu[apdu_len], 0);
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_opening_tag(apdu, 0);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = bacapp_encode_property_state(&apdu[apdu_len],
|
apdu += len;
|
||||||
&data->notificationParams.changeOfState.newState);
|
}
|
||||||
|
len = bacapp_encode_property_state(
|
||||||
|
apdu, &data->notificationParams.changeOfState.newState);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_closing_tag(&apdu[apdu_len], 0);
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_closing_tag(apdu, 0);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_context_bitstring(&apdu[apdu_len], 1,
|
apdu += len;
|
||||||
&data->notificationParams.changeOfState
|
}
|
||||||
.statusFlags);
|
len = encode_context_bitstring(apdu, 1,
|
||||||
|
&data->notificationParams.changeOfState.statusFlags);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_closing_tag(&apdu[apdu_len], 1);
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_closing_tag(apdu, 1);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EVENT_CHANGE_OF_VALUE:
|
case EVENT_CHANGE_OF_VALUE:
|
||||||
len = encode_opening_tag(&apdu[apdu_len], 2);
|
len = encode_opening_tag(apdu, 2);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_opening_tag(&apdu[apdu_len], 0);
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_opening_tag(apdu, 0);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
switch (data->notificationParams.changeOfValue.tag) {
|
switch (data->notificationParams.changeOfValue.tag) {
|
||||||
case CHANGE_OF_VALUE_REAL:
|
case CHANGE_OF_VALUE_REAL:
|
||||||
len = encode_context_real(&apdu[apdu_len], 1,
|
len = encode_context_real(apdu, 1,
|
||||||
data->notificationParams.changeOfValue
|
data->notificationParams.changeOfValue.newValue
|
||||||
.newValue.changeValue);
|
.changeValue);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CHANGE_OF_VALUE_BITS:
|
case CHANGE_OF_VALUE_BITS:
|
||||||
len =
|
len = encode_context_bitstring(apdu, 0,
|
||||||
encode_context_bitstring(&apdu[apdu_len], 0,
|
&data->notificationParams.changeOfValue.newValue
|
||||||
&data->notificationParams.changeOfValue
|
.changedBits);
|
||||||
.newValue.changedBits);
|
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
len = encode_closing_tag(apdu, 0);
|
||||||
len = encode_closing_tag(&apdu[apdu_len], 0);
|
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_context_bitstring(&apdu[apdu_len], 1,
|
apdu += len;
|
||||||
&data->notificationParams.changeOfValue
|
}
|
||||||
.statusFlags);
|
len = encode_context_bitstring(apdu, 1,
|
||||||
|
&data->notificationParams.changeOfValue.statusFlags);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_closing_tag(&apdu[apdu_len], 2);
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_closing_tag(apdu, 2);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EVENT_COMMAND_FAILURE:
|
case EVENT_COMMAND_FAILURE:
|
||||||
|
len = encode_opening_tag(apdu, 3);
|
||||||
len = encode_opening_tag(&apdu[apdu_len], 3);
|
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_opening_tag(&apdu[apdu_len], 0);
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_opening_tag(apdu, 0);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
switch (data->notificationParams.commandFailure.tag) {
|
switch (data->notificationParams.commandFailure.tag) {
|
||||||
case COMMAND_FAILURE_BINARY_PV:
|
case COMMAND_FAILURE_BINARY_PV:
|
||||||
len = encode_application_enumerated(
|
len = encode_application_enumerated(apdu,
|
||||||
&apdu[apdu_len],
|
|
||||||
data->notificationParams.commandFailure
|
data->notificationParams.commandFailure
|
||||||
.commandValue.binaryValue);
|
.commandValue.binaryValue);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COMMAND_FAILURE_UNSIGNED:
|
case COMMAND_FAILURE_UNSIGNED:
|
||||||
len =
|
len = encode_application_unsigned(apdu,
|
||||||
encode_application_unsigned(&apdu[apdu_len],
|
|
||||||
data->notificationParams.commandFailure
|
data->notificationParams.commandFailure
|
||||||
.commandValue.unsignedValue);
|
.commandValue.unsignedValue);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
len = encode_closing_tag(apdu, 0);
|
||||||
len = encode_closing_tag(&apdu[apdu_len], 0);
|
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_context_bitstring(&apdu[apdu_len], 1,
|
apdu += len;
|
||||||
&data->notificationParams.commandFailure
|
}
|
||||||
.statusFlags);
|
len = encode_context_bitstring(apdu, 1,
|
||||||
|
&data->notificationParams.commandFailure.statusFlags);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_opening_tag(&apdu[apdu_len], 2);
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_opening_tag(apdu, 2);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
switch (data->notificationParams.commandFailure.tag) {
|
switch (data->notificationParams.commandFailure.tag) {
|
||||||
case COMMAND_FAILURE_BINARY_PV:
|
case COMMAND_FAILURE_BINARY_PV:
|
||||||
len = encode_application_enumerated(
|
len = encode_application_enumerated(apdu,
|
||||||
&apdu[apdu_len],
|
|
||||||
data->notificationParams.commandFailure
|
data->notificationParams.commandFailure
|
||||||
.feedbackValue.binaryValue);
|
.feedbackValue.binaryValue);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COMMAND_FAILURE_UNSIGNED:
|
case COMMAND_FAILURE_UNSIGNED:
|
||||||
len =
|
len = encode_application_unsigned(apdu,
|
||||||
encode_application_unsigned(&apdu[apdu_len],
|
|
||||||
data->notificationParams.commandFailure
|
data->notificationParams.commandFailure
|
||||||
.feedbackValue.unsignedValue);
|
.feedbackValue.unsignedValue);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
len = encode_closing_tag(apdu, 2);
|
||||||
len = encode_closing_tag(&apdu[apdu_len], 2);
|
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_closing_tag(&apdu[apdu_len], 3);
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_closing_tag(apdu, 3);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EVENT_FLOATING_LIMIT:
|
case EVENT_FLOATING_LIMIT:
|
||||||
len = encode_opening_tag(&apdu[apdu_len], 4);
|
len = encode_opening_tag(apdu, 4);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_context_real(&apdu[apdu_len], 0,
|
apdu += len;
|
||||||
data->notificationParams.floatingLimit
|
}
|
||||||
.referenceValue);
|
len = encode_context_real(apdu, 0,
|
||||||
|
data->notificationParams.floatingLimit.referenceValue);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_context_bitstring(&apdu[apdu_len], 1,
|
apdu += len;
|
||||||
&data->notificationParams.floatingLimit
|
}
|
||||||
.statusFlags);
|
len = encode_context_bitstring(apdu, 1,
|
||||||
|
&data->notificationParams.floatingLimit.statusFlags);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_context_real(&apdu[apdu_len], 2,
|
apdu += len;
|
||||||
data->notificationParams.floatingLimit
|
}
|
||||||
.setPointValue);
|
len = encode_context_real(apdu, 2,
|
||||||
|
data->notificationParams.floatingLimit.setPointValue);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_context_real(&apdu[apdu_len], 3,
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_context_real(apdu, 3,
|
||||||
data->notificationParams.floatingLimit.errorLimit);
|
data->notificationParams.floatingLimit.errorLimit);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_closing_tag(&apdu[apdu_len], 4);
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_closing_tag(apdu, 4);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EVENT_OUT_OF_RANGE:
|
case EVENT_OUT_OF_RANGE:
|
||||||
len = encode_opening_tag(&apdu[apdu_len], 5);
|
len = encode_opening_tag(apdu, 5);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_context_real(&apdu[apdu_len], 0,
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_context_real(apdu, 0,
|
||||||
data->notificationParams.outOfRange.exceedingValue);
|
data->notificationParams.outOfRange.exceedingValue);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_context_bitstring(&apdu[apdu_len], 1,
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_context_bitstring(apdu, 1,
|
||||||
&data->notificationParams.outOfRange.statusFlags);
|
&data->notificationParams.outOfRange.statusFlags);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_context_real(&apdu[apdu_len], 2,
|
apdu += len;
|
||||||
data->notificationParams.outOfRange.deadband);
|
}
|
||||||
|
len = encode_context_real(
|
||||||
|
apdu, 2, data->notificationParams.outOfRange.deadband);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_context_real(&apdu[apdu_len], 3,
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_context_real(apdu, 3,
|
||||||
data->notificationParams.outOfRange.exceededLimit);
|
data->notificationParams.outOfRange.exceededLimit);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_closing_tag(&apdu[apdu_len], 5);
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_closing_tag(apdu, 5);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EVENT_CHANGE_OF_LIFE_SAFETY:
|
case EVENT_CHANGE_OF_LIFE_SAFETY:
|
||||||
len = encode_opening_tag(&apdu[apdu_len], 8);
|
len = encode_opening_tag(apdu, 8);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_context_enumerated(&apdu[apdu_len], 0,
|
apdu += len;
|
||||||
data->notificationParams.changeOfLifeSafety
|
}
|
||||||
.newState);
|
len = encode_context_enumerated(apdu, 0,
|
||||||
|
data->notificationParams.changeOfLifeSafety.newState);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_context_enumerated(&apdu[apdu_len], 1,
|
apdu += len;
|
||||||
data->notificationParams.changeOfLifeSafety
|
}
|
||||||
.newMode);
|
len = encode_context_enumerated(apdu, 1,
|
||||||
|
data->notificationParams.changeOfLifeSafety.newMode);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_context_bitstring(&apdu[apdu_len], 2,
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_context_bitstring(apdu, 2,
|
||||||
&data->notificationParams.changeOfLifeSafety
|
&data->notificationParams.changeOfLifeSafety
|
||||||
.statusFlags);
|
.statusFlags);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_context_enumerated(&apdu[apdu_len], 3,
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_context_enumerated(apdu, 3,
|
||||||
data->notificationParams.changeOfLifeSafety
|
data->notificationParams.changeOfLifeSafety
|
||||||
.operationExpected);
|
.operationExpected);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_closing_tag(&apdu[apdu_len], 8);
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_closing_tag(apdu, 8);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EVENT_BUFFER_READY:
|
case EVENT_BUFFER_READY:
|
||||||
len = encode_opening_tag(&apdu[apdu_len], 10);
|
len = encode_opening_tag(apdu, 10);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = bacapp_encode_context_device_obj_property_ref(
|
apdu += len;
|
||||||
&apdu[apdu_len], 0,
|
}
|
||||||
&data->notificationParams.bufferReady
|
len = bacapp_encode_context_device_obj_property_ref(apdu, 0,
|
||||||
.bufferProperty);
|
&data->notificationParams.bufferReady.bufferProperty);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_context_unsigned(&apdu[apdu_len], 1,
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_context_unsigned(apdu, 1,
|
||||||
data->notificationParams.bufferReady
|
data->notificationParams.bufferReady
|
||||||
.previousNotification);
|
.previousNotification);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_context_unsigned(&apdu[apdu_len], 2,
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_context_unsigned(apdu, 2,
|
||||||
data->notificationParams.bufferReady
|
data->notificationParams.bufferReady
|
||||||
.currentNotification);
|
.currentNotification);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_closing_tag(&apdu[apdu_len], 10);
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_closing_tag(apdu, 10);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case EVENT_UNSIGNED_RANGE:
|
case EVENT_UNSIGNED_RANGE:
|
||||||
len = encode_opening_tag(&apdu[apdu_len], 11);
|
len = encode_opening_tag(apdu, 11);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_context_unsigned(&apdu[apdu_len], 0,
|
apdu += len;
|
||||||
data->notificationParams.unsignedRange
|
}
|
||||||
.exceedingValue);
|
len = encode_context_unsigned(apdu, 0,
|
||||||
|
data->notificationParams.unsignedRange.exceedingValue);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_context_bitstring(&apdu[apdu_len], 1,
|
apdu += len;
|
||||||
&data->notificationParams.unsignedRange
|
}
|
||||||
.statusFlags);
|
len = encode_context_bitstring(apdu, 1,
|
||||||
|
&data->notificationParams.unsignedRange.statusFlags);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_context_unsigned(&apdu[apdu_len], 2,
|
apdu += len;
|
||||||
data->notificationParams.unsignedRange
|
}
|
||||||
.exceededLimit);
|
len = encode_context_unsigned(apdu, 2,
|
||||||
|
data->notificationParams.unsignedRange.exceededLimit);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_closing_tag(&apdu[apdu_len], 11);
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_closing_tag(apdu, 11);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case EVENT_ACCESS_EVENT:
|
case EVENT_ACCESS_EVENT:
|
||||||
len = encode_opening_tag(&apdu[apdu_len], 13);
|
len = encode_opening_tag(apdu, 13);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_context_enumerated(&apdu[apdu_len], 0,
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_context_enumerated(apdu, 0,
|
||||||
data->notificationParams.accessEvent.accessEvent);
|
data->notificationParams.accessEvent.accessEvent);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_context_bitstring(&apdu[apdu_len], 1,
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_context_bitstring(apdu, 1,
|
||||||
&data->notificationParams.accessEvent.statusFlags);
|
&data->notificationParams.accessEvent.statusFlags);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = encode_context_unsigned(&apdu[apdu_len], 2,
|
apdu += len;
|
||||||
data->notificationParams.accessEvent
|
}
|
||||||
.accessEventTag);
|
len = encode_context_unsigned(apdu, 2,
|
||||||
|
data->notificationParams.accessEvent.accessEventTag);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len =
|
apdu += len;
|
||||||
bacapp_encode_context_timestamp(&apdu[apdu_len], 3,
|
}
|
||||||
&data->notificationParams.accessEvent
|
len = bacapp_encode_context_timestamp(apdu, 3,
|
||||||
.accessEventTime);
|
&data->notificationParams.accessEvent.accessEventTime);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
len = bacapp_encode_context_device_obj_ref(
|
apdu += len;
|
||||||
&apdu[apdu_len], 4,
|
}
|
||||||
&data->notificationParams.accessEvent
|
len = bacapp_encode_context_device_obj_ref(apdu, 4,
|
||||||
.accessCredential);
|
&data->notificationParams.accessEvent.accessCredential);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
if (data->notificationParams.accessEvent
|
if (data->notificationParams.accessEvent
|
||||||
.authenticationFactor.format_type <
|
.authenticationFactor.format_type <
|
||||||
AUTHENTICATION_FACTOR_MAX) {
|
AUTHENTICATION_FACTOR_MAX) {
|
||||||
len = bacapp_encode_context_authentication_factor(
|
len =
|
||||||
&apdu[apdu_len], 5,
|
bacapp_encode_context_authentication_factor(apdu, 5,
|
||||||
&data->notificationParams.accessEvent
|
&data->notificationParams.accessEvent
|
||||||
.authenticationFactor);
|
.authenticationFactor);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
len = encode_closing_tag(&apdu[apdu_len], 13);
|
len = encode_closing_tag(apdu, 13);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case EVENT_EXTENDED:
|
case EVENT_EXTENDED:
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
len = encode_closing_tag(&apdu[apdu_len], 12);
|
len = encode_closing_tag(apdu, 12);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
break;
|
break;
|
||||||
case NOTIFY_ACK_NOTIFICATION:
|
case NOTIFY_ACK_NOTIFICATION:
|
||||||
@@ -551,10 +699,40 @@ int event_notify_encode_service_request(
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return apdu_len;
|
return apdu_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Encode the EventNotification service request
|
||||||
|
* @param apdu Pointer to the buffer for encoding into
|
||||||
|
* @param apdu_size number of bytes available in the buffer
|
||||||
|
* @param data Pointer to the service data used for encoding values
|
||||||
|
* @return number of bytes encoded, or zero if unable to encode or too large
|
||||||
|
*/
|
||||||
|
size_t event_notification_service_request_encode(
|
||||||
|
uint8_t *apdu, size_t apdu_size, BACNET_EVENT_NOTIFICATION_DATA *data)
|
||||||
|
{
|
||||||
|
size_t apdu_len = 0; /* total length of the apdu, return value */
|
||||||
|
|
||||||
|
apdu_len = event_notify_encode_service_request(NULL, data);
|
||||||
|
if (apdu_len > apdu_size) {
|
||||||
|
apdu_len = 0;
|
||||||
|
} else {
|
||||||
|
apdu_len = event_notify_encode_service_request(apdu, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return apdu_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Decode the EventNotification service request only.
|
||||||
|
* @param apdu Pointer to the buffer.
|
||||||
|
* @param apdu_len Number of valid bytes in the buffer.
|
||||||
|
* @param data Pointer to the data to store the decoded values, or NULL
|
||||||
|
*
|
||||||
|
* @return Bytes decoded or BACNET_STATUS_ERROR on error.
|
||||||
|
*/
|
||||||
int event_notify_decode_service_request(
|
int event_notify_decode_service_request(
|
||||||
uint8_t *apdu, unsigned apdu_len, BACNET_EVENT_NOTIFICATION_DATA *data)
|
uint8_t *apdu, unsigned apdu_len, BACNET_EVENT_NOTIFICATION_DATA *data)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -227,6 +227,12 @@ extern "C" {
|
|||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
BACNET_EVENT_NOTIFICATION_DATA * data);
|
BACNET_EVENT_NOTIFICATION_DATA * data);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
size_t event_notification_service_request_encode(
|
||||||
|
uint8_t *apdu,
|
||||||
|
size_t apdu_size,
|
||||||
|
BACNET_EVENT_NOTIFICATION_DATA *data);
|
||||||
|
|
||||||
/***************************************************
|
/***************************************************
|
||||||
**
|
**
|
||||||
** Decodes the service data part of Event Notification
|
** Decodes the service data part of Event Notification
|
||||||
|
|||||||
+53
-8
@@ -39,6 +39,52 @@
|
|||||||
|
|
||||||
/** @file getevent.c Encode/Decode GetEvent services */
|
/** @file getevent.c Encode/Decode GetEvent services */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Encode APDU for GetEvent-Request service
|
||||||
|
* @param apdu Pointer to a buffer, or NULL for length
|
||||||
|
* @param lastReceivedObjectIdentifier Object identifier
|
||||||
|
* @return Bytes encoded.
|
||||||
|
*/
|
||||||
|
int getevent_apdu_encode(uint8_t *apdu,
|
||||||
|
BACNET_OBJECT_ID *lastReceivedObjectIdentifier)
|
||||||
|
{
|
||||||
|
int len = 0;
|
||||||
|
int apdu_len = 0;
|
||||||
|
|
||||||
|
/* encode optional parameter */
|
||||||
|
if (lastReceivedObjectIdentifier) {
|
||||||
|
len = encode_context_object_id(apdu, 0,
|
||||||
|
lastReceivedObjectIdentifier->type,
|
||||||
|
lastReceivedObjectIdentifier->instance);
|
||||||
|
apdu_len += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return apdu_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Encode the GetEvent-Request service
|
||||||
|
* @param apdu Pointer to the buffer for encoding into
|
||||||
|
* @param apdu_size number of bytes available in the buffer
|
||||||
|
* @param data Pointer to the service data used for encoding values
|
||||||
|
* @return number of bytes encoded, or zero if unable to encode or too large
|
||||||
|
*/
|
||||||
|
size_t getevent_service_request_encode(
|
||||||
|
uint8_t *apdu, size_t apdu_size,
|
||||||
|
BACNET_OBJECT_ID *data)
|
||||||
|
{
|
||||||
|
size_t apdu_len = 0; /* total length of the apdu, return value */
|
||||||
|
|
||||||
|
apdu_len = getevent_apdu_encode(NULL, data);
|
||||||
|
if (apdu_len > apdu_size) {
|
||||||
|
apdu_len = 0;
|
||||||
|
} else {
|
||||||
|
apdu_len = getevent_apdu_encode(apdu, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return apdu_len;
|
||||||
|
}
|
||||||
|
|
||||||
/** Encode service
|
/** Encode service
|
||||||
*
|
*
|
||||||
* @param apdu APDU buffer to encode to.
|
* @param apdu APDU buffer to encode to.
|
||||||
@@ -49,7 +95,7 @@
|
|||||||
*/
|
*/
|
||||||
int getevent_encode_apdu(uint8_t *apdu,
|
int getevent_encode_apdu(uint8_t *apdu,
|
||||||
uint8_t invoke_id,
|
uint8_t invoke_id,
|
||||||
BACNET_OBJECT_ID *lastReceivedObjectIdentifier)
|
BACNET_OBJECT_ID *data)
|
||||||
{
|
{
|
||||||
int len = 0; /* length of each encoding */
|
int len = 0; /* length of each encoding */
|
||||||
int apdu_len = 0; /* total length of the apdu, return value */
|
int apdu_len = 0; /* total length of the apdu, return value */
|
||||||
@@ -59,15 +105,14 @@ int getevent_encode_apdu(uint8_t *apdu,
|
|||||||
apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU);
|
apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU);
|
||||||
apdu[2] = invoke_id;
|
apdu[2] = invoke_id;
|
||||||
apdu[3] = SERVICE_CONFIRMED_GET_EVENT_INFORMATION;
|
apdu[3] = SERVICE_CONFIRMED_GET_EVENT_INFORMATION;
|
||||||
apdu_len = 4;
|
}
|
||||||
/* encode optional parameter */
|
len = 4;
|
||||||
if (lastReceivedObjectIdentifier) {
|
|
||||||
len = encode_context_object_id(&apdu[apdu_len], 0,
|
|
||||||
lastReceivedObjectIdentifier->type,
|
|
||||||
lastReceivedObjectIdentifier->instance);
|
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
}
|
}
|
||||||
}
|
len = getevent_apdu_encode(apdu, data);
|
||||||
|
apdu_len += len;
|
||||||
|
|
||||||
return apdu_len;
|
return apdu_len;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,6 +62,11 @@ extern "C" {
|
|||||||
uint8_t invoke_id,
|
uint8_t invoke_id,
|
||||||
BACNET_OBJECT_ID * lastReceivedObjectIdentifier);
|
BACNET_OBJECT_ID * lastReceivedObjectIdentifier);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
size_t getevent_service_request_encode(
|
||||||
|
uint8_t *apdu, size_t apdu_size,
|
||||||
|
BACNET_OBJECT_ID *data);
|
||||||
|
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
int getevent_decode_service_request(
|
int getevent_decode_service_request(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
#include "bacnet/list_element.h"
|
#include "bacnet/list_element.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Encode the Add/Remove ListElement service request only
|
* @brief Encode the Add/Remove ListElement service request APDU
|
||||||
*
|
*
|
||||||
* AddListElement-Request ::= SEQUENCE {
|
* AddListElement-Request ::= SEQUENCE {
|
||||||
* object-identifier [0] BACnetObjectIdentifier,
|
* object-identifier [0] BACnetObjectIdentifier,
|
||||||
@@ -85,6 +85,28 @@ int list_element_encode_service_request(
|
|||||||
return apdu_len;
|
return apdu_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Encode the Add/Remove ListElement service request only
|
||||||
|
* @param apdu Pointer to the buffer for encoding into
|
||||||
|
* @param apdu_size number of bytes available in the buffer
|
||||||
|
* @param data Pointer to the service data used for encoding values
|
||||||
|
* @return number of bytes encoded, or zero if unable to encode or too large
|
||||||
|
*/
|
||||||
|
size_t list_element_service_request_encode(
|
||||||
|
uint8_t *apdu, size_t apdu_size, BACNET_LIST_ELEMENT_DATA *data)
|
||||||
|
{
|
||||||
|
size_t apdu_len = 0; /* total length of the apdu, return value */
|
||||||
|
|
||||||
|
apdu_len = list_element_encode_service_request(NULL, data);
|
||||||
|
if (apdu_len > apdu_size) {
|
||||||
|
apdu_len = 0;
|
||||||
|
} else {
|
||||||
|
apdu_len = list_element_encode_service_request(apdu, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return apdu_len;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Decode the Add/Remove ListElement service request only
|
* @brief Decode the Add/Remove ListElement service request only
|
||||||
* @param apdu Pointer to the buffer for decoding.
|
* @param apdu Pointer to the buffer for decoding.
|
||||||
@@ -273,7 +295,6 @@ int list_element_error_ack_encode(
|
|||||||
return apdu_len;
|
return apdu_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !BACNET_SVC_SERVER
|
|
||||||
/**
|
/**
|
||||||
* @brief Decoding for AddListElement or RemoveListElement Error Ack
|
* @brief Decoding for AddListElement or RemoveListElement Error Ack
|
||||||
* AddListElement-Error ::= SEQUENCE {
|
* AddListElement-Error ::= SEQUENCE {
|
||||||
@@ -362,4 +383,3 @@ int list_element_error_ack_decode(
|
|||||||
|
|
||||||
return apdu_len;
|
return apdu_len;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -67,6 +67,9 @@ BACNET_STACK_EXPORT
|
|||||||
int list_element_encode_service_request(
|
int list_element_encode_service_request(
|
||||||
uint8_t *apdu, BACNET_LIST_ELEMENT_DATA *list_element);
|
uint8_t *apdu, BACNET_LIST_ELEMENT_DATA *list_element);
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
|
size_t list_element_service_request_encode(
|
||||||
|
uint8_t *apdu, size_t apdu_size, BACNET_LIST_ELEMENT_DATA *list_element);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
int list_element_decode_service_request(
|
int list_element_decode_service_request(
|
||||||
uint8_t *apdu, unsigned apdu_len, BACNET_LIST_ELEMENT_DATA *list_element);
|
uint8_t *apdu, unsigned apdu_len, BACNET_LIST_ELEMENT_DATA *list_element);
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
|
|||||||
+82
-21
@@ -38,37 +38,98 @@
|
|||||||
|
|
||||||
/** @file lso.c BACnet Life Safety Operation encode/decode */
|
/** @file lso.c BACnet Life Safety Operation encode/decode */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Encode APDU for LifeSafetyOperation-Request
|
||||||
|
* @param apdu Pointer to the buffer, or NULL for length
|
||||||
|
* @param data Pointer to the data to encode.
|
||||||
|
* @return number of bytes encoded, or zero on error.
|
||||||
|
*/
|
||||||
|
int life_safety_operation_encode(uint8_t *apdu, BACNET_LSO_DATA *data)
|
||||||
|
{
|
||||||
|
int len = 0; /* length of each encoding */
|
||||||
|
int apdu_len = 0; /* total length of the apdu, return value */
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* tag 0 - requestingProcessId */
|
||||||
|
len = encode_context_unsigned(apdu, 0, data->processId);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
/* tag 1 - requestingSource */
|
||||||
|
len = encode_context_character_string(
|
||||||
|
apdu, 1, &data->requestingSrc);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
/* Operation */
|
||||||
|
len = encode_context_enumerated(apdu, 2, data->operation);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
/* Object ID */
|
||||||
|
if (data->use_target) {
|
||||||
|
len = encode_context_object_id(apdu, 3,
|
||||||
|
data->targetObject.type, data->targetObject.instance);
|
||||||
|
apdu_len += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return apdu_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Encode APDU for LifeSafetyOperation-Request
|
||||||
|
* @param apdu Pointer to the buffer, or NULL for length
|
||||||
|
* @param data Pointer to the data to encode.
|
||||||
|
* @return number of bytes encoded, or zero on error.
|
||||||
|
*/
|
||||||
int lso_encode_apdu(uint8_t *apdu, uint8_t invoke_id, BACNET_LSO_DATA *data)
|
int lso_encode_apdu(uint8_t *apdu, uint8_t invoke_id, BACNET_LSO_DATA *data)
|
||||||
{
|
{
|
||||||
int len = 0; /* length of each encoding */
|
int len = 0; /* length of each encoding */
|
||||||
int apdu_len = 0; /* total length of the apdu, return value */
|
int apdu_len = 0; /* total length of the apdu, return value */
|
||||||
|
|
||||||
if (apdu && data) {
|
if (apdu) {
|
||||||
apdu[0] = PDU_TYPE_CONFIRMED_SERVICE_REQUEST;
|
apdu[0] = PDU_TYPE_CONFIRMED_SERVICE_REQUEST;
|
||||||
apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU);
|
apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU);
|
||||||
apdu[2] = invoke_id;
|
apdu[2] = invoke_id;
|
||||||
apdu[3] = SERVICE_CONFIRMED_LIFE_SAFETY_OPERATION;
|
apdu[3] = SERVICE_CONFIRMED_LIFE_SAFETY_OPERATION;
|
||||||
apdu_len = 4;
|
|
||||||
/* tag 0 - requestingProcessId */
|
|
||||||
len = encode_context_unsigned(&apdu[apdu_len], 0, data->processId);
|
|
||||||
apdu_len += len;
|
|
||||||
/* tag 1 - requestingSource */
|
|
||||||
len = encode_context_character_string(
|
|
||||||
&apdu[apdu_len], 1, &data->requestingSrc);
|
|
||||||
apdu_len += len;
|
|
||||||
/*
|
|
||||||
Operation
|
|
||||||
*/
|
|
||||||
len = encode_context_enumerated(&apdu[apdu_len], 2, data->operation);
|
|
||||||
apdu_len += len;
|
|
||||||
/*
|
|
||||||
Object ID
|
|
||||||
*/
|
|
||||||
if (data->use_target) {
|
|
||||||
len = encode_context_object_id(&apdu[apdu_len], 3,
|
|
||||||
data->targetObject.type, data->targetObject.instance);
|
|
||||||
apdu_len += len;
|
|
||||||
}
|
}
|
||||||
|
len = 4;
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = life_safety_operation_encode(apdu, data);
|
||||||
|
if (len > 0) {
|
||||||
|
apdu_len += len;
|
||||||
|
} else {
|
||||||
|
apdu_len = len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return apdu_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Encode the LifeSafetyOperation-Request
|
||||||
|
* @param apdu Pointer to the buffer for encoding into
|
||||||
|
* @param apdu_size number of bytes available in the buffer
|
||||||
|
* @param data Pointer to the service data used for encoding values
|
||||||
|
* @return number of bytes encoded, or zero if unable to encode or too large
|
||||||
|
*/
|
||||||
|
size_t life_safety_operation_request_encode(
|
||||||
|
uint8_t *apdu, size_t apdu_size, BACNET_LSO_DATA *data)
|
||||||
|
{
|
||||||
|
size_t apdu_len = 0;
|
||||||
|
|
||||||
|
apdu_len = life_safety_operation_encode(NULL, data);
|
||||||
|
if (apdu_len > apdu_size) {
|
||||||
|
apdu_len = 0;
|
||||||
|
} else {
|
||||||
|
apdu_len = life_safety_operation_encode(apdu, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
return apdu_len;
|
return apdu_len;
|
||||||
|
|||||||
+15
-7
@@ -31,12 +31,6 @@
|
|||||||
#include "bacnet/bacdef.h"
|
#include "bacnet/bacdef.h"
|
||||||
#include "bacnet/bacstr.h"
|
#include "bacnet/bacstr.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
/* Life Safety Operation Service */
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t processId;
|
uint32_t processId;
|
||||||
BACNET_CHARACTER_STRING requestingSrc;
|
BACNET_CHARACTER_STRING requestingSrc;
|
||||||
@@ -45,13 +39,27 @@ extern "C" {
|
|||||||
bool use_target:1;
|
bool use_target:1;
|
||||||
} BACNET_LSO_DATA;
|
} BACNET_LSO_DATA;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
int lso_encode_apdu(
|
int lso_encode_apdu(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
uint8_t invoke_id,
|
uint8_t invoke_id,
|
||||||
BACNET_LSO_DATA * data);
|
BACNET_LSO_DATA * data);
|
||||||
/* decode the service request only */
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
int life_safety_operation_encode(
|
||||||
|
uint8_t *apdu,
|
||||||
|
BACNET_LSO_DATA *data);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
size_t life_safety_operation_request_encode(
|
||||||
|
uint8_t *apdu,
|
||||||
|
size_t apdu_size,
|
||||||
|
BACNET_LSO_DATA *data);
|
||||||
|
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
int lso_decode_service_request(
|
int lso_decode_service_request(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
|
|||||||
+58
-15
@@ -40,9 +40,8 @@
|
|||||||
|
|
||||||
/** @file rd.c Encode/Decode Reinitialize Device APDUs */
|
/** @file rd.c Encode/Decode Reinitialize Device APDUs */
|
||||||
#if BACNET_SVC_RD_A
|
#if BACNET_SVC_RD_A
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Encode Reinitialize Device service
|
* @brief Encode ReinitializeDevice-Request APDU
|
||||||
*
|
*
|
||||||
* ReinitializeDevice-Request ::= SEQUENCE {
|
* ReinitializeDevice-Request ::= SEQUENCE {
|
||||||
* reinitialized-state-of-device [0] ENUMERATED {
|
* reinitialized-state-of-device [0] ENUMERATED {
|
||||||
@@ -58,6 +57,62 @@
|
|||||||
* password [1] CharacterString (SIZE (1..20)) OPTIONAL
|
* password [1] CharacterString (SIZE (1..20)) OPTIONAL
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
|
* @param apdu Pointer to the buffer, or NULL for length
|
||||||
|
* @param state Reinitialization state
|
||||||
|
* @param password Pointer to the pass phrase.
|
||||||
|
* @return number of bytes encoded
|
||||||
|
*/
|
||||||
|
int reinitialize_device_encode(uint8_t *apdu,
|
||||||
|
BACNET_REINITIALIZED_STATE state,
|
||||||
|
BACNET_CHARACTER_STRING *password)
|
||||||
|
{
|
||||||
|
int len = 0; /* length of each encoding */
|
||||||
|
int apdu_len = 0; /* total length of the apdu, return value */
|
||||||
|
|
||||||
|
/* reinitialized-state-of-device [0] ENUMERATED */
|
||||||
|
len = encode_context_enumerated(apdu, 0, state);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
/* password [1] CharacterString (SIZE (1..20)) OPTIONAL */
|
||||||
|
if (password) {
|
||||||
|
if ((password->length >= 1) && (password->length <= 20)) {
|
||||||
|
len = encode_context_character_string(apdu, 1, password);
|
||||||
|
apdu_len += len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return apdu_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Encode the COVNotification service request
|
||||||
|
* @param apdu Pointer to the buffer for encoding into
|
||||||
|
* @param apdu_size number of bytes available in the buffer
|
||||||
|
* @param state Reinitialization state
|
||||||
|
* @param password Pointer to the pass phrase.
|
||||||
|
* @return number of bytes encoded, or zero if unable to encode or too large
|
||||||
|
*/
|
||||||
|
size_t reinitialize_device_request_encode(uint8_t *apdu,
|
||||||
|
size_t apdu_size,
|
||||||
|
BACNET_REINITIALIZED_STATE state,
|
||||||
|
BACNET_CHARACTER_STRING *password)
|
||||||
|
{
|
||||||
|
size_t apdu_len = 0; /* total length of the apdu, return value */
|
||||||
|
|
||||||
|
apdu_len = reinitialize_device_encode(NULL, state, password);
|
||||||
|
if (apdu_len > apdu_size) {
|
||||||
|
apdu_len = 0;
|
||||||
|
} else {
|
||||||
|
apdu_len = reinitialize_device_encode(apdu, state, password);
|
||||||
|
}
|
||||||
|
|
||||||
|
return apdu_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Encode Reinitialize Device service
|
||||||
* @param apdu Pointer to the APDU buffer.
|
* @param apdu Pointer to the APDU buffer.
|
||||||
* @param invoke_id Invoke-Id
|
* @param invoke_id Invoke-Id
|
||||||
* @param state Reinitialization state
|
* @param state Reinitialization state
|
||||||
@@ -84,20 +139,8 @@ int rd_encode_apdu(uint8_t *apdu,
|
|||||||
if (apdu) {
|
if (apdu) {
|
||||||
apdu += len;
|
apdu += len;
|
||||||
}
|
}
|
||||||
len = encode_context_enumerated(apdu, 0, state);
|
len = reinitialize_device_encode(apdu, state, password);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
if (apdu) {
|
|
||||||
apdu += len;
|
|
||||||
}
|
|
||||||
/* optional password */
|
|
||||||
if (password) {
|
|
||||||
/* Must be at least 1 character, limited to 20 characters */
|
|
||||||
if ((password->length >= 1) && (password->length <= 20)) {
|
|
||||||
len = encode_context_character_string(
|
|
||||||
apdu, 1, password);
|
|
||||||
apdu_len += len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return apdu_len;
|
return apdu_len;
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-1
@@ -45,7 +45,6 @@ typedef bool(
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
/* encode service */
|
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
int rd_encode_apdu(
|
int rd_encode_apdu(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
@@ -53,6 +52,17 @@ extern "C" {
|
|||||||
BACNET_REINITIALIZED_STATE state,
|
BACNET_REINITIALIZED_STATE state,
|
||||||
BACNET_CHARACTER_STRING * password);
|
BACNET_CHARACTER_STRING * password);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
int reinitialize_device_encode(uint8_t *apdu,
|
||||||
|
BACNET_REINITIALIZED_STATE state,
|
||||||
|
BACNET_CHARACTER_STRING *password);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
size_t reinitialize_device_request_encode(
|
||||||
|
uint8_t *apdu, size_t apdu_size,
|
||||||
|
BACNET_REINITIALIZED_STATE state,
|
||||||
|
BACNET_CHARACTER_STRING *password);
|
||||||
|
|
||||||
/* decode the service request only */
|
/* decode the service request only */
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
int rd_decode_service_request(
|
int rd_decode_service_request(
|
||||||
|
|||||||
+167
-76
@@ -44,7 +44,9 @@
|
|||||||
* objectIdentifier [0] BACnetObjectIdentifier,
|
* objectIdentifier [0] BACnetObjectIdentifier,
|
||||||
* propertyIdentifier [1] BACnetPropertyIdentifier,
|
* propertyIdentifier [1] BACnetPropertyIdentifier,
|
||||||
* propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array
|
* propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array
|
||||||
* datatype range CHOICE { byPosition [3] SEQUENCE { referenceIndex Unsigned,
|
* datatype range CHOICE {
|
||||||
|
* byPosition [3] SEQUENCE {
|
||||||
|
* referenceIndex Unsigned,
|
||||||
* count INTEGER
|
* count INTEGER
|
||||||
* },
|
* },
|
||||||
* -- context tag 4 is deprecated
|
* -- context tag 4 is deprecated
|
||||||
@@ -61,6 +63,139 @@
|
|||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Encode ReadRange-Request APDU
|
||||||
|
* @param apdu Pointer to the buffer, or NULL for length
|
||||||
|
* @param data Pointer to the data to encode.
|
||||||
|
* @return number of bytes encoded, or zero on error.
|
||||||
|
*/
|
||||||
|
int read_range_encode(uint8_t *apdu, BACNET_READ_RANGE_DATA *data)
|
||||||
|
{
|
||||||
|
int len = 0; /* length of each encoding */
|
||||||
|
int apdu_len = 0; /* total length of the apdu, return value */
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* objectIdentifier [0] BACnetObjectIdentifier */
|
||||||
|
len = encode_context_object_id(
|
||||||
|
apdu, 0, data->object_type, data->object_instance);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
/* propertyIdentifier [1] BACnetPropertyIdentifier */
|
||||||
|
len = encode_context_enumerated(apdu, 1, data->object_property);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
/* propertyArrayIndex [2] Unsigned OPTIONAL */
|
||||||
|
if (data->array_index != BACNET_ARRAY_ALL) {
|
||||||
|
len = encode_context_unsigned(apdu, 2, data->array_index);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (data->RequestType) {
|
||||||
|
case RR_BY_POSITION:
|
||||||
|
/* byPosition [3] SEQUENCE */
|
||||||
|
len = encode_opening_tag(apdu, 3);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_application_unsigned(apdu, data->Range.RefIndex);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_application_signed(apdu, data->Count);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_closing_tag(apdu, 3);
|
||||||
|
apdu_len += len;
|
||||||
|
break;
|
||||||
|
case RR_BY_SEQUENCE:
|
||||||
|
/* bySequenceNumber [6] SEQUENCE */
|
||||||
|
len = encode_opening_tag(apdu, 6);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_application_unsigned(apdu, data->Range.RefSeqNum);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_application_signed(apdu, data->Count);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_closing_tag(apdu, 6);
|
||||||
|
apdu_len += len;
|
||||||
|
break;
|
||||||
|
case RR_BY_TIME:
|
||||||
|
/* byTime [7] SEQUENCE */
|
||||||
|
len = encode_opening_tag(apdu, 7);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_application_date(apdu, &data->Range.RefTime.date);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_application_time(apdu, &data->Range.RefTime.time);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_application_signed(apdu, data->Count);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_closing_tag(apdu, 7);
|
||||||
|
apdu_len += len;
|
||||||
|
break;
|
||||||
|
case RR_READ_ALL:
|
||||||
|
/* read the whole list - omit the range parameter */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return apdu_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Encode ReadRange-Request service APDU
|
||||||
|
* @param apdu Pointer to the buffer for encoding into
|
||||||
|
* @param apdu_size number of bytes available in the buffer
|
||||||
|
* @param data Pointer to the service data used for encoding values
|
||||||
|
* @return number of bytes encoded, or zero if unable to encode or too large
|
||||||
|
*/
|
||||||
|
size_t read_range_request_encode(
|
||||||
|
uint8_t *apdu, size_t apdu_size, BACNET_READ_RANGE_DATA *data)
|
||||||
|
{
|
||||||
|
size_t apdu_len = 0; /* total length of the apdu, return value */
|
||||||
|
|
||||||
|
apdu_len = read_range_encode(NULL, data);
|
||||||
|
if (apdu_len > apdu_size) {
|
||||||
|
apdu_len = 0;
|
||||||
|
} else {
|
||||||
|
apdu_len = read_range_encode(apdu, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return apdu_len;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build a ReadRange request packet.
|
* Build a ReadRange request packet.
|
||||||
*
|
*
|
||||||
@@ -71,8 +206,9 @@
|
|||||||
* @return Bytes encoded.
|
* @return Bytes encoded.
|
||||||
*/
|
*/
|
||||||
int rr_encode_apdu(
|
int rr_encode_apdu(
|
||||||
uint8_t *apdu, uint8_t invoke_id, BACNET_READ_RANGE_DATA *rrdata)
|
uint8_t *apdu, uint8_t invoke_id, BACNET_READ_RANGE_DATA *data)
|
||||||
{
|
{
|
||||||
|
int len = 0; /* length of each encoding */
|
||||||
int apdu_len = 0; /* total length of the apdu, return value */
|
int apdu_len = 0; /* total length of the apdu, return value */
|
||||||
|
|
||||||
if (apdu) {
|
if (apdu) {
|
||||||
@@ -80,61 +216,14 @@ int rr_encode_apdu(
|
|||||||
apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU);
|
apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU);
|
||||||
apdu[2] = invoke_id;
|
apdu[2] = invoke_id;
|
||||||
apdu[3] = SERVICE_CONFIRMED_READ_RANGE; /* service choice */
|
apdu[3] = SERVICE_CONFIRMED_READ_RANGE; /* service choice */
|
||||||
apdu_len = 4;
|
|
||||||
|
|
||||||
apdu_len += encode_context_object_id(
|
|
||||||
&apdu[apdu_len], 0, rrdata->object_type, rrdata->object_instance);
|
|
||||||
apdu_len += encode_context_enumerated(
|
|
||||||
&apdu[apdu_len], 1, rrdata->object_property);
|
|
||||||
|
|
||||||
/* optional array index */
|
|
||||||
|
|
||||||
if (rrdata->array_index != BACNET_ARRAY_ALL) {
|
|
||||||
apdu_len += encode_context_unsigned(
|
|
||||||
&apdu[apdu_len], 2, rrdata->array_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Build the appropriate (optional) range parameter based on the request
|
|
||||||
* type */
|
|
||||||
|
|
||||||
switch (rrdata->RequestType) {
|
|
||||||
case RR_BY_POSITION:
|
|
||||||
apdu_len += encode_opening_tag(&apdu[apdu_len], 3);
|
|
||||||
apdu_len += encode_application_unsigned(
|
|
||||||
&apdu[apdu_len], rrdata->Range.RefIndex);
|
|
||||||
apdu_len +=
|
|
||||||
encode_application_signed(&apdu[apdu_len], rrdata->Count);
|
|
||||||
apdu_len += encode_closing_tag(&apdu[apdu_len], 3);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RR_BY_SEQUENCE:
|
|
||||||
apdu_len += encode_opening_tag(&apdu[apdu_len], 6);
|
|
||||||
apdu_len += encode_application_unsigned(
|
|
||||||
&apdu[apdu_len], rrdata->Range.RefSeqNum);
|
|
||||||
apdu_len +=
|
|
||||||
encode_application_signed(&apdu[apdu_len], rrdata->Count);
|
|
||||||
apdu_len += encode_closing_tag(&apdu[apdu_len], 6);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RR_BY_TIME:
|
|
||||||
apdu_len += encode_opening_tag(&apdu[apdu_len], 7);
|
|
||||||
apdu_len += encode_application_date(
|
|
||||||
&apdu[apdu_len], &rrdata->Range.RefTime.date);
|
|
||||||
apdu_len += encode_application_time(
|
|
||||||
&apdu[apdu_len], &rrdata->Range.RefTime.time);
|
|
||||||
apdu_len +=
|
|
||||||
encode_application_signed(&apdu[apdu_len], rrdata->Count);
|
|
||||||
apdu_len += encode_closing_tag(&apdu[apdu_len], 7);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RR_READ_ALL: /* to attempt a read of the whole array or list,
|
|
||||||
omit the range parameter */
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
len = 4;
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
}
|
}
|
||||||
|
len = read_range_encode(apdu, data);
|
||||||
|
apdu_len += len;
|
||||||
|
|
||||||
return apdu_len;
|
return apdu_len;
|
||||||
}
|
}
|
||||||
@@ -200,12 +289,13 @@ int rr_decode_service_request(
|
|||||||
explicit checking later */
|
explicit checking later */
|
||||||
if (len < apdu_len) {
|
if (len < apdu_len) {
|
||||||
/*
|
/*
|
||||||
* Note: We pick up the opening tag and then decode the parameter
|
* Note: We pick up the opening tag and then decode the
|
||||||
* types we recognise. We deal with the count and the closing tag in
|
* parameter types we recognise. We deal with the count and the
|
||||||
* each case statement even though it might appear that we could do
|
* closing tag in each case statement even though it might
|
||||||
* them after the switch statement as common elements. This is so
|
* appear that we could do them after the switch statement as
|
||||||
* that if we receive a tag we don't recognise, we don't try to
|
* common elements. This is so that if we receive a tag we don't
|
||||||
* decode it blindly and make a mess of it.
|
* recognise, we don't try to decode it blindly and make a mess
|
||||||
|
* of it.
|
||||||
*/
|
*/
|
||||||
len += decode_tag_number_and_value(
|
len += decode_tag_number_and_value(
|
||||||
&apdu[len], &tag_number, &len_value_type);
|
&apdu[len], &tag_number, &len_value_type);
|
||||||
@@ -313,7 +403,8 @@ int rr_decode_service_request(
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default: /* If we don't recognise the tag then we do nothing
|
default: /* If we don't recognise the tag then we do nothing
|
||||||
* here and try to return all elements of the array */
|
* here and try to return all elements of the array
|
||||||
|
*/
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -331,10 +422,10 @@ int rr_decode_service_request(
|
|||||||
* propertyArrayIndex [2] Unsigned OPTIONAL , -- used only with
|
* propertyArrayIndex [2] Unsigned OPTIONAL , -- used only with
|
||||||
* array datatype resultFlags [3] BACnetResultFlags, itemCount [4]
|
* array datatype resultFlags [3] BACnetResultFlags, itemCount [4]
|
||||||
* Unsigned, itemData [5] SEQUENCE OF ABSTRACT-SYNTAX.&TYPE,
|
* Unsigned, itemData [5] SEQUENCE OF ABSTRACT-SYNTAX.&TYPE,
|
||||||
* firstSequenceNumber [6] Unsigned32 OPTIONAL -- used only if 'Item Count'
|
* firstSequenceNumber [6] Unsigned32 OPTIONAL -- used only if 'Item
|
||||||
* > 0 and the request was either of
|
* Count' > 0 and the request was either of
|
||||||
* -- type 'By Sequence Number'
|
* -- type 'By Sequence
|
||||||
* or 'By Time'
|
* Number' or 'By Time'
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -343,7 +434,8 @@ int rr_decode_service_request(
|
|||||||
*
|
*
|
||||||
* @param apdu Pointer to the buffer.
|
* @param apdu Pointer to the buffer.
|
||||||
* @param invoke_id ID invoked.
|
* @param invoke_id ID invoked.
|
||||||
* @param rrdata Pointer to the read range data structure used for encoding.
|
* @param rrdata Pointer to the read range data structure used for
|
||||||
|
* encoding.
|
||||||
*
|
*
|
||||||
* @return The count of encoded bytes.
|
* @return The count of encoded bytes.
|
||||||
*/
|
*/
|
||||||
@@ -375,9 +467,9 @@ int rr_ack_encode_apdu(
|
|||||||
/* Context 4 Item Count */
|
/* Context 4 Item Count */
|
||||||
apdu_len +=
|
apdu_len +=
|
||||||
encode_context_unsigned(&apdu[apdu_len], 4, rrdata->ItemCount);
|
encode_context_unsigned(&apdu[apdu_len], 4, rrdata->ItemCount);
|
||||||
/* Context 5 Property list - reading the standard it looks like an empty
|
/* Context 5 Property list - reading the standard it looks like an
|
||||||
* list still requires an opening and closing tag as the tagged
|
* empty list still requires an opening and closing tag as the
|
||||||
* parameter is not optional
|
* tagged parameter is not optional
|
||||||
*/
|
*/
|
||||||
apdu_len += encode_opening_tag(&apdu[apdu_len], 5);
|
apdu_len += encode_opening_tag(&apdu[apdu_len], 5);
|
||||||
if (rrdata->ItemCount != 0) {
|
if (rrdata->ItemCount != 0) {
|
||||||
@@ -498,9 +590,9 @@ int rr_ack_decode_service_request(uint8_t *apdu,
|
|||||||
}
|
}
|
||||||
if (decode_is_opening_tag_number(&apdu[len], 5)) {
|
if (decode_is_opening_tag_number(&apdu[len], 5)) {
|
||||||
len++; /* A tag number of 5 is not extended so only one octet
|
len++; /* A tag number of 5 is not extended so only one octet
|
||||||
* Setup the start position and length of the data returned
|
* Setup the start position and length of the data
|
||||||
* from the request don't decode the application tag number
|
* returned from the request don't decode the application
|
||||||
* or its data here. */
|
* tag number or its data here. */
|
||||||
rrdata->application_data = &apdu[len];
|
rrdata->application_data = &apdu[len];
|
||||||
start_len = len;
|
start_len = len;
|
||||||
while (len < apdu_len) {
|
while (len < apdu_len) {
|
||||||
@@ -510,7 +602,8 @@ int rr_ack_decode_service_request(uint8_t *apdu,
|
|||||||
len++; /* Step over single byte closing tag */
|
len++; /* Step over single byte closing tag */
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
/* Don't care about tag number, just skipping over anyway */
|
/* Don't care about tag number, just skipping over
|
||||||
|
* anyway */
|
||||||
len += decode_tag_number_and_value(
|
len += decode_tag_number_and_value(
|
||||||
&apdu[len], NULL, &len_value_type);
|
&apdu[len], NULL, &len_value_type);
|
||||||
len += len_value_type; /* Skip over data value as well */
|
len += len_value_type; /* Skip over data value as well */
|
||||||
@@ -540,5 +633,3 @@ int rr_ack_decode_service_request(uint8_t *apdu,
|
|||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: Currently does not have test framework */
|
|
||||||
|
|||||||
@@ -138,6 +138,16 @@ extern "C" {
|
|||||||
uint8_t invoke_id,
|
uint8_t invoke_id,
|
||||||
BACNET_READ_RANGE_DATA * rrdata);
|
BACNET_READ_RANGE_DATA * rrdata);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
int read_range_encode(
|
||||||
|
uint8_t *apdu,
|
||||||
|
BACNET_READ_RANGE_DATA *data);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
size_t read_range_request_encode(
|
||||||
|
uint8_t *apdu,
|
||||||
|
size_t apdu_size,
|
||||||
|
BACNET_READ_RANGE_DATA *data);
|
||||||
|
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
int rr_decode_service_request(
|
int rr_decode_service_request(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
|
|||||||
+195
-39
@@ -40,6 +40,76 @@
|
|||||||
/** @file rp.c Encode/Decode Read Property and RP ACKs */
|
/** @file rp.c Encode/Decode Read Property and RP ACKs */
|
||||||
|
|
||||||
#if BACNET_SVC_RP_A
|
#if BACNET_SVC_RP_A
|
||||||
|
/**
|
||||||
|
* @brief Encode APDU for ReadProperty-Request
|
||||||
|
*
|
||||||
|
* ReadProperty-Request ::= SEQUENCE {
|
||||||
|
* object-identifier [0] BACnetObjectIdentifier,
|
||||||
|
* property-identifier [1] BACnetPropertyIdentifier,
|
||||||
|
* property-array-index [2] Unsigned OPTIONAL
|
||||||
|
* -- used only with array datatype
|
||||||
|
* -- if omitted with an array the entire array is referenced
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* @param apdu Pointer to the buffer, or NULL for length
|
||||||
|
* @param data Pointer to the data to encode.
|
||||||
|
* @return number of bytes encoded, or zero on error.
|
||||||
|
*/
|
||||||
|
int read_property_request_encode(uint8_t *apdu, BACNET_READ_PROPERTY_DATA *data)
|
||||||
|
{
|
||||||
|
int len = 0; /* length of each encoding */
|
||||||
|
int apdu_len = 0; /* total length of the apdu, return value */
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* object-identifier [0] BACnetObjectIdentifier */
|
||||||
|
if (data->object_type <= BACNET_MAX_OBJECT) {
|
||||||
|
len = encode_context_object_id(
|
||||||
|
apdu, 0, data->object_type, data->object_instance);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* property-identifier [1] BACnetPropertyIdentifier */
|
||||||
|
if (data->object_property <= MAX_BACNET_PROPERTY_ID) {
|
||||||
|
len = encode_context_enumerated(apdu, 1, data->object_property);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* property-array-index [2] Unsigned OPTIONAL */
|
||||||
|
if (data->array_index != BACNET_ARRAY_ALL) {
|
||||||
|
len = encode_context_unsigned(apdu, 2, data->array_index);
|
||||||
|
apdu_len += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return apdu_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Encode the ReadProperty-Request service
|
||||||
|
* @param apdu Pointer to the buffer for encoding into
|
||||||
|
* @param apdu_size number of bytes available in the buffer
|
||||||
|
* @param data Pointer to the service data used for encoding values
|
||||||
|
* @return number of bytes encoded, or zero if unable to encode or too large
|
||||||
|
*/
|
||||||
|
size_t read_property_request_service_encode(
|
||||||
|
uint8_t *apdu, size_t apdu_size, BACNET_READ_PROPERTY_DATA *data)
|
||||||
|
{
|
||||||
|
size_t apdu_len = 0; /* total length of the apdu, return value */
|
||||||
|
|
||||||
|
apdu_len = read_property_request_encode(NULL, data);
|
||||||
|
if (apdu_len > apdu_size) {
|
||||||
|
apdu_len = 0;
|
||||||
|
} else {
|
||||||
|
apdu_len = read_property_request_encode(apdu, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return apdu_len;
|
||||||
|
}
|
||||||
|
|
||||||
/** Encode the service
|
/** Encode the service
|
||||||
*
|
*
|
||||||
@@ -50,7 +120,7 @@
|
|||||||
* @return Bytes encoded or zero on error.
|
* @return Bytes encoded or zero on error.
|
||||||
*/
|
*/
|
||||||
int rp_encode_apdu(
|
int rp_encode_apdu(
|
||||||
uint8_t *apdu, uint8_t invoke_id, BACNET_READ_PROPERTY_DATA *rpdata)
|
uint8_t *apdu, uint8_t invoke_id, BACNET_READ_PROPERTY_DATA *data)
|
||||||
{
|
{
|
||||||
int len = 0; /* length of each encoding */
|
int len = 0; /* length of each encoding */
|
||||||
int apdu_len = 0; /* total length of the apdu, return value */
|
int apdu_len = 0; /* total length of the apdu, return value */
|
||||||
@@ -60,29 +130,14 @@ int rp_encode_apdu(
|
|||||||
apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU);
|
apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU);
|
||||||
apdu[2] = invoke_id;
|
apdu[2] = invoke_id;
|
||||||
apdu[3] = SERVICE_CONFIRMED_READ_PROPERTY; /* service choice */
|
apdu[3] = SERVICE_CONFIRMED_READ_PROPERTY; /* service choice */
|
||||||
apdu_len = 4;
|
}
|
||||||
if (rpdata->object_type <= BACNET_MAX_OBJECT) {
|
len = 4;
|
||||||
/* check bounds so that we could create malformed
|
|
||||||
messages for testing */
|
|
||||||
len = encode_context_object_id(&apdu[apdu_len], 0,
|
|
||||||
rpdata->object_type, rpdata->object_instance);
|
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
}
|
}
|
||||||
/* The value should be in the range of 0 to 4194303. */
|
len = read_property_request_encode(apdu, data);
|
||||||
if (rpdata->object_property <= MAX_BACNET_PROPERTY_ID) {
|
|
||||||
/* check bounds so that we could create malformed
|
|
||||||
messages for testing */
|
|
||||||
len = encode_context_enumerated(
|
|
||||||
&apdu[apdu_len], 1, rpdata->object_property);
|
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
}
|
|
||||||
/* optional array index */
|
|
||||||
if (rpdata->array_index != BACNET_ARRAY_ALL) {
|
|
||||||
len = encode_context_unsigned(
|
|
||||||
&apdu[apdu_len], 2, rpdata->array_index);
|
|
||||||
apdu_len += len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return apdu_len;
|
return apdu_len;
|
||||||
}
|
}
|
||||||
@@ -158,6 +213,91 @@ int rp_decode_service_request(
|
|||||||
|
|
||||||
return (int)len;
|
return (int)len;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @brief Encode APDU for ReadProperty-ACK
|
||||||
|
*
|
||||||
|
* ReadProperty-ACK ::= SEQUENCE {
|
||||||
|
* object-identifier [0] BACnetObjectIdentifier,
|
||||||
|
* property-identifier [1] BACnetPropertyIdentifier,
|
||||||
|
* property-array-index [2] Unsigned OPTIONAL,
|
||||||
|
* -- used only with array datatype
|
||||||
|
* -- if omitted with an array the entire array is referenced
|
||||||
|
* property-value [3]
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* @param apdu Pointer to the buffer, or NULL for length
|
||||||
|
* @param data Pointer to the data to encode.
|
||||||
|
* @return number of bytes encoded, or zero on error.
|
||||||
|
*/
|
||||||
|
int read_property_ack_encode(uint8_t *apdu, BACNET_READ_PROPERTY_DATA *data)
|
||||||
|
{
|
||||||
|
int len = 0; /* length of each encoding */
|
||||||
|
int apdu_len = 0; /* total length of the apdu, return value */
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* object-identifier [0] BACnetObjectIdentifier */
|
||||||
|
len = encode_context_object_id(
|
||||||
|
apdu, 0, data->object_type, data->object_instance);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
/* property-identifier [1] BACnetPropertyIdentifier */
|
||||||
|
len = encode_context_enumerated(apdu, 1, data->object_property);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
/* property-array-index [2] Unsigned OPTIONAL */
|
||||||
|
if (data->array_index != BACNET_ARRAY_ALL) {
|
||||||
|
len = encode_context_unsigned(apdu, 2, data->array_index);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* property-value [3] */
|
||||||
|
len = encode_opening_tag(apdu, 3);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
if (apdu) {
|
||||||
|
for (len = 0; len < data->application_data_len; len++) {
|
||||||
|
apdu[len] = data->application_data[len];
|
||||||
|
}
|
||||||
|
apdu += data->application_data_len;
|
||||||
|
}
|
||||||
|
apdu_len += data->application_data_len;
|
||||||
|
len = encode_closing_tag(apdu, 3);
|
||||||
|
apdu_len += len;
|
||||||
|
|
||||||
|
return apdu_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Encode the COVNotification service request
|
||||||
|
* @param apdu Pointer to the buffer for encoding into
|
||||||
|
* @param apdu_size number of bytes available in the buffer
|
||||||
|
* @param data Pointer to the service data used for encoding values
|
||||||
|
* @return number of bytes encoded, or zero if unable to encode or too large
|
||||||
|
*/
|
||||||
|
size_t read_property_ack_service_encode(
|
||||||
|
uint8_t *apdu, size_t apdu_size, BACNET_READ_PROPERTY_DATA *data)
|
||||||
|
{
|
||||||
|
size_t apdu_len = 0; /* total length of the apdu, return value */
|
||||||
|
|
||||||
|
apdu_len = read_property_ack_encode(NULL, data);
|
||||||
|
if (apdu_len > apdu_size) {
|
||||||
|
apdu_len = 0;
|
||||||
|
} else {
|
||||||
|
apdu_len = read_property_ack_encode(apdu, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return apdu_len;
|
||||||
|
}
|
||||||
|
|
||||||
/** Alternate method to encode the ack without extra buffer.
|
/** Alternate method to encode the ack without extra buffer.
|
||||||
*
|
*
|
||||||
@@ -177,24 +317,34 @@ int rp_ack_encode_apdu_init(
|
|||||||
apdu[0] = PDU_TYPE_COMPLEX_ACK; /* complex ACK service */
|
apdu[0] = PDU_TYPE_COMPLEX_ACK; /* complex ACK service */
|
||||||
apdu[1] = invoke_id; /* original invoke id from request */
|
apdu[1] = invoke_id; /* original invoke id from request */
|
||||||
apdu[2] = SERVICE_CONFIRMED_READ_PROPERTY; /* service choice */
|
apdu[2] = SERVICE_CONFIRMED_READ_PROPERTY; /* service choice */
|
||||||
apdu_len = 3;
|
}
|
||||||
|
len = 3;
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
/* service ack follows */
|
/* service ack follows */
|
||||||
len = encode_context_object_id(
|
len = encode_context_object_id(
|
||||||
&apdu[apdu_len], 0, rpdata->object_type, rpdata->object_instance);
|
apdu, 0, rpdata->object_type, rpdata->object_instance);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
len = encode_context_enumerated(
|
if (apdu) {
|
||||||
&apdu[apdu_len], 1, rpdata->object_property);
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_context_enumerated(apdu, 1, rpdata->object_property);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
/* context 2 array index is optional */
|
/* context 2 array index is optional */
|
||||||
if (rpdata->array_index != BACNET_ARRAY_ALL) {
|
if (rpdata->array_index != BACNET_ARRAY_ALL) {
|
||||||
len = encode_context_unsigned(
|
len = encode_context_unsigned(apdu, 2, rpdata->array_index);
|
||||||
&apdu[apdu_len], 2, rpdata->array_index);
|
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
}
|
}
|
||||||
len = encode_opening_tag(&apdu[apdu_len], 3);
|
}
|
||||||
|
len = encode_opening_tag(apdu, 3);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
}
|
|
||||||
|
|
||||||
return apdu_len;
|
return apdu_len;
|
||||||
}
|
}
|
||||||
@@ -234,19 +384,25 @@ int rp_ack_encode_apdu(
|
|||||||
int len = 0; /* length of each encoding */
|
int len = 0; /* length of each encoding */
|
||||||
int apdu_len = 0; /* total length of the apdu, return value */
|
int apdu_len = 0; /* total length of the apdu, return value */
|
||||||
|
|
||||||
if (apdu) {
|
if (rpdata) {
|
||||||
/* Do the initial encoding */
|
/* Do the initial encoding */
|
||||||
apdu_len = rp_ack_encode_apdu_init(apdu, invoke_id, rpdata);
|
len = rp_ack_encode_apdu_init(apdu, invoke_id, rpdata);
|
||||||
/* propertyValue
|
apdu_len += len;
|
||||||
* double check maximum possible */
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
imax = rpdata->application_data_len;
|
imax = rpdata->application_data_len;
|
||||||
if (imax > (MAX_APDU - apdu_len - 2)) {
|
|
||||||
imax = (MAX_APDU - apdu_len - 2);
|
|
||||||
}
|
|
||||||
for (len = 0; len < imax; len++) {
|
for (len = 0; len < imax; len++) {
|
||||||
apdu[apdu_len++] = rpdata->application_data[len];
|
if (apdu) {
|
||||||
|
apdu[len] = rpdata->application_data[len];
|
||||||
}
|
}
|
||||||
apdu_len += encode_closing_tag(&apdu[apdu_len], 3);
|
}
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_closing_tag(apdu, 3);
|
||||||
|
apdu_len += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
return apdu_len;
|
return apdu_len;
|
||||||
|
|||||||
+22
-1
@@ -61,7 +61,28 @@ typedef int (
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
/* encode service */
|
BACNET_STACK_EXPORT
|
||||||
|
int read_property_request_encode(
|
||||||
|
uint8_t *apdu,
|
||||||
|
BACNET_READ_PROPERTY_DATA *data);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
size_t read_property_request_service_encode(
|
||||||
|
uint8_t *apdu,
|
||||||
|
size_t apdu_size,
|
||||||
|
BACNET_READ_PROPERTY_DATA *data);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
int read_property_ack_encode(
|
||||||
|
uint8_t *apdu,
|
||||||
|
BACNET_READ_PROPERTY_DATA *data);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
size_t read_property_ack_service_encode(
|
||||||
|
uint8_t *apdu,
|
||||||
|
size_t apdu_size,
|
||||||
|
BACNET_READ_PROPERTY_DATA *data);
|
||||||
|
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
int rp_encode_apdu(
|
int rp_encode_apdu(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
|
|||||||
+105
-45
@@ -41,6 +41,104 @@
|
|||||||
/** @file wp.c Encode/Decode BACnet Write Property APDUs */
|
/** @file wp.c Encode/Decode BACnet Write Property APDUs */
|
||||||
|
|
||||||
#if BACNET_SVC_WP_A
|
#if BACNET_SVC_WP_A
|
||||||
|
/**
|
||||||
|
* @brief Encode the WriteProperty service request
|
||||||
|
*
|
||||||
|
* WriteProperty-Request ::= SEQUENCE {
|
||||||
|
* object-identifier [0] BACnetObjectIdentifier,
|
||||||
|
* property-identifier [1] BACnetPropertyIdentifier,
|
||||||
|
* property-array-index [2] Unsigned OPTIONAL,
|
||||||
|
* -- used only with array datatype
|
||||||
|
* -- if omitted with an array the entire
|
||||||
|
* -- array is referenced
|
||||||
|
* property-value [3] ABSTRACT-SYNTAX.&Type,
|
||||||
|
* priority [4] Unsigned (1..16) OPTIONAL
|
||||||
|
* -– used only when property is commandable
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* @param apdu Pointer to the buffer, or NULL for length
|
||||||
|
* @param invoke_id ID of service invoked.
|
||||||
|
* @param data Pointer to the service data used for encoding values
|
||||||
|
* @return number of bytes encoded, or zero if unable to encode
|
||||||
|
*/
|
||||||
|
size_t writeproperty_apdu_encode(
|
||||||
|
uint8_t *apdu, BACNET_WRITE_PROPERTY_DATA *data)
|
||||||
|
{
|
||||||
|
size_t apdu_len = 0; /* total length of the apdu, return value */
|
||||||
|
size_t len = 0; /* total length of the apdu, return value */
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
len = encode_context_object_id(
|
||||||
|
apdu, 0, data->object_type, data->object_instance);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
len = encode_context_enumerated(apdu, 1, data->object_property);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
/* optional array index; ALL is -1 which is assumed when missing */
|
||||||
|
if (data->array_index != BACNET_ARRAY_ALL) {
|
||||||
|
len = encode_context_unsigned(apdu, 2, data->array_index);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* propertyValue */
|
||||||
|
len = encode_opening_tag(apdu, 3);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
for (len = 0; len < data->application_data_len; len++) {
|
||||||
|
if (apdu) {
|
||||||
|
*apdu = data->application_data[len];
|
||||||
|
apdu += 1;
|
||||||
|
}
|
||||||
|
apdu_len++;
|
||||||
|
}
|
||||||
|
len = encode_closing_tag(apdu, 3);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu) {
|
||||||
|
apdu += len;
|
||||||
|
}
|
||||||
|
/* optional priority - 0 if not set, 1..16 if set */
|
||||||
|
if (data->priority != BACNET_NO_PRIORITY) {
|
||||||
|
len = encode_context_unsigned(apdu, 4, data->priority);
|
||||||
|
apdu_len += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return apdu_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize the APDU for encode service.
|
||||||
|
* @param apdu Pointer to the buffer, or NULL for length
|
||||||
|
* @param apdu Pointer to the buffer for encoding into
|
||||||
|
* @param apdu_size number of bytes available in the buffer
|
||||||
|
* @param data Pointer to the service data used for encoding values
|
||||||
|
* @return number of bytes encoded, or zero if unable to encode or too large
|
||||||
|
*/
|
||||||
|
size_t writeproperty_service_request_encode(
|
||||||
|
uint8_t *apdu, size_t apdu_size, BACNET_WRITE_PROPERTY_DATA *data)
|
||||||
|
{
|
||||||
|
size_t apdu_len = 0; /* total length of the apdu, return value */
|
||||||
|
|
||||||
|
apdu_len = writeproperty_apdu_encode(NULL, data);
|
||||||
|
if (apdu_len > apdu_size) {
|
||||||
|
apdu_len = 0;
|
||||||
|
} else {
|
||||||
|
apdu_len = writeproperty_apdu_encode(apdu, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return apdu_len;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialize the APDU for encode service.
|
* @brief Initialize the APDU for encode service.
|
||||||
*
|
*
|
||||||
@@ -82,48 +180,8 @@ int wp_encode_apdu(
|
|||||||
if (apdu) {
|
if (apdu) {
|
||||||
apdu += len;
|
apdu += len;
|
||||||
}
|
}
|
||||||
len = encode_context_object_id(
|
len = writeproperty_apdu_encode(apdu, wpdata);
|
||||||
apdu, 0, wpdata->object_type, wpdata->object_instance);
|
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
if (apdu) {
|
|
||||||
apdu += len;
|
|
||||||
}
|
|
||||||
len = encode_context_enumerated(apdu, 1, wpdata->object_property);
|
|
||||||
apdu_len += len;
|
|
||||||
if (apdu) {
|
|
||||||
apdu += len;
|
|
||||||
}
|
|
||||||
/* optional array index; ALL is -1 which is assumed when missing */
|
|
||||||
if (wpdata->array_index != BACNET_ARRAY_ALL) {
|
|
||||||
len = encode_context_unsigned(apdu, 2, wpdata->array_index);
|
|
||||||
apdu_len += len;
|
|
||||||
if (apdu) {
|
|
||||||
apdu += len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* propertyValue */
|
|
||||||
len = encode_opening_tag(apdu, 3);
|
|
||||||
apdu_len += len;
|
|
||||||
if (apdu) {
|
|
||||||
apdu += len;
|
|
||||||
}
|
|
||||||
for (len = 0; len < wpdata->application_data_len; len++) {
|
|
||||||
if (apdu) {
|
|
||||||
*apdu = wpdata->application_data[len];
|
|
||||||
apdu += 1;
|
|
||||||
}
|
|
||||||
apdu_len++;
|
|
||||||
}
|
|
||||||
len = encode_closing_tag(apdu, 3);
|
|
||||||
apdu_len += len;
|
|
||||||
if (apdu) {
|
|
||||||
apdu += len;
|
|
||||||
}
|
|
||||||
/* optional priority - 0 if not set, 1..16 if set */
|
|
||||||
if (wpdata->priority != BACNET_NO_PRIORITY) {
|
|
||||||
len = encode_context_unsigned(apdu, 4, wpdata->priority);
|
|
||||||
apdu_len += len;
|
|
||||||
}
|
|
||||||
|
|
||||||
return apdu_len;
|
return apdu_len;
|
||||||
}
|
}
|
||||||
@@ -318,8 +376,9 @@ bool write_property_string_valid(BACNET_WRITE_PROPERTY_DATA *wp_data,
|
|||||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||||
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||||
}
|
}
|
||||||
} else if ((len_max > 0) && (characterstring_length(
|
} else if ((len_max > 0) &&
|
||||||
&value->type.Character_String) > len_max)) {
|
(characterstring_length(&value->type.Character_String) >
|
||||||
|
len_max)) {
|
||||||
if (wp_data) {
|
if (wp_data) {
|
||||||
wp_data->error_class = ERROR_CLASS_RESOURCES;
|
wp_data->error_class = ERROR_CLASS_RESOURCES;
|
||||||
wp_data->error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY;
|
wp_data->error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY;
|
||||||
@@ -362,8 +421,9 @@ bool write_property_empty_string_valid(BACNET_WRITE_PROPERTY_DATA *wp_data,
|
|||||||
if (value && (value->tag == BACNET_APPLICATION_TAG_CHARACTER_STRING)) {
|
if (value && (value->tag == BACNET_APPLICATION_TAG_CHARACTER_STRING)) {
|
||||||
if (characterstring_encoding(&value->type.Character_String) ==
|
if (characterstring_encoding(&value->type.Character_String) ==
|
||||||
CHARACTER_ANSI_X34) {
|
CHARACTER_ANSI_X34) {
|
||||||
if ((len_max > 0) && (characterstring_length(
|
if ((len_max > 0) &&
|
||||||
&value->type.Character_String) > len_max)) {
|
(characterstring_length(&value->type.Character_String) >
|
||||||
|
len_max)) {
|
||||||
if (wp_data) {
|
if (wp_data) {
|
||||||
wp_data->error_class = ERROR_CLASS_RESOURCES;
|
wp_data->error_class = ERROR_CLASS_RESOURCES;
|
||||||
wp_data->error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY;
|
wp_data->error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY;
|
||||||
|
|||||||
@@ -68,6 +68,15 @@ extern "C" {
|
|||||||
|
|
||||||
/* encode service */
|
/* encode service */
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
|
size_t writeproperty_apdu_encode(
|
||||||
|
uint8_t *apdu,
|
||||||
|
BACNET_WRITE_PROPERTY_DATA *data);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
size_t writeproperty_service_request_encode(
|
||||||
|
uint8_t *apdu,
|
||||||
|
size_t apdu_size,
|
||||||
|
BACNET_WRITE_PROPERTY_DATA *data);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
int wp_encode_apdu(
|
int wp_encode_apdu(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
uint8_t invoke_id,
|
uint8_t invoke_id,
|
||||||
|
|||||||
@@ -165,13 +165,14 @@ static void testCOVNotifyData(BACNET_COV_DATA *data, BACNET_COV_DATA *test_data)
|
|||||||
static void testUCOVNotifyData(BACNET_COV_DATA *data)
|
static void testUCOVNotifyData(BACNET_COV_DATA *data)
|
||||||
{
|
{
|
||||||
uint8_t apdu[480] = { 0 };
|
uint8_t apdu[480] = { 0 };
|
||||||
int len = 0;
|
int len = 0, null_len = 0, apdu_len = 0;
|
||||||
int apdu_len = 0;
|
|
||||||
BACNET_COV_DATA test_data = { 0 };
|
BACNET_COV_DATA test_data = { 0 };
|
||||||
BACNET_PROPERTY_VALUE value_list[5] = { { 0 } };
|
BACNET_PROPERTY_VALUE value_list[5] = { { 0 } };
|
||||||
|
|
||||||
|
null_len = ucov_notify_encode_apdu(NULL, sizeof(apdu), data);
|
||||||
len = ucov_notify_encode_apdu(&apdu[0], sizeof(apdu), data);
|
len = ucov_notify_encode_apdu(&apdu[0], sizeof(apdu), data);
|
||||||
zassert_true(len > 0, NULL);
|
zassert_true(len > 0, NULL);
|
||||||
|
zassert_equal(len, null_len, NULL);
|
||||||
apdu_len = len;
|
apdu_len = len;
|
||||||
|
|
||||||
cov_data_value_list_link(
|
cov_data_value_list_link(
|
||||||
@@ -184,14 +185,15 @@ static void testUCOVNotifyData(BACNET_COV_DATA *data)
|
|||||||
static void testCCOVNotifyData(uint8_t invoke_id, BACNET_COV_DATA *data)
|
static void testCCOVNotifyData(uint8_t invoke_id, BACNET_COV_DATA *data)
|
||||||
{
|
{
|
||||||
uint8_t apdu[480] = { 0 };
|
uint8_t apdu[480] = { 0 };
|
||||||
int len = 0;
|
int len = 0, null_len = 0, apdu_len = 0;
|
||||||
int apdu_len = 0;
|
|
||||||
BACNET_COV_DATA test_data = { 0 };
|
BACNET_COV_DATA test_data = { 0 };
|
||||||
BACNET_PROPERTY_VALUE value_list[2] = { { 0 } };
|
BACNET_PROPERTY_VALUE value_list[2] = { { 0 } };
|
||||||
uint8_t test_invoke_id = 0;
|
uint8_t test_invoke_id = 0;
|
||||||
|
|
||||||
|
null_len = ccov_notify_encode_apdu(NULL, sizeof(apdu), invoke_id, data);
|
||||||
len = ccov_notify_encode_apdu(&apdu[0], sizeof(apdu), invoke_id, data);
|
len = ccov_notify_encode_apdu(&apdu[0], sizeof(apdu), invoke_id, data);
|
||||||
zassert_not_equal(len, 0, NULL);
|
zassert_not_equal(len, 0, NULL);
|
||||||
|
zassert_equal(len, null_len, NULL);
|
||||||
apdu_len = len;
|
apdu_len = len;
|
||||||
|
|
||||||
cov_data_value_list_link(&test_data, &value_list[0], 2);
|
cov_data_value_list_link(&test_data, &value_list[0], 2);
|
||||||
|
|||||||
+38
-26
@@ -20,60 +20,74 @@
|
|||||||
* @brief Test
|
* @brief Test
|
||||||
*/
|
*/
|
||||||
static int dcc_decode_apdu(uint8_t *apdu,
|
static int dcc_decode_apdu(uint8_t *apdu,
|
||||||
unsigned apdu_len,
|
unsigned apdu_size,
|
||||||
uint8_t *invoke_id,
|
uint8_t *invoke_id,
|
||||||
uint16_t *timeDuration,
|
uint16_t *timeDuration,
|
||||||
BACNET_COMMUNICATION_ENABLE_DISABLE *enable_disable,
|
BACNET_COMMUNICATION_ENABLE_DISABLE *enable_disable,
|
||||||
BACNET_CHARACTER_STRING *password)
|
BACNET_CHARACTER_STRING *password)
|
||||||
{
|
{
|
||||||
int len = 0;
|
int len = 0;
|
||||||
unsigned offset = 0;
|
unsigned apdu_len = 0;
|
||||||
|
|
||||||
if (!apdu)
|
if (!apdu) {
|
||||||
return -1;
|
return BACNET_STATUS_ERROR;
|
||||||
/* optional checking - most likely was already done prior to this call */
|
}
|
||||||
if (apdu[0] != PDU_TYPE_CONFIRMED_SERVICE_REQUEST)
|
if (apdu_size > 4) {
|
||||||
return -1;
|
if (apdu[0] != PDU_TYPE_CONFIRMED_SERVICE_REQUEST) {
|
||||||
|
return BACNET_STATUS_ERROR;
|
||||||
|
}
|
||||||
/* apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU); */
|
/* apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU); */
|
||||||
*invoke_id = apdu[2]; /* invoke id - filled in by net layer */
|
*invoke_id = apdu[2]; /* invoke id - filled in by net layer */
|
||||||
if (apdu[3] != SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL)
|
if (apdu[3] != SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL) {
|
||||||
return -1;
|
return BACNET_STATUS_ERROR;
|
||||||
offset = 4;
|
}
|
||||||
|
apdu_len = 4;
|
||||||
if (apdu_len > offset) {
|
} else {
|
||||||
len = dcc_decode_service_request(&apdu[offset], apdu_len - offset,
|
return BACNET_STATUS_ERROR;
|
||||||
|
}
|
||||||
|
if (apdu_size > apdu_len) {
|
||||||
|
len = dcc_decode_service_request(&apdu[apdu_len], apdu_size - apdu_len,
|
||||||
timeDuration, enable_disable, password);
|
timeDuration, enable_disable, password);
|
||||||
|
if (len > 0) {
|
||||||
|
apdu_len += len;
|
||||||
|
} else {
|
||||||
|
apdu_len = len;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return len;
|
return apdu_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_DeviceCommunicationControlData(
|
static void test_DeviceCommunicationControlData(uint8_t invoke_id,
|
||||||
uint8_t invoke_id,
|
|
||||||
uint16_t timeDuration,
|
uint16_t timeDuration,
|
||||||
BACNET_COMMUNICATION_ENABLE_DISABLE enable_disable,
|
BACNET_COMMUNICATION_ENABLE_DISABLE enable_disable,
|
||||||
BACNET_CHARACTER_STRING *password)
|
BACNET_CHARACTER_STRING *password)
|
||||||
{
|
{
|
||||||
uint8_t apdu[480] = { 0 };
|
uint8_t apdu[480] = { 0 };
|
||||||
int len = 0;
|
int apdu_size = 0, null_len = 0, test_len = 0;
|
||||||
int apdu_len = 0;
|
|
||||||
uint8_t test_invoke_id = 0;
|
uint8_t test_invoke_id = 0;
|
||||||
uint16_t test_timeDuration = 0;
|
uint16_t test_timeDuration = 0;
|
||||||
BACNET_COMMUNICATION_ENABLE_DISABLE test_enable_disable;
|
BACNET_COMMUNICATION_ENABLE_DISABLE test_enable_disable;
|
||||||
BACNET_CHARACTER_STRING test_password;
|
BACNET_CHARACTER_STRING test_password;
|
||||||
|
|
||||||
len = dcc_encode_apdu(
|
null_len = dcc_encode_apdu(
|
||||||
|
NULL, invoke_id, timeDuration, enable_disable, password);
|
||||||
|
apdu_size = dcc_encode_apdu(
|
||||||
&apdu[0], invoke_id, timeDuration, enable_disable, password);
|
&apdu[0], invoke_id, timeDuration, enable_disable, password);
|
||||||
zassert_not_equal(len, 0, NULL);
|
zassert_equal(apdu_size, null_len, NULL);
|
||||||
apdu_len = len;
|
zassert_not_equal(apdu_size, 0, NULL);
|
||||||
|
|
||||||
len = dcc_decode_apdu(&apdu[0], apdu_len, &test_invoke_id,
|
test_len = dcc_decode_apdu(&apdu[0], apdu_size, &test_invoke_id,
|
||||||
&test_timeDuration, &test_enable_disable, &test_password);
|
&test_timeDuration, &test_enable_disable, &test_password);
|
||||||
zassert_not_equal(len, -1, NULL);
|
zassert_not_equal(test_len, -1, NULL);
|
||||||
zassert_equal(test_invoke_id, invoke_id, NULL);
|
zassert_equal(test_invoke_id, invoke_id, NULL);
|
||||||
zassert_equal(test_timeDuration, timeDuration, NULL);
|
zassert_equal(test_timeDuration, timeDuration, NULL);
|
||||||
zassert_equal(test_enable_disable, enable_disable, NULL);
|
zassert_equal(test_enable_disable, enable_disable, NULL);
|
||||||
zassert_true(characterstring_same(&test_password, password), NULL);
|
zassert_true(characterstring_same(&test_password, password), NULL);
|
||||||
|
test_len = dcc_decode_apdu(apdu, 4, &test_invoke_id,
|
||||||
|
&test_timeDuration, &test_enable_disable, &test_password);
|
||||||
|
zassert_true(test_len < 0, "apdu_size=%d test_len=%d",
|
||||||
|
apdu_size, test_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_ZTEST_NEW_API)
|
#if defined(CONFIG_ZTEST_NEW_API)
|
||||||
@@ -149,7 +163,6 @@ static void test_DeviceCommunicationControlMalformedData(void)
|
|||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#if defined(CONFIG_ZTEST_NEW_API)
|
#if defined(CONFIG_ZTEST_NEW_API)
|
||||||
ZTEST_SUITE(dcc_tests, NULL, NULL, NULL, NULL, NULL);
|
ZTEST_SUITE(dcc_tests, NULL, NULL, NULL, NULL, NULL);
|
||||||
#else
|
#else
|
||||||
@@ -157,8 +170,7 @@ void test_main(void)
|
|||||||
{
|
{
|
||||||
ztest_test_suite(dcc_tests,
|
ztest_test_suite(dcc_tests,
|
||||||
ztest_unit_test(test_DeviceCommunicationControl),
|
ztest_unit_test(test_DeviceCommunicationControl),
|
||||||
ztest_unit_test(test_DeviceCommunicationControlMalformedData)
|
ztest_unit_test(test_DeviceCommunicationControlMalformedData));
|
||||||
);
|
|
||||||
|
|
||||||
ztest_run_test_suite(dcc_tests);
|
ztest_run_test_suite(dcc_tests);
|
||||||
}
|
}
|
||||||
|
|||||||
+278
-342
@@ -25,17 +25,14 @@ static BACNET_EVENT_NOTIFICATION_DATA data2;
|
|||||||
static void verifyBaseEventState(void)
|
static void verifyBaseEventState(void)
|
||||||
{
|
{
|
||||||
zassert_equal(data.processIdentifier, data2.processIdentifier, NULL);
|
zassert_equal(data.processIdentifier, data2.processIdentifier, NULL);
|
||||||
zassert_equal(
|
zassert_equal(data.initiatingObjectIdentifier.instance,
|
||||||
data.initiatingObjectIdentifier.instance,
|
|
||||||
data2.initiatingObjectIdentifier.instance, NULL);
|
data2.initiatingObjectIdentifier.instance, NULL);
|
||||||
zassert_equal(
|
zassert_equal(data.initiatingObjectIdentifier.type,
|
||||||
data.initiatingObjectIdentifier.type,
|
|
||||||
data2.initiatingObjectIdentifier.type, NULL);
|
data2.initiatingObjectIdentifier.type, NULL);
|
||||||
zassert_equal(
|
zassert_equal(data.eventObjectIdentifier.instance,
|
||||||
data.eventObjectIdentifier.instance,
|
|
||||||
data2.eventObjectIdentifier.instance, NULL);
|
data2.eventObjectIdentifier.instance, NULL);
|
||||||
zassert_equal(
|
zassert_equal(data.eventObjectIdentifier.type,
|
||||||
data.eventObjectIdentifier.type, data2.eventObjectIdentifier.type, NULL);
|
data2.eventObjectIdentifier.type, NULL);
|
||||||
zassert_equal(data.notificationClass, data2.notificationClass, NULL);
|
zassert_equal(data.notificationClass, data2.notificationClass, NULL);
|
||||||
zassert_equal(data.priority, data2.priority, NULL);
|
zassert_equal(data.priority, data2.priority, NULL);
|
||||||
zassert_equal(data.notifyType, data2.notifyType, NULL);
|
zassert_equal(data.notifyType, data2.notifyType, NULL);
|
||||||
@@ -44,8 +41,10 @@ static void verifyBaseEventState(void)
|
|||||||
zassert_equal(data.toState, data2.toState, NULL);
|
zassert_equal(data.toState, data2.toState, NULL);
|
||||||
|
|
||||||
if (data.messageText != NULL && data2.messageText != NULL) {
|
if (data.messageText != NULL && data2.messageText != NULL) {
|
||||||
zassert_equal(data.messageText->encoding, data2.messageText->encoding, NULL);
|
zassert_equal(
|
||||||
zassert_equal(data.messageText->length, data2.messageText->length, NULL);
|
data.messageText->encoding, data2.messageText->encoding, NULL);
|
||||||
|
zassert_equal(
|
||||||
|
data.messageText->length, data2.messageText->length, NULL);
|
||||||
zassert_equal(
|
zassert_equal(
|
||||||
strcmp(data.messageText->value, data2.messageText->value), 0, NULL);
|
strcmp(data.messageText->value, data2.messageText->value), 0, NULL);
|
||||||
}
|
}
|
||||||
@@ -54,51 +53,38 @@ static void verifyBaseEventState(void)
|
|||||||
|
|
||||||
switch (data.timeStamp.tag) {
|
switch (data.timeStamp.tag) {
|
||||||
case TIME_STAMP_SEQUENCE:
|
case TIME_STAMP_SEQUENCE:
|
||||||
zassert_equal(
|
zassert_equal(data.timeStamp.value.sequenceNum,
|
||||||
data.timeStamp.value.sequenceNum,
|
|
||||||
data2.timeStamp.value.sequenceNum, NULL);
|
data2.timeStamp.value.sequenceNum, NULL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TIME_STAMP_DATETIME:
|
case TIME_STAMP_DATETIME:
|
||||||
zassert_equal(
|
zassert_equal(data.timeStamp.value.dateTime.time.hour,
|
||||||
data.timeStamp.value.dateTime.time.hour,
|
|
||||||
data2.timeStamp.value.dateTime.time.hour, NULL);
|
data2.timeStamp.value.dateTime.time.hour, NULL);
|
||||||
zassert_equal(
|
zassert_equal(data.timeStamp.value.dateTime.time.min,
|
||||||
data.timeStamp.value.dateTime.time.min,
|
|
||||||
data2.timeStamp.value.dateTime.time.min, NULL);
|
data2.timeStamp.value.dateTime.time.min, NULL);
|
||||||
zassert_equal(
|
zassert_equal(data.timeStamp.value.dateTime.time.sec,
|
||||||
data.timeStamp.value.dateTime.time.sec,
|
|
||||||
data2.timeStamp.value.dateTime.time.sec, NULL);
|
data2.timeStamp.value.dateTime.time.sec, NULL);
|
||||||
zassert_equal(
|
zassert_equal(data.timeStamp.value.dateTime.time.hundredths,
|
||||||
data.timeStamp.value.dateTime.time.hundredths,
|
|
||||||
data2.timeStamp.value.dateTime.time.hundredths, NULL);
|
data2.timeStamp.value.dateTime.time.hundredths, NULL);
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(data.timeStamp.value.dateTime.date.day,
|
||||||
data.timeStamp.value.dateTime.date.day,
|
|
||||||
data2.timeStamp.value.dateTime.date.day, NULL);
|
data2.timeStamp.value.dateTime.date.day, NULL);
|
||||||
zassert_equal(
|
zassert_equal(data.timeStamp.value.dateTime.date.month,
|
||||||
data.timeStamp.value.dateTime.date.month,
|
|
||||||
data2.timeStamp.value.dateTime.date.month, NULL);
|
data2.timeStamp.value.dateTime.date.month, NULL);
|
||||||
zassert_equal(
|
zassert_equal(data.timeStamp.value.dateTime.date.wday,
|
||||||
data.timeStamp.value.dateTime.date.wday,
|
|
||||||
data2.timeStamp.value.dateTime.date.wday, NULL);
|
data2.timeStamp.value.dateTime.date.wday, NULL);
|
||||||
zassert_equal(
|
zassert_equal(data.timeStamp.value.dateTime.date.year,
|
||||||
data.timeStamp.value.dateTime.date.year,
|
|
||||||
data2.timeStamp.value.dateTime.date.year, NULL);
|
data2.timeStamp.value.dateTime.date.year, NULL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TIME_STAMP_TIME:
|
case TIME_STAMP_TIME:
|
||||||
zassert_equal(
|
zassert_equal(data.timeStamp.value.time.hour,
|
||||||
data.timeStamp.value.time.hour,
|
|
||||||
data2.timeStamp.value.time.hour, NULL);
|
data2.timeStamp.value.time.hour, NULL);
|
||||||
zassert_equal(
|
zassert_equal(data.timeStamp.value.time.min,
|
||||||
data.timeStamp.value.time.min,
|
|
||||||
data2.timeStamp.value.time.min, NULL);
|
data2.timeStamp.value.time.min, NULL);
|
||||||
zassert_equal(
|
zassert_equal(data.timeStamp.value.time.sec,
|
||||||
data.timeStamp.value.time.sec,
|
|
||||||
data2.timeStamp.value.time.sec, NULL);
|
data2.timeStamp.value.time.sec, NULL);
|
||||||
zassert_equal(
|
zassert_equal(data.timeStamp.value.time.hundredths,
|
||||||
data.timeStamp.value.time.hundredths,
|
|
||||||
data2.timeStamp.value.time.hundredths, NULL);
|
data2.timeStamp.value.time.hundredths, NULL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -118,8 +104,7 @@ static void testEventEventState(void)
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
uint8_t buffer[MAX_APDU];
|
uint8_t buffer[MAX_APDU];
|
||||||
int inLen;
|
int apdu_len, test_len, null_len;
|
||||||
int outLen;
|
|
||||||
BACNET_CHARACTER_STRING messageText;
|
BACNET_CHARACTER_STRING messageText;
|
||||||
BACNET_CHARACTER_STRING messageText2;
|
BACNET_CHARACTER_STRING messageText2;
|
||||||
characterstring_init_ansi(
|
characterstring_init_ansi(
|
||||||
@@ -156,31 +141,25 @@ static void testEventEventState(void)
|
|||||||
bitstring_set_bit(&data.notificationParams.changeOfState.statusFlags,
|
bitstring_set_bit(&data.notificationParams.changeOfState.statusFlags,
|
||||||
STATUS_FLAG_OUT_OF_SERVICE, false);
|
STATUS_FLAG_OUT_OF_SERVICE, false);
|
||||||
|
|
||||||
inLen = event_notify_encode_service_request(&buffer[0], &data);
|
null_len = event_notify_encode_service_request(NULL, &data);
|
||||||
|
apdu_len = event_notify_encode_service_request(&buffer[0], &data);
|
||||||
outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2);
|
zassert_equal(
|
||||||
|
apdu_len, null_len, "apdu_len=%d null_len=%d", apdu_len, null_len);
|
||||||
zassert_equal(inLen, outLen, NULL);
|
test_len =
|
||||||
|
event_notify_decode_service_request(&buffer[0], apdu_len, &data2);
|
||||||
|
zassert_equal(
|
||||||
|
apdu_len, test_len, "apdu_len=%d test_len=%d", apdu_len, test_len);
|
||||||
verifyBaseEventState();
|
verifyBaseEventState();
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(data.notificationParams.changeOfState.newState.tag,
|
||||||
data.notificationParams.changeOfState.newState.tag,
|
|
||||||
data2.notificationParams.changeOfState.newState.tag, NULL);
|
data2.notificationParams.changeOfState.newState.tag, NULL);
|
||||||
zassert_equal(
|
zassert_equal(data.notificationParams.changeOfState.newState.state.units,
|
||||||
data.notificationParams.changeOfState.newState.state.units,
|
|
||||||
data2.notificationParams.changeOfState.newState.state.units, NULL);
|
data2.notificationParams.changeOfState.newState.state.units, NULL);
|
||||||
|
|
||||||
zassert_true(
|
zassert_true(
|
||||||
bitstring_same(&data.notificationParams.changeOfState.statusFlags,
|
bitstring_same(&data.notificationParams.changeOfState.statusFlags,
|
||||||
&data2.notificationParams.changeOfState.statusFlags), NULL);
|
&data2.notificationParams.changeOfState.statusFlags),
|
||||||
|
NULL);
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Same, but timestamp of
|
** Same, but timestamp of
|
||||||
@@ -197,29 +176,22 @@ static void testEventEventState(void)
|
|||||||
data.timeStamp.value.dateTime.date.year = 1945;
|
data.timeStamp.value.dateTime.date.year = 1945;
|
||||||
|
|
||||||
memset(buffer, 0, MAX_APDU);
|
memset(buffer, 0, MAX_APDU);
|
||||||
inLen = event_notify_encode_service_request(&buffer[0], &data);
|
null_len = event_notify_encode_service_request(NULL, &data);
|
||||||
|
apdu_len = event_notify_encode_service_request(&buffer[0], &data);
|
||||||
|
zassert_equal(
|
||||||
|
apdu_len, null_len, "apdu_len=%d null_len=%d", apdu_len, null_len);
|
||||||
|
|
||||||
memset(&data2, 0, sizeof(data2));
|
memset(&data2, 0, sizeof(data2));
|
||||||
data2.messageText = &messageText2;
|
data2.messageText = &messageText2;
|
||||||
outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2);
|
test_len =
|
||||||
|
event_notify_decode_service_request(&buffer[0], apdu_len, &data2);
|
||||||
|
|
||||||
zassert_equal(inLen, outLen, NULL);
|
zassert_equal(apdu_len, test_len, NULL);
|
||||||
verifyBaseEventState();
|
verifyBaseEventState();
|
||||||
zassert_equal(
|
zassert_equal(data.notificationParams.changeOfState.newState.tag,
|
||||||
data.notificationParams.changeOfState.newState.tag,
|
|
||||||
data2.notificationParams.changeOfState.newState.tag, NULL);
|
data2.notificationParams.changeOfState.newState.tag, NULL);
|
||||||
zassert_equal(
|
zassert_equal(data.notificationParams.changeOfState.newState.state.units,
|
||||||
data.notificationParams.changeOfState.newState.state.units,
|
|
||||||
data2.notificationParams.changeOfState.newState.state.units, NULL);
|
data2.notificationParams.changeOfState.newState.state.units, NULL);
|
||||||
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Event Type = EVENT_CHANGE_OF_BITSTRING
|
** Event Type = EVENT_CHANGE_OF_BITSTRING
|
||||||
*/
|
*/
|
||||||
@@ -255,35 +227,33 @@ static void testEventEventState(void)
|
|||||||
STATUS_FLAG_OUT_OF_SERVICE, false);
|
STATUS_FLAG_OUT_OF_SERVICE, false);
|
||||||
|
|
||||||
memset(buffer, 0, MAX_APDU);
|
memset(buffer, 0, MAX_APDU);
|
||||||
inLen = event_notify_encode_service_request(&buffer[0], &data);
|
null_len = event_notify_encode_service_request(NULL, &data);
|
||||||
|
apdu_len = event_notify_encode_service_request(&buffer[0], &data);
|
||||||
|
zassert_equal(
|
||||||
|
apdu_len, null_len, "apdu_len=%d null_len=%d", apdu_len, null_len);
|
||||||
|
|
||||||
memset(&data2, 0, sizeof(data2));
|
memset(&data2, 0, sizeof(data2));
|
||||||
data2.messageText = &messageText2;
|
data2.messageText = &messageText2;
|
||||||
outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2);
|
test_len =
|
||||||
|
event_notify_decode_service_request(&buffer[0], apdu_len, &data2);
|
||||||
|
|
||||||
zassert_equal(inLen, outLen, NULL);
|
zassert_equal(apdu_len, test_len, NULL);
|
||||||
verifyBaseEventState();
|
verifyBaseEventState();
|
||||||
|
|
||||||
zassert_true(
|
zassert_true(
|
||||||
bitstring_same(
|
bitstring_same(
|
||||||
&data.notificationParams.changeOfBitstring.referencedBitString,
|
&data.notificationParams.changeOfBitstring.referencedBitString,
|
||||||
&data2.notificationParams.changeOfBitstring.referencedBitString), NULL);
|
&data2.notificationParams.changeOfBitstring.referencedBitString),
|
||||||
|
NULL);
|
||||||
|
|
||||||
zassert_true(
|
zassert_true(
|
||||||
bitstring_same(&data.notificationParams.changeOfBitstring.statusFlags,
|
bitstring_same(&data.notificationParams.changeOfBitstring.statusFlags,
|
||||||
&data2.notificationParams.changeOfBitstring.statusFlags), NULL);
|
&data2.notificationParams.changeOfBitstring.statusFlags),
|
||||||
|
NULL);
|
||||||
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/*
|
/*
|
||||||
** Event Type = EVENT_CHANGE_OF_VALUE - float value
|
** Event Type = EVENT_CHANGE_OF_VALUE - float value
|
||||||
*/
|
*/
|
||||||
|
|
||||||
data.eventType = EVENT_CHANGE_OF_VALUE;
|
data.eventType = EVENT_CHANGE_OF_VALUE;
|
||||||
data.notificationParams.changeOfValue.tag = CHANGE_OF_VALUE_REAL;
|
data.notificationParams.changeOfValue.tag = CHANGE_OF_VALUE_REAL;
|
||||||
data.notificationParams.changeOfValue.newValue.changeValue = 1.23f;
|
data.notificationParams.changeOfValue.newValue.changeValue = 1.23f;
|
||||||
@@ -300,25 +270,28 @@ static void testEventEventState(void)
|
|||||||
STATUS_FLAG_OUT_OF_SERVICE, false);
|
STATUS_FLAG_OUT_OF_SERVICE, false);
|
||||||
|
|
||||||
memset(buffer, 0, MAX_APDU);
|
memset(buffer, 0, MAX_APDU);
|
||||||
inLen = event_notify_encode_service_request(&buffer[0], &data);
|
null_len = event_notify_encode_service_request(NULL, &data);
|
||||||
|
apdu_len = event_notify_encode_service_request(&buffer[0], &data);
|
||||||
|
zassert_equal(
|
||||||
|
apdu_len, null_len, "apdu_len=%d null_len=%d", apdu_len, null_len);
|
||||||
|
|
||||||
memset(&data2, 0, sizeof(data2));
|
memset(&data2, 0, sizeof(data2));
|
||||||
data2.messageText = &messageText2;
|
data2.messageText = &messageText2;
|
||||||
outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2);
|
test_len =
|
||||||
|
event_notify_decode_service_request(&buffer[0], apdu_len, &data2);
|
||||||
|
|
||||||
zassert_equal(inLen, outLen, NULL);
|
zassert_equal(apdu_len, test_len, NULL);
|
||||||
verifyBaseEventState();
|
verifyBaseEventState();
|
||||||
|
|
||||||
zassert_true(
|
zassert_true(
|
||||||
bitstring_same(&data.notificationParams.changeOfValue.statusFlags,
|
bitstring_same(&data.notificationParams.changeOfValue.statusFlags,
|
||||||
&data2.notificationParams.changeOfValue.statusFlags), NULL);
|
&data2.notificationParams.changeOfValue.statusFlags),
|
||||||
|
NULL);
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(data.notificationParams.changeOfValue.tag,
|
||||||
data.notificationParams.changeOfValue.tag,
|
|
||||||
data2.notificationParams.changeOfValue.tag, NULL);
|
data2.notificationParams.changeOfValue.tag, NULL);
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(data.notificationParams.changeOfValue.newValue.changeValue,
|
||||||
data.notificationParams.changeOfValue.newValue.changeValue,
|
|
||||||
data2.notificationParams.changeOfValue.newValue.changeValue, NULL);
|
data2.notificationParams.changeOfValue.newValue.changeValue, NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -326,7 +299,6 @@ static void testEventEventState(void)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
data.notificationParams.changeOfValue.tag = CHANGE_OF_VALUE_BITS;
|
data.notificationParams.changeOfValue.tag = CHANGE_OF_VALUE_BITS;
|
||||||
|
|
||||||
bitstring_init(&data.notificationParams.changeOfValue.newValue.changedBits);
|
bitstring_init(&data.notificationParams.changeOfValue.newValue.changedBits);
|
||||||
bitstring_set_bit(
|
bitstring_set_bit(
|
||||||
&data.notificationParams.changeOfValue.newValue.changedBits, 0, true);
|
&data.notificationParams.changeOfValue.newValue.changedBits, 0, true);
|
||||||
@@ -336,42 +308,34 @@ static void testEventEventState(void)
|
|||||||
&data.notificationParams.changeOfValue.newValue.changedBits, 2, false);
|
&data.notificationParams.changeOfValue.newValue.changedBits, 2, false);
|
||||||
bitstring_set_bit(
|
bitstring_set_bit(
|
||||||
&data.notificationParams.changeOfValue.newValue.changedBits, 3, false);
|
&data.notificationParams.changeOfValue.newValue.changedBits, 3, false);
|
||||||
|
|
||||||
memset(buffer, 0, MAX_APDU);
|
memset(buffer, 0, MAX_APDU);
|
||||||
inLen = event_notify_encode_service_request(&buffer[0], &data);
|
null_len = event_notify_encode_service_request(NULL, &data);
|
||||||
|
apdu_len = event_notify_encode_service_request(&buffer[0], &data);
|
||||||
|
zassert_equal(
|
||||||
|
apdu_len, null_len, "apdu_len=%d null_len=%d", apdu_len, null_len);
|
||||||
memset(&data2, 0, sizeof(data2));
|
memset(&data2, 0, sizeof(data2));
|
||||||
data2.messageText = &messageText2;
|
data2.messageText = &messageText2;
|
||||||
outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2);
|
test_len =
|
||||||
|
event_notify_decode_service_request(&buffer[0], apdu_len, &data2);
|
||||||
|
zassert_equal(apdu_len, test_len, NULL);
|
||||||
|
|
||||||
zassert_equal(inLen, outLen, NULL);
|
|
||||||
verifyBaseEventState();
|
verifyBaseEventState();
|
||||||
|
|
||||||
zassert_true(
|
zassert_true(
|
||||||
bitstring_same(&data.notificationParams.changeOfValue.statusFlags,
|
bitstring_same(&data.notificationParams.changeOfValue.statusFlags,
|
||||||
&data2.notificationParams.changeOfValue.statusFlags), NULL);
|
&data2.notificationParams.changeOfValue.statusFlags),
|
||||||
|
NULL);
|
||||||
zassert_equal(
|
zassert_equal(data.notificationParams.changeOfValue.tag,
|
||||||
data.notificationParams.changeOfValue.tag,
|
|
||||||
data2.notificationParams.changeOfValue.tag, NULL);
|
data2.notificationParams.changeOfValue.tag, NULL);
|
||||||
|
|
||||||
zassert_true(
|
zassert_true(
|
||||||
bitstring_same(
|
bitstring_same(
|
||||||
&data.notificationParams.changeOfValue.newValue.changedBits,
|
&data.notificationParams.changeOfValue.newValue.changedBits,
|
||||||
&data2.notificationParams.changeOfValue.newValue.changedBits), NULL);
|
&data2.notificationParams.changeOfValue.newValue.changedBits),
|
||||||
|
NULL);
|
||||||
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/*
|
/*
|
||||||
** Event Type = EVENT_COMMAND_FAILURE
|
** Event Type = EVENT_COMMAND_FAILURE
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** commandValue = enumerated
|
** commandValue = enumerated
|
||||||
*/
|
*/
|
||||||
@@ -381,9 +345,7 @@ static void testEventEventState(void)
|
|||||||
BINARY_INACTIVE;
|
BINARY_INACTIVE;
|
||||||
data.notificationParams.commandFailure.feedbackValue.binaryValue =
|
data.notificationParams.commandFailure.feedbackValue.binaryValue =
|
||||||
BINARY_ACTIVE;
|
BINARY_ACTIVE;
|
||||||
|
|
||||||
bitstring_init(&data.notificationParams.commandFailure.statusFlags);
|
bitstring_init(&data.notificationParams.commandFailure.statusFlags);
|
||||||
|
|
||||||
bitstring_set_bit(&data.notificationParams.commandFailure.statusFlags,
|
bitstring_set_bit(&data.notificationParams.commandFailure.statusFlags,
|
||||||
STATUS_FLAG_IN_ALARM, true);
|
STATUS_FLAG_IN_ALARM, true);
|
||||||
bitstring_set_bit(&data.notificationParams.commandFailure.statusFlags,
|
bitstring_set_bit(&data.notificationParams.commandFailure.statusFlags,
|
||||||
@@ -392,21 +354,23 @@ static void testEventEventState(void)
|
|||||||
STATUS_FLAG_OVERRIDDEN, false);
|
STATUS_FLAG_OVERRIDDEN, false);
|
||||||
bitstring_set_bit(&data.notificationParams.commandFailure.statusFlags,
|
bitstring_set_bit(&data.notificationParams.commandFailure.statusFlags,
|
||||||
STATUS_FLAG_OUT_OF_SERVICE, false);
|
STATUS_FLAG_OUT_OF_SERVICE, false);
|
||||||
|
|
||||||
memset(buffer, 0, MAX_APDU);
|
memset(buffer, 0, MAX_APDU);
|
||||||
inLen = event_notify_encode_service_request(&buffer[0], &data);
|
null_len = event_notify_encode_service_request(NULL, &data);
|
||||||
|
apdu_len = event_notify_encode_service_request(&buffer[0], &data);
|
||||||
|
zassert_equal(
|
||||||
|
apdu_len, null_len, "apdu_len=%d null_len=%d", apdu_len, null_len);
|
||||||
memset(&data2, 0, sizeof(data2));
|
memset(&data2, 0, sizeof(data2));
|
||||||
data2.messageText = &messageText2;
|
data2.messageText = &messageText2;
|
||||||
outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2);
|
test_len =
|
||||||
|
event_notify_decode_service_request(&buffer[0], apdu_len, &data2);
|
||||||
|
zassert_equal(
|
||||||
|
apdu_len, test_len, "apdu_len=%d test_len=%d", apdu_len, test_len);
|
||||||
|
|
||||||
zassert_equal(inLen, outLen, NULL);
|
|
||||||
verifyBaseEventState();
|
verifyBaseEventState();
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(
|
||||||
data.notificationParams.commandFailure.commandValue.binaryValue,
|
data.notificationParams.commandFailure.commandValue.binaryValue,
|
||||||
data2.notificationParams.commandFailure.commandValue.binaryValue,
|
data2.notificationParams.commandFailure.commandValue.binaryValue, NULL);
|
||||||
NULL);
|
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(
|
||||||
data.notificationParams.commandFailure.feedbackValue.binaryValue,
|
data.notificationParams.commandFailure.feedbackValue.binaryValue,
|
||||||
@@ -415,7 +379,8 @@ static void testEventEventState(void)
|
|||||||
|
|
||||||
zassert_true(
|
zassert_true(
|
||||||
bitstring_same(&data.notificationParams.commandFailure.statusFlags,
|
bitstring_same(&data.notificationParams.commandFailure.statusFlags,
|
||||||
&data2.notificationParams.commandFailure.statusFlags), NULL);
|
&data2.notificationParams.commandFailure.statusFlags),
|
||||||
|
NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** commandValue = unsigned
|
** commandValue = unsigned
|
||||||
@@ -437,13 +402,17 @@ static void testEventEventState(void)
|
|||||||
STATUS_FLAG_OUT_OF_SERVICE, false);
|
STATUS_FLAG_OUT_OF_SERVICE, false);
|
||||||
|
|
||||||
memset(buffer, 0, MAX_APDU);
|
memset(buffer, 0, MAX_APDU);
|
||||||
inLen = event_notify_encode_service_request(&buffer[0], &data);
|
null_len = event_notify_encode_service_request(NULL, &data);
|
||||||
|
apdu_len = event_notify_encode_service_request(&buffer[0], &data);
|
||||||
|
zassert_equal(
|
||||||
|
apdu_len, null_len, "apdu_len=%d null_len=%d", apdu_len, null_len);
|
||||||
|
|
||||||
memset(&data2, 0, sizeof(data2));
|
memset(&data2, 0, sizeof(data2));
|
||||||
data2.messageText = &messageText2;
|
data2.messageText = &messageText2;
|
||||||
outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2);
|
test_len =
|
||||||
|
event_notify_decode_service_request(&buffer[0], apdu_len, &data2);
|
||||||
|
|
||||||
zassert_equal(inLen, outLen, NULL);
|
zassert_equal(apdu_len, test_len, NULL);
|
||||||
verifyBaseEventState();
|
verifyBaseEventState();
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(
|
||||||
@@ -458,15 +427,9 @@ static void testEventEventState(void)
|
|||||||
|
|
||||||
zassert_true(
|
zassert_true(
|
||||||
bitstring_same(&data.notificationParams.commandFailure.statusFlags,
|
bitstring_same(&data.notificationParams.commandFailure.statusFlags,
|
||||||
&data2.notificationParams.commandFailure.statusFlags), NULL);
|
&data2.notificationParams.commandFailure.statusFlags),
|
||||||
|
NULL);
|
||||||
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/*
|
/*
|
||||||
** Event Type = EVENT_FLOATING_LIMIT
|
** Event Type = EVENT_FLOATING_LIMIT
|
||||||
*/
|
*/
|
||||||
@@ -487,37 +450,31 @@ static void testEventEventState(void)
|
|||||||
STATUS_FLAG_OUT_OF_SERVICE, false);
|
STATUS_FLAG_OUT_OF_SERVICE, false);
|
||||||
|
|
||||||
memset(buffer, 0, MAX_APDU);
|
memset(buffer, 0, MAX_APDU);
|
||||||
inLen = event_notify_encode_service_request(&buffer[0], &data);
|
null_len = event_notify_encode_service_request(NULL, &data);
|
||||||
|
apdu_len = event_notify_encode_service_request(&buffer[0], &data);
|
||||||
|
zassert_equal(
|
||||||
|
apdu_len, null_len, "apdu_len=%d null_len=%d", apdu_len, null_len);
|
||||||
memset(&data2, 0, sizeof(data2));
|
memset(&data2, 0, sizeof(data2));
|
||||||
data2.messageText = &messageText2;
|
data2.messageText = &messageText2;
|
||||||
outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2);
|
test_len =
|
||||||
|
event_notify_decode_service_request(&buffer[0], apdu_len, &data2);
|
||||||
zassert_equal(inLen, outLen, NULL);
|
zassert_equal(
|
||||||
|
apdu_len, test_len, "apdu_len=%d test_len=%d", apdu_len, test_len);
|
||||||
verifyBaseEventState();
|
verifyBaseEventState();
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(data.notificationParams.floatingLimit.referenceValue,
|
||||||
data.notificationParams.floatingLimit.referenceValue,
|
|
||||||
data2.notificationParams.floatingLimit.referenceValue, NULL);
|
data2.notificationParams.floatingLimit.referenceValue, NULL);
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(data.notificationParams.floatingLimit.setPointValue,
|
||||||
data.notificationParams.floatingLimit.setPointValue,
|
|
||||||
data2.notificationParams.floatingLimit.setPointValue, NULL);
|
data2.notificationParams.floatingLimit.setPointValue, NULL);
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(data.notificationParams.floatingLimit.errorLimit,
|
||||||
data.notificationParams.floatingLimit.errorLimit,
|
|
||||||
data2.notificationParams.floatingLimit.errorLimit, NULL);
|
data2.notificationParams.floatingLimit.errorLimit, NULL);
|
||||||
zassert_true(
|
zassert_true(
|
||||||
bitstring_same(&data.notificationParams.floatingLimit.statusFlags,
|
bitstring_same(&data.notificationParams.floatingLimit.statusFlags,
|
||||||
&data2.notificationParams.floatingLimit.statusFlags), NULL);
|
&data2.notificationParams.floatingLimit.statusFlags),
|
||||||
|
NULL);
|
||||||
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/*
|
/*
|
||||||
** Event Type = EVENT_OUT_OF_RANGE
|
** Event Type = EVENT_OUT_OF_RANGE
|
||||||
*/
|
*/
|
||||||
@@ -538,37 +495,31 @@ static void testEventEventState(void)
|
|||||||
STATUS_FLAG_OUT_OF_SERVICE, false);
|
STATUS_FLAG_OUT_OF_SERVICE, false);
|
||||||
|
|
||||||
memset(buffer, 0, MAX_APDU);
|
memset(buffer, 0, MAX_APDU);
|
||||||
inLen = event_notify_encode_service_request(&buffer[0], &data);
|
null_len = event_notify_encode_service_request(NULL, &data);
|
||||||
|
apdu_len = event_notify_encode_service_request(&buffer[0], &data);
|
||||||
|
zassert_equal(
|
||||||
|
apdu_len, null_len, "apdu_len=%d null_len=%d", apdu_len, null_len);
|
||||||
|
|
||||||
memset(&data2, 0, sizeof(data2));
|
memset(&data2, 0, sizeof(data2));
|
||||||
data2.messageText = &messageText2;
|
data2.messageText = &messageText2;
|
||||||
outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2);
|
test_len =
|
||||||
|
event_notify_decode_service_request(&buffer[0], apdu_len, &data2);
|
||||||
|
|
||||||
zassert_equal(inLen, outLen, NULL);
|
zassert_equal(apdu_len, test_len, NULL);
|
||||||
verifyBaseEventState();
|
verifyBaseEventState();
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(data.notificationParams.outOfRange.deadband,
|
||||||
data.notificationParams.outOfRange.deadband,
|
|
||||||
data2.notificationParams.outOfRange.deadband, NULL);
|
data2.notificationParams.outOfRange.deadband, NULL);
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(data.notificationParams.outOfRange.exceededLimit,
|
||||||
data.notificationParams.outOfRange.exceededLimit,
|
|
||||||
data2.notificationParams.outOfRange.exceededLimit, NULL);
|
data2.notificationParams.outOfRange.exceededLimit, NULL);
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(data.notificationParams.outOfRange.exceedingValue,
|
||||||
data.notificationParams.outOfRange.exceedingValue,
|
|
||||||
data2.notificationParams.outOfRange.exceedingValue, NULL);
|
data2.notificationParams.outOfRange.exceedingValue, NULL);
|
||||||
zassert_true(
|
zassert_true(bitstring_same(&data.notificationParams.outOfRange.statusFlags,
|
||||||
bitstring_same(&data.notificationParams.outOfRange.statusFlags,
|
&data2.notificationParams.outOfRange.statusFlags),
|
||||||
&data2.notificationParams.outOfRange.statusFlags), NULL);
|
NULL);
|
||||||
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/*
|
/*
|
||||||
** Event Type = EVENT_CHANGE_OF_LIFE_SAFETY
|
** Event Type = EVENT_CHANGE_OF_LIFE_SAFETY
|
||||||
*/
|
*/
|
||||||
@@ -591,38 +542,33 @@ static void testEventEventState(void)
|
|||||||
STATUS_FLAG_OUT_OF_SERVICE, false);
|
STATUS_FLAG_OUT_OF_SERVICE, false);
|
||||||
|
|
||||||
memset(buffer, 0, MAX_APDU);
|
memset(buffer, 0, MAX_APDU);
|
||||||
inLen = event_notify_encode_service_request(&buffer[0], &data);
|
null_len = event_notify_encode_service_request(NULL, &data);
|
||||||
|
apdu_len = event_notify_encode_service_request(&buffer[0], &data);
|
||||||
|
zassert_equal(
|
||||||
|
apdu_len, null_len, "apdu_len=%d null_len=%d", apdu_len, null_len);
|
||||||
|
|
||||||
memset(&data2, 0, sizeof(data2));
|
memset(&data2, 0, sizeof(data2));
|
||||||
data2.messageText = &messageText2;
|
data2.messageText = &messageText2;
|
||||||
outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2);
|
test_len =
|
||||||
|
event_notify_decode_service_request(&buffer[0], apdu_len, &data2);
|
||||||
|
|
||||||
zassert_equal(inLen, outLen, NULL);
|
zassert_equal(apdu_len, test_len, NULL);
|
||||||
verifyBaseEventState();
|
verifyBaseEventState();
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(data.notificationParams.changeOfLifeSafety.newMode,
|
||||||
data.notificationParams.changeOfLifeSafety.newMode,
|
|
||||||
data2.notificationParams.changeOfLifeSafety.newMode, NULL);
|
data2.notificationParams.changeOfLifeSafety.newMode, NULL);
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(data.notificationParams.changeOfLifeSafety.newState,
|
||||||
data.notificationParams.changeOfLifeSafety.newState,
|
|
||||||
data2.notificationParams.changeOfLifeSafety.newState, NULL);
|
data2.notificationParams.changeOfLifeSafety.newState, NULL);
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(data.notificationParams.changeOfLifeSafety.operationExpected,
|
||||||
data.notificationParams.changeOfLifeSafety.operationExpected,
|
|
||||||
data2.notificationParams.changeOfLifeSafety.operationExpected, NULL);
|
data2.notificationParams.changeOfLifeSafety.operationExpected, NULL);
|
||||||
|
|
||||||
zassert_true(
|
zassert_true(
|
||||||
bitstring_same(&data.notificationParams.changeOfLifeSafety.statusFlags,
|
bitstring_same(&data.notificationParams.changeOfLifeSafety.statusFlags,
|
||||||
&data2.notificationParams.changeOfLifeSafety.statusFlags), NULL);
|
&data2.notificationParams.changeOfLifeSafety.statusFlags),
|
||||||
|
NULL);
|
||||||
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/*
|
/*
|
||||||
** Event Type = EVENT_UNSIGNED_RANGE
|
** Event Type = EVENT_UNSIGNED_RANGE
|
||||||
*/
|
*/
|
||||||
@@ -642,34 +588,30 @@ static void testEventEventState(void)
|
|||||||
STATUS_FLAG_OUT_OF_SERVICE, false);
|
STATUS_FLAG_OUT_OF_SERVICE, false);
|
||||||
|
|
||||||
memset(buffer, 0, MAX_APDU);
|
memset(buffer, 0, MAX_APDU);
|
||||||
inLen = event_notify_encode_service_request(&buffer[0], &data);
|
null_len = event_notify_encode_service_request(NULL, &data);
|
||||||
|
apdu_len = event_notify_encode_service_request(&buffer[0], &data);
|
||||||
|
zassert_equal(
|
||||||
|
apdu_len, null_len, "apdu_len=%d null_len=%d", apdu_len, null_len);
|
||||||
|
|
||||||
memset(&data2, 0, sizeof(data2));
|
memset(&data2, 0, sizeof(data2));
|
||||||
data2.messageText = &messageText2;
|
data2.messageText = &messageText2;
|
||||||
outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2);
|
test_len =
|
||||||
|
event_notify_decode_service_request(&buffer[0], apdu_len, &data2);
|
||||||
|
|
||||||
zassert_equal(inLen, outLen, NULL);
|
zassert_equal(apdu_len, test_len, NULL);
|
||||||
verifyBaseEventState();
|
verifyBaseEventState();
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(data.notificationParams.unsignedRange.exceedingValue,
|
||||||
data.notificationParams.unsignedRange.exceedingValue,
|
|
||||||
data2.notificationParams.unsignedRange.exceedingValue, NULL);
|
data2.notificationParams.unsignedRange.exceedingValue, NULL);
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(data.notificationParams.unsignedRange.exceededLimit,
|
||||||
data.notificationParams.unsignedRange.exceededLimit,
|
|
||||||
data2.notificationParams.unsignedRange.exceededLimit, NULL);
|
data2.notificationParams.unsignedRange.exceededLimit, NULL);
|
||||||
|
|
||||||
zassert_true(
|
zassert_true(
|
||||||
bitstring_same(&data.notificationParams.unsignedRange.statusFlags,
|
bitstring_same(&data.notificationParams.unsignedRange.statusFlags,
|
||||||
&data2.notificationParams.unsignedRange.statusFlags), NULL);
|
&data2.notificationParams.unsignedRange.statusFlags),
|
||||||
|
NULL);
|
||||||
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/*
|
/*
|
||||||
** Event Type = EVENT_BUFFER_READY
|
** Event Type = EVENT_BUFFER_READY
|
||||||
*/
|
*/
|
||||||
@@ -689,62 +631,57 @@ static void testEventEventState(void)
|
|||||||
data.notificationParams.bufferReady.bufferProperty.arrayIndex = 0;
|
data.notificationParams.bufferReady.bufferProperty.arrayIndex = 0;
|
||||||
|
|
||||||
memset(buffer, 0, MAX_APDU);
|
memset(buffer, 0, MAX_APDU);
|
||||||
inLen = event_notify_encode_service_request(&buffer[0], &data);
|
null_len = event_notify_encode_service_request(NULL, &data);
|
||||||
|
apdu_len = event_notify_encode_service_request(&buffer[0], &data);
|
||||||
|
zassert_equal(
|
||||||
|
apdu_len, null_len, "apdu_len=%d null_len=%d", apdu_len, null_len);
|
||||||
|
|
||||||
memset(&data2, 0, sizeof(data2));
|
memset(&data2, 0, sizeof(data2));
|
||||||
data2.messageText = &messageText2;
|
data2.messageText = &messageText2;
|
||||||
outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2);
|
test_len =
|
||||||
|
event_notify_decode_service_request(&buffer[0], apdu_len, &data2);
|
||||||
|
|
||||||
zassert_equal(inLen, outLen, NULL);
|
zassert_equal(apdu_len, test_len, NULL);
|
||||||
verifyBaseEventState();
|
verifyBaseEventState();
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(data.notificationParams.bufferReady.previousNotification,
|
||||||
data.notificationParams.bufferReady.previousNotification,
|
|
||||||
data2.notificationParams.bufferReady.previousNotification, NULL);
|
data2.notificationParams.bufferReady.previousNotification, NULL);
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(data.notificationParams.bufferReady.currentNotification,
|
||||||
data.notificationParams.bufferReady.currentNotification,
|
|
||||||
data2.notificationParams.bufferReady.currentNotification, NULL);
|
data2.notificationParams.bufferReady.currentNotification, NULL);
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(data.notificationParams.bufferReady.bufferProperty
|
||||||
data.notificationParams.bufferReady.bufferProperty.deviceIdentifier
|
.deviceIdentifier.type,
|
||||||
.type,
|
|
||||||
data2.notificationParams.bufferReady.bufferProperty.deviceIdentifier
|
data2.notificationParams.bufferReady.bufferProperty.deviceIdentifier
|
||||||
.type, NULL);
|
|
||||||
|
|
||||||
zassert_equal(
|
|
||||||
data.notificationParams.bufferReady.bufferProperty.deviceIdentifier
|
|
||||||
.instance,
|
|
||||||
data2.notificationParams.bufferReady.bufferProperty.deviceIdentifier
|
|
||||||
.instance, NULL);
|
|
||||||
|
|
||||||
zassert_equal(
|
|
||||||
data.notificationParams.bufferReady.bufferProperty.objectIdentifier
|
|
||||||
.instance,
|
|
||||||
data2.notificationParams.bufferReady.bufferProperty.objectIdentifier
|
|
||||||
.instance, NULL);
|
|
||||||
|
|
||||||
zassert_equal(
|
|
||||||
data.notificationParams.bufferReady.bufferProperty.objectIdentifier
|
|
||||||
.type,
|
.type,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
zassert_equal(data.notificationParams.bufferReady.bufferProperty
|
||||||
|
.deviceIdentifier.instance,
|
||||||
|
data2.notificationParams.bufferReady.bufferProperty.deviceIdentifier
|
||||||
|
.instance,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
zassert_equal(data.notificationParams.bufferReady.bufferProperty
|
||||||
|
.objectIdentifier.instance,
|
||||||
data2.notificationParams.bufferReady.bufferProperty.objectIdentifier
|
data2.notificationParams.bufferReady.bufferProperty.objectIdentifier
|
||||||
.type, NULL);
|
.instance,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
zassert_equal(data.notificationParams.bufferReady.bufferProperty
|
||||||
|
.objectIdentifier.type,
|
||||||
|
data2.notificationParams.bufferReady.bufferProperty.objectIdentifier
|
||||||
|
.type,
|
||||||
|
NULL);
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(
|
||||||
data.notificationParams.bufferReady.bufferProperty.propertyIdentifier,
|
data.notificationParams.bufferReady.bufferProperty.propertyIdentifier,
|
||||||
data2.notificationParams.bufferReady.bufferProperty
|
data2.notificationParams.bufferReady.bufferProperty.propertyIdentifier,
|
||||||
.propertyIdentifier, NULL);
|
NULL);
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(data.notificationParams.bufferReady.bufferProperty.arrayIndex,
|
||||||
data.notificationParams.bufferReady.bufferProperty.arrayIndex,
|
|
||||||
data2.notificationParams.bufferReady.bufferProperty.arrayIndex, NULL);
|
data2.notificationParams.bufferReady.bufferProperty.arrayIndex, NULL);
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/**********************************************************************************/
|
|
||||||
/*
|
/*
|
||||||
** Event Type = EVENT_ACCESS_EVENT
|
** Event Type = EVENT_ACCESS_EVENT
|
||||||
*/
|
*/
|
||||||
@@ -757,15 +694,16 @@ static void testEventEventState(void)
|
|||||||
data.notificationParams.accessEvent.accessEventTime.tag =
|
data.notificationParams.accessEvent.accessEventTime.tag =
|
||||||
TIME_STAMP_SEQUENCE;
|
TIME_STAMP_SEQUENCE;
|
||||||
data.notificationParams.accessEvent.accessEventTime.value.sequenceNum = 17;
|
data.notificationParams.accessEvent.accessEventTime.value.sequenceNum = 17;
|
||||||
data.notificationParams.accessEvent.accessCredential.
|
data.notificationParams.accessEvent.accessCredential.deviceIdentifier
|
||||||
deviceIdentifier.instance = 1234;
|
.instance = 1234;
|
||||||
data.notificationParams.accessEvent.accessCredential.
|
data.notificationParams.accessEvent.accessCredential.deviceIdentifier.type =
|
||||||
deviceIdentifier.type = OBJECT_DEVICE;
|
OBJECT_DEVICE;
|
||||||
data.notificationParams.accessEvent.accessCredential.
|
data.notificationParams.accessEvent.accessCredential.objectIdentifier
|
||||||
objectIdentifier.instance = 17;
|
.instance = 17;
|
||||||
data.notificationParams.accessEvent.accessCredential.
|
data.notificationParams.accessEvent.accessCredential.objectIdentifier.type =
|
||||||
objectIdentifier.type = OBJECT_ACCESS_POINT;
|
OBJECT_ACCESS_POINT;
|
||||||
data.notificationParams.accessEvent.authenticationFactor.format_type = AUTHENTICATION_FACTOR_MAX; // omit authenticationFactor
|
data.notificationParams.accessEvent.authenticationFactor.format_type =
|
||||||
|
AUTHENTICATION_FACTOR_MAX; // omit authenticationFactor
|
||||||
|
|
||||||
bitstring_init(&data.notificationParams.accessEvent.statusFlags);
|
bitstring_init(&data.notificationParams.accessEvent.statusFlags);
|
||||||
bitstring_set_bit(&data.notificationParams.accessEvent.statusFlags,
|
bitstring_set_bit(&data.notificationParams.accessEvent.statusFlags,
|
||||||
@@ -778,60 +716,61 @@ static void testEventEventState(void)
|
|||||||
STATUS_FLAG_OUT_OF_SERVICE, false);
|
STATUS_FLAG_OUT_OF_SERVICE, false);
|
||||||
|
|
||||||
memset(buffer, 0, MAX_APDU);
|
memset(buffer, 0, MAX_APDU);
|
||||||
inLen = event_notify_encode_service_request(&buffer[0], &data);
|
null_len = event_notify_encode_service_request(NULL, &data);
|
||||||
|
apdu_len = event_notify_encode_service_request(&buffer[0], &data);
|
||||||
|
zassert_equal(
|
||||||
|
apdu_len, null_len, "apdu_len=%d null_len=%d", apdu_len, null_len);
|
||||||
|
|
||||||
memset(&data2, 0, sizeof(data2));
|
memset(&data2, 0, sizeof(data2));
|
||||||
data2.messageText = &messageText2;
|
data2.messageText = &messageText2;
|
||||||
outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2);
|
test_len =
|
||||||
|
event_notify_decode_service_request(&buffer[0], apdu_len, &data2);
|
||||||
|
|
||||||
zassert_equal(inLen, outLen, NULL);
|
zassert_equal(apdu_len, test_len, NULL);
|
||||||
verifyBaseEventState();
|
verifyBaseEventState();
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(data.notificationParams.accessEvent.accessEvent,
|
||||||
data.notificationParams.accessEvent.accessEvent,
|
|
||||||
data2.notificationParams.accessEvent.accessEvent, NULL);
|
data2.notificationParams.accessEvent.accessEvent, NULL);
|
||||||
|
|
||||||
zassert_true(
|
zassert_true(
|
||||||
bitstring_same(&data.notificationParams.accessEvent.statusFlags,
|
bitstring_same(&data.notificationParams.accessEvent.statusFlags,
|
||||||
&data2.notificationParams.accessEvent.statusFlags), NULL);
|
&data2.notificationParams.accessEvent.statusFlags),
|
||||||
|
NULL);
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(data.notificationParams.accessEvent.accessEventTag,
|
||||||
data.notificationParams.accessEvent.accessEventTag,
|
|
||||||
data2.notificationParams.accessEvent.accessEventTag, NULL);
|
data2.notificationParams.accessEvent.accessEventTag, NULL);
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(data.notificationParams.accessEvent.accessEventTime.tag,
|
||||||
data.notificationParams.accessEvent.accessEventTime.tag,
|
|
||||||
data2.notificationParams.accessEvent.accessEventTime.tag, NULL);
|
data2.notificationParams.accessEvent.accessEventTime.tag, NULL);
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(
|
||||||
data.notificationParams.accessEvent.accessEventTime.
|
data.notificationParams.accessEvent.accessEventTime.value.sequenceNum,
|
||||||
value.sequenceNum,
|
data2.notificationParams.accessEvent.accessEventTime.value.sequenceNum,
|
||||||
data2.notificationParams.accessEvent.accessEventTime.
|
NULL);
|
||||||
value.sequenceNum, NULL);
|
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(data.notificationParams.accessEvent.accessCredential
|
||||||
data.notificationParams.accessEvent.accessCredential.
|
.deviceIdentifier.instance,
|
||||||
deviceIdentifier.instance,
|
data2.notificationParams.accessEvent.accessCredential.deviceIdentifier
|
||||||
data2.notificationParams.accessEvent.accessCredential.
|
.instance,
|
||||||
deviceIdentifier.instance, NULL);
|
NULL);
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(data.notificationParams.accessEvent.accessCredential
|
||||||
data.notificationParams.accessEvent.accessCredential.
|
.deviceIdentifier.type,
|
||||||
deviceIdentifier.type,
|
data2.notificationParams.accessEvent.accessCredential.deviceIdentifier
|
||||||
data2.notificationParams.accessEvent.accessCredential.
|
.type,
|
||||||
deviceIdentifier.type, NULL);
|
NULL);
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(data.notificationParams.accessEvent.accessCredential
|
||||||
data.notificationParams.accessEvent.accessCredential.
|
.objectIdentifier.instance,
|
||||||
objectIdentifier.instance,
|
data2.notificationParams.accessEvent.accessCredential.objectIdentifier
|
||||||
data2.notificationParams.accessEvent.accessCredential.
|
.instance,
|
||||||
objectIdentifier.instance, NULL);
|
NULL);
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(data.notificationParams.accessEvent.accessCredential
|
||||||
data.notificationParams.accessEvent.accessCredential.
|
.objectIdentifier.type,
|
||||||
objectIdentifier.type,
|
data2.notificationParams.accessEvent.accessCredential.objectIdentifier
|
||||||
data2.notificationParams.accessEvent.accessCredential.
|
.type,
|
||||||
objectIdentifier.type, NULL);
|
NULL);
|
||||||
|
|
||||||
// OPTIONAL authenticationFactor included
|
// OPTIONAL authenticationFactor included
|
||||||
data.eventType = EVENT_ACCESS_EVENT;
|
data.eventType = EVENT_ACCESS_EVENT;
|
||||||
@@ -841,22 +780,22 @@ static void testEventEventState(void)
|
|||||||
data.notificationParams.accessEvent.accessEventTime.tag =
|
data.notificationParams.accessEvent.accessEventTime.tag =
|
||||||
TIME_STAMP_SEQUENCE;
|
TIME_STAMP_SEQUENCE;
|
||||||
data.notificationParams.accessEvent.accessEventTime.value.sequenceNum = 17;
|
data.notificationParams.accessEvent.accessEventTime.value.sequenceNum = 17;
|
||||||
data.notificationParams.accessEvent.accessCredential.
|
data.notificationParams.accessEvent.accessCredential.deviceIdentifier
|
||||||
deviceIdentifier.instance = 1234;
|
.instance = 1234;
|
||||||
data.notificationParams.accessEvent.accessCredential.
|
data.notificationParams.accessEvent.accessCredential.deviceIdentifier.type =
|
||||||
deviceIdentifier.type = OBJECT_DEVICE;
|
OBJECT_DEVICE;
|
||||||
data.notificationParams.accessEvent.accessCredential.
|
data.notificationParams.accessEvent.accessCredential.objectIdentifier
|
||||||
objectIdentifier.instance = 17;
|
.instance = 17;
|
||||||
data.notificationParams.accessEvent.accessCredential.
|
data.notificationParams.accessEvent.accessCredential.objectIdentifier.type =
|
||||||
objectIdentifier.type = OBJECT_ACCESS_POINT;
|
OBJECT_ACCESS_POINT;
|
||||||
data.notificationParams.accessEvent.authenticationFactor.format_type =
|
data.notificationParams.accessEvent.authenticationFactor.format_type =
|
||||||
AUTHENTICATION_FACTOR_SIMPLE_NUMBER16;
|
AUTHENTICATION_FACTOR_SIMPLE_NUMBER16;
|
||||||
data.notificationParams.accessEvent.authenticationFactor.format_class =
|
data.notificationParams.accessEvent.authenticationFactor.format_class = 215;
|
||||||
215;
|
|
||||||
uint8_t octetstringValue[2] = { 0x00, 0x10 };
|
uint8_t octetstringValue[2] = { 0x00, 0x10 };
|
||||||
|
|
||||||
octetstring_init(&data.notificationParams.accessEvent.
|
octetstring_init(
|
||||||
authenticationFactor.value, octetstringValue, 2);
|
&data.notificationParams.accessEvent.authenticationFactor.value,
|
||||||
|
octetstringValue, 2);
|
||||||
|
|
||||||
bitstring_init(&data.notificationParams.accessEvent.statusFlags);
|
bitstring_init(&data.notificationParams.accessEvent.statusFlags);
|
||||||
bitstring_set_bit(&data.notificationParams.accessEvent.statusFlags,
|
bitstring_set_bit(&data.notificationParams.accessEvent.statusFlags,
|
||||||
@@ -869,60 +808,61 @@ static void testEventEventState(void)
|
|||||||
STATUS_FLAG_OUT_OF_SERVICE, false);
|
STATUS_FLAG_OUT_OF_SERVICE, false);
|
||||||
|
|
||||||
memset(buffer, 0, MAX_APDU);
|
memset(buffer, 0, MAX_APDU);
|
||||||
inLen = event_notify_encode_service_request(&buffer[0], &data);
|
null_len = event_notify_encode_service_request(NULL, &data);
|
||||||
|
apdu_len = event_notify_encode_service_request(&buffer[0], &data);
|
||||||
|
zassert_equal(
|
||||||
|
apdu_len, null_len, "apdu_len=%d null_len=%d", apdu_len, null_len);
|
||||||
|
|
||||||
memset(&data2, 0, sizeof(data2));
|
memset(&data2, 0, sizeof(data2));
|
||||||
data2.messageText = &messageText2;
|
data2.messageText = &messageText2;
|
||||||
outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2);
|
test_len =
|
||||||
|
event_notify_decode_service_request(&buffer[0], apdu_len, &data2);
|
||||||
|
|
||||||
zassert_equal(inLen, outLen, NULL);
|
zassert_equal(apdu_len, test_len, NULL);
|
||||||
verifyBaseEventState();
|
verifyBaseEventState();
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(data.notificationParams.accessEvent.accessEvent,
|
||||||
data.notificationParams.accessEvent.accessEvent,
|
|
||||||
data2.notificationParams.accessEvent.accessEvent, NULL);
|
data2.notificationParams.accessEvent.accessEvent, NULL);
|
||||||
|
|
||||||
zassert_true(
|
zassert_true(
|
||||||
bitstring_same(&data.notificationParams.accessEvent.statusFlags,
|
bitstring_same(&data.notificationParams.accessEvent.statusFlags,
|
||||||
&data2.notificationParams.accessEvent.statusFlags), NULL);
|
&data2.notificationParams.accessEvent.statusFlags),
|
||||||
|
NULL);
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(data.notificationParams.accessEvent.accessEventTag,
|
||||||
data.notificationParams.accessEvent.accessEventTag,
|
|
||||||
data2.notificationParams.accessEvent.accessEventTag, NULL);
|
data2.notificationParams.accessEvent.accessEventTag, NULL);
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(data.notificationParams.accessEvent.accessEventTime.tag,
|
||||||
data.notificationParams.accessEvent.accessEventTime.tag,
|
|
||||||
data2.notificationParams.accessEvent.accessEventTime.tag, NULL);
|
data2.notificationParams.accessEvent.accessEventTime.tag, NULL);
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(
|
||||||
data.notificationParams.accessEvent.accessEventTime.
|
data.notificationParams.accessEvent.accessEventTime.value.sequenceNum,
|
||||||
value.sequenceNum,
|
data2.notificationParams.accessEvent.accessEventTime.value.sequenceNum,
|
||||||
data2.notificationParams.accessEvent.accessEventTime.
|
NULL);
|
||||||
value.sequenceNum, NULL);
|
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(data.notificationParams.accessEvent.accessCredential
|
||||||
data.notificationParams.accessEvent.accessCredential.
|
.deviceIdentifier.instance,
|
||||||
deviceIdentifier.instance,
|
data2.notificationParams.accessEvent.accessCredential.deviceIdentifier
|
||||||
data2.notificationParams.accessEvent.accessCredential.
|
.instance,
|
||||||
deviceIdentifier.instance, NULL);
|
NULL);
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(data.notificationParams.accessEvent.accessCredential
|
||||||
data.notificationParams.accessEvent.accessCredential.
|
.deviceIdentifier.type,
|
||||||
deviceIdentifier.type,
|
data2.notificationParams.accessEvent.accessCredential.deviceIdentifier
|
||||||
data2.notificationParams.accessEvent.accessCredential.
|
.type,
|
||||||
deviceIdentifier.type, NULL);
|
NULL);
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(data.notificationParams.accessEvent.accessCredential
|
||||||
data.notificationParams.accessEvent.accessCredential.
|
.objectIdentifier.instance,
|
||||||
objectIdentifier.instance,
|
data2.notificationParams.accessEvent.accessCredential.objectIdentifier
|
||||||
data2.notificationParams.accessEvent.accessCredential.
|
.instance,
|
||||||
objectIdentifier.instance, NULL);
|
NULL);
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(data.notificationParams.accessEvent.accessCredential
|
||||||
data.notificationParams.accessEvent.accessCredential.
|
.objectIdentifier.type,
|
||||||
objectIdentifier.type,
|
data2.notificationParams.accessEvent.accessCredential.objectIdentifier
|
||||||
data2.notificationParams.accessEvent.accessCredential.
|
.type,
|
||||||
objectIdentifier.type, NULL);
|
NULL);
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(
|
||||||
data.notificationParams.accessEvent.authenticationFactor.format_type,
|
data.notificationParams.accessEvent.authenticationFactor.format_type,
|
||||||
@@ -930,14 +870,13 @@ static void testEventEventState(void)
|
|||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
zassert_equal(
|
zassert_equal(
|
||||||
data.notificationParams.accessEvent.
|
data.notificationParams.accessEvent.authenticationFactor.format_class,
|
||||||
authenticationFactor.format_class,
|
data2.notificationParams.accessEvent.authenticationFactor.format_class,
|
||||||
data2.notificationParams.accessEvent.
|
NULL);
|
||||||
authenticationFactor.format_class, NULL);
|
|
||||||
|
|
||||||
zassert_true(
|
zassert_true(
|
||||||
octetstring_value_same(&data.notificationParams.
|
octetstring_value_same(
|
||||||
accessEvent.authenticationFactor.value,
|
&data.notificationParams.accessEvent.authenticationFactor.value,
|
||||||
&data2.notificationParams.accessEvent.authenticationFactor.value),
|
&data2.notificationParams.accessEvent.authenticationFactor.value),
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
@@ -945,15 +884,12 @@ static void testEventEventState(void)
|
|||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#if defined(CONFIG_ZTEST_NEW_API)
|
#if defined(CONFIG_ZTEST_NEW_API)
|
||||||
ZTEST_SUITE(event_tests, NULL, NULL, NULL, NULL, NULL);
|
ZTEST_SUITE(event_tests, NULL, NULL, NULL, NULL, NULL);
|
||||||
#else
|
#else
|
||||||
void test_main(void)
|
void test_main(void)
|
||||||
{
|
{
|
||||||
ztest_test_suite(event_tests,
|
ztest_test_suite(event_tests, ztest_unit_test(testEventEventState));
|
||||||
ztest_unit_test(testEventEventState)
|
|
||||||
);
|
|
||||||
|
|
||||||
ztest_run_test_suite(event_tests);
|
ztest_run_test_suite(event_tests);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,30 +20,39 @@
|
|||||||
* @brief Test
|
* @brief Test
|
||||||
*/
|
*/
|
||||||
static int getevent_decode_apdu(uint8_t *apdu,
|
static int getevent_decode_apdu(uint8_t *apdu,
|
||||||
unsigned apdu_len,
|
unsigned apdu_size,
|
||||||
uint8_t *invoke_id,
|
uint8_t *invoke_id,
|
||||||
BACNET_OBJECT_ID *lastReceivedObjectIdentifier)
|
BACNET_OBJECT_ID *lastReceivedObjectIdentifier)
|
||||||
{
|
{
|
||||||
int len = 0;
|
int len = 0;
|
||||||
unsigned offset = 0;
|
unsigned apdu_len = 0;
|
||||||
|
|
||||||
if (!apdu)
|
if (!apdu) {
|
||||||
return -1;
|
return BACNET_STATUS_ERROR;
|
||||||
/* optional checking - most likely was already done prior to this call */
|
}
|
||||||
if (apdu[0] != PDU_TYPE_CONFIRMED_SERVICE_REQUEST)
|
if (apdu_size > 4) {
|
||||||
return -1;
|
if (apdu[0] != PDU_TYPE_CONFIRMED_SERVICE_REQUEST) {
|
||||||
|
return BACNET_STATUS_ERROR;
|
||||||
|
}
|
||||||
/* apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU); */
|
/* apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU); */
|
||||||
*invoke_id = apdu[2]; /* invoke id - filled in by net layer */
|
*invoke_id = apdu[2]; /* invoke id - filled in by net layer */
|
||||||
if (apdu[3] != SERVICE_CONFIRMED_GET_EVENT_INFORMATION)
|
if (apdu[3] != SERVICE_CONFIRMED_GET_EVENT_INFORMATION) {
|
||||||
return -1;
|
return BACNET_STATUS_ERROR;
|
||||||
offset = 4;
|
}
|
||||||
|
apdu_len = 4;
|
||||||
if (apdu_len > offset) {
|
|
||||||
len = getevent_decode_service_request(
|
|
||||||
&apdu[offset], apdu_len - offset, lastReceivedObjectIdentifier);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return len;
|
if (apdu_size > apdu_len) {
|
||||||
|
len = getevent_decode_service_request(
|
||||||
|
&apdu[apdu_len], apdu_size - apdu_len, lastReceivedObjectIdentifier);
|
||||||
|
if (len > 0) {
|
||||||
|
apdu_len += len;
|
||||||
|
} else {
|
||||||
|
apdu_len = len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return apdu_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int getevent_ack_decode_apdu(uint8_t *apdu,
|
static int getevent_ack_decode_apdu(uint8_t *apdu,
|
||||||
@@ -150,8 +159,7 @@ static void testGetEventInformation(void)
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
uint8_t apdu[480] = { 0 };
|
uint8_t apdu[480] = { 0 };
|
||||||
int len = 0;
|
int apdu_len, test_len, null_len;
|
||||||
int apdu_len = 0;
|
|
||||||
uint8_t invoke_id = 128;
|
uint8_t invoke_id = 128;
|
||||||
uint8_t test_invoke_id = 0;
|
uint8_t test_invoke_id = 0;
|
||||||
BACNET_OBJECT_ID lastReceivedObjectIdentifier;
|
BACNET_OBJECT_ID lastReceivedObjectIdentifier;
|
||||||
@@ -159,14 +167,18 @@ static void testGetEventInformation(void)
|
|||||||
|
|
||||||
lastReceivedObjectIdentifier.type = OBJECT_BINARY_INPUT;
|
lastReceivedObjectIdentifier.type = OBJECT_BINARY_INPUT;
|
||||||
lastReceivedObjectIdentifier.instance = 12345;
|
lastReceivedObjectIdentifier.instance = 12345;
|
||||||
len = getevent_encode_apdu(
|
null_len = getevent_encode_apdu(
|
||||||
|
NULL, invoke_id, &lastReceivedObjectIdentifier);
|
||||||
|
apdu_len = getevent_encode_apdu(
|
||||||
&apdu[0], invoke_id, &lastReceivedObjectIdentifier);
|
&apdu[0], invoke_id, &lastReceivedObjectIdentifier);
|
||||||
zassert_not_equal(len, 0, NULL);
|
zassert_equal(apdu_len, null_len, NULL);
|
||||||
apdu_len = len;
|
zassert_not_equal(apdu_len, 0, NULL);
|
||||||
|
|
||||||
len = getevent_decode_apdu(&apdu[0], apdu_len, &test_invoke_id,
|
test_len = getevent_decode_apdu(&apdu[0], apdu_len, &test_invoke_id,
|
||||||
&test_lastReceivedObjectIdentifier);
|
&test_lastReceivedObjectIdentifier);
|
||||||
zassert_not_equal(len, -1, NULL);
|
zassert_equal(
|
||||||
|
apdu_len, test_len, "apdu_len=%d test_len=%d", apdu_len, test_len);
|
||||||
|
zassert_not_equal(test_len, -1, NULL);
|
||||||
zassert_equal(test_invoke_id, invoke_id, NULL);
|
zassert_equal(test_invoke_id, invoke_id, NULL);
|
||||||
zassert_equal(
|
zassert_equal(
|
||||||
test_lastReceivedObjectIdentifier.type,
|
test_lastReceivedObjectIdentifier.type,
|
||||||
|
|||||||
@@ -27,9 +27,17 @@ static void test_ListElement(void)
|
|||||||
|
|
||||||
list_element.application_data = NULL;
|
list_element.application_data = NULL;
|
||||||
list_element.application_data_len = 0;
|
list_element.application_data_len = 0;
|
||||||
|
/* NULL test - number of bytes which would have been written to the APDU */
|
||||||
null_len = list_element_encode_service_request(NULL, &list_element);
|
null_len = list_element_encode_service_request(NULL, &list_element);
|
||||||
apdu_len = list_element_encode_service_request(apdu, &list_element);
|
apdu_len = list_element_encode_service_request(apdu, &list_element);
|
||||||
zassert_equal(apdu_len, null_len, NULL);
|
zassert_equal(apdu_len, null_len, NULL);
|
||||||
|
apdu_len =
|
||||||
|
list_element_service_request_encode(apdu, null_len, &list_element);
|
||||||
|
zassert_equal(apdu_len, null_len, NULL);
|
||||||
|
/* negative test - too short */
|
||||||
|
null_len = list_element_service_request_encode(NULL, 0, &list_element);
|
||||||
|
zassert_equal(0, null_len, NULL);
|
||||||
|
/* decoder test */
|
||||||
test_len =
|
test_len =
|
||||||
list_element_decode_service_request(apdu, apdu_len, &test_list_element);
|
list_element_decode_service_request(apdu, apdu_len, &test_list_element);
|
||||||
zassert_equal(apdu_len, test_len, NULL);
|
zassert_equal(apdu_len, test_len, NULL);
|
||||||
|
|||||||
+20
-18
@@ -25,13 +25,12 @@ ZTEST(lso_tests, testLSO)
|
|||||||
static void testLSO(void)
|
static void testLSO(void)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
uint8_t apdu[1000];
|
uint8_t apdu[1000] = { 0 };
|
||||||
int len;
|
uint8_t invoke_id = 100;
|
||||||
|
int apdu_len = 0, null_len = 0, test_len = 0;
|
||||||
|
|
||||||
BACNET_LSO_DATA data;
|
BACNET_LSO_DATA data = { 0 };
|
||||||
BACNET_LSO_DATA rxdata;
|
BACNET_LSO_DATA test_data = { 0 };
|
||||||
|
|
||||||
memset(&rxdata, 0, sizeof(rxdata));
|
|
||||||
|
|
||||||
characterstring_init_ansi(&data.requestingSrc, "foobar");
|
characterstring_init_ansi(&data.requestingSrc, "foobar");
|
||||||
data.operation = LIFE_SAFETY_OP_RESET;
|
data.operation = LIFE_SAFETY_OP_RESET;
|
||||||
@@ -39,19 +38,22 @@ static void testLSO(void)
|
|||||||
data.use_target = true;
|
data.use_target = true;
|
||||||
data.targetObject.instance = 0x1000;
|
data.targetObject.instance = 0x1000;
|
||||||
data.targetObject.type = OBJECT_BINARY_INPUT;
|
data.targetObject.type = OBJECT_BINARY_INPUT;
|
||||||
|
/* encode/decode */
|
||||||
len = lso_encode_apdu(apdu, 100, &data);
|
null_len = lso_encode_apdu(NULL, invoke_id, &data);
|
||||||
|
apdu_len = lso_encode_apdu(apdu, invoke_id, &data);
|
||||||
lso_decode_service_request(&apdu[4], len, &rxdata);
|
|
||||||
|
|
||||||
zassert_equal(data.operation, rxdata.operation, NULL);
|
|
||||||
zassert_equal(data.processId, rxdata.processId, NULL);
|
|
||||||
zassert_equal(data.use_target, rxdata.use_target, NULL);
|
|
||||||
zassert_equal(data.targetObject.instance, rxdata.targetObject.instance, NULL);
|
|
||||||
zassert_equal(data.targetObject.type, rxdata.targetObject.type, NULL);
|
|
||||||
zassert_equal(
|
zassert_equal(
|
||||||
memcmp(data.requestingSrc.value, rxdata.requestingSrc.value,
|
apdu_len, null_len, "apdu_len=%d null_len=%d", apdu_len, null_len);
|
||||||
rxdata.requestingSrc.length), 0, NULL);
|
test_len = lso_decode_service_request(&apdu[4], apdu_len, &test_data);
|
||||||
|
zassert_true(test_len > 0, "test_len=%d", test_len);
|
||||||
|
/* check the values decoded */
|
||||||
|
zassert_equal(data.operation, test_data.operation, NULL);
|
||||||
|
zassert_equal(data.processId, test_data.processId, NULL);
|
||||||
|
zassert_equal(data.use_target, test_data.use_target, NULL);
|
||||||
|
zassert_equal(data.targetObject.instance, test_data.targetObject.instance, NULL);
|
||||||
|
zassert_equal(data.targetObject.type, test_data.targetObject.type, NULL);
|
||||||
|
zassert_equal(
|
||||||
|
memcmp(data.requestingSrc.value, test_data.requestingSrc.value,
|
||||||
|
test_data.requestingSrc.length), 0, NULL);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
|
|||||||
@@ -30,21 +30,21 @@ static int rd_decode_apdu(uint8_t *apdu,
|
|||||||
int apdu_len = 0;
|
int apdu_len = 0;
|
||||||
|
|
||||||
if (!apdu) {
|
if (!apdu) {
|
||||||
return -1;
|
return BACNET_STATUS_ERROR;
|
||||||
}
|
}
|
||||||
if (apdu_size <= 4) {
|
if (apdu_size <= 4) {
|
||||||
return -1;
|
return BACNET_STATUS_ERROR;
|
||||||
}
|
}
|
||||||
/* optional checking - most likely was already done prior to this call */
|
/* optional checking - most likely was already done prior to this call */
|
||||||
if (apdu[0] != PDU_TYPE_CONFIRMED_SERVICE_REQUEST) {
|
if (apdu[0] != PDU_TYPE_CONFIRMED_SERVICE_REQUEST) {
|
||||||
return -1;
|
return BACNET_STATUS_ERROR;
|
||||||
}
|
}
|
||||||
/* apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU); */
|
/* apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU); */
|
||||||
if (invoke_id) {
|
if (invoke_id) {
|
||||||
*invoke_id = apdu[2]; /* invoke id - filled in by net layer */
|
*invoke_id = apdu[2]; /* invoke id - filled in by net layer */
|
||||||
}
|
}
|
||||||
if (apdu[3] != SERVICE_CONFIRMED_REINITIALIZE_DEVICE) {
|
if (apdu[3] != SERVICE_CONFIRMED_REINITIALIZE_DEVICE) {
|
||||||
return -1;
|
return BACNET_STATUS_ERROR;
|
||||||
}
|
}
|
||||||
apdu_len = 4;
|
apdu_len = 4;
|
||||||
if (apdu_len < apdu_size) {
|
if (apdu_len < apdu_size) {
|
||||||
|
|||||||
+91
-49
@@ -21,55 +21,77 @@
|
|||||||
* @brief Test
|
* @brief Test
|
||||||
*/
|
*/
|
||||||
static int rp_decode_apdu(uint8_t *apdu,
|
static int rp_decode_apdu(uint8_t *apdu,
|
||||||
unsigned apdu_len,
|
unsigned apdu_size,
|
||||||
uint8_t *invoke_id,
|
uint8_t *invoke_id,
|
||||||
BACNET_READ_PROPERTY_DATA *rpdata)
|
BACNET_READ_PROPERTY_DATA *rpdata)
|
||||||
{
|
{
|
||||||
int len = 0;
|
int len = 0;
|
||||||
unsigned offset = 0;
|
unsigned apdu_len = 0;
|
||||||
|
|
||||||
if (!apdu)
|
if (!apdu) {
|
||||||
return -1;
|
return BACNET_STATUS_ERROR;
|
||||||
|
}
|
||||||
|
if (apdu_size <= 4) {
|
||||||
|
return BACNET_STATUS_ERROR;
|
||||||
|
}
|
||||||
/* optional checking - most likely was already done prior to this call */
|
/* optional checking - most likely was already done prior to this call */
|
||||||
if (apdu[0] != PDU_TYPE_CONFIRMED_SERVICE_REQUEST)
|
if (apdu[0] != PDU_TYPE_CONFIRMED_SERVICE_REQUEST) {
|
||||||
return -1;
|
return BACNET_STATUS_ERROR;
|
||||||
|
}
|
||||||
/* apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU); */
|
/* apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU); */
|
||||||
*invoke_id = apdu[2]; /* invoke id - filled in by net layer */
|
*invoke_id = apdu[2]; /* invoke id - filled in by net layer */
|
||||||
if (apdu[3] != SERVICE_CONFIRMED_READ_PROPERTY)
|
if (apdu[3] != SERVICE_CONFIRMED_READ_PROPERTY) {
|
||||||
return -1;
|
return BACNET_STATUS_ERROR;
|
||||||
offset = 4;
|
}
|
||||||
|
apdu_len = 4;
|
||||||
|
|
||||||
if (apdu_len > offset) {
|
if (apdu_size > apdu_len) {
|
||||||
len =
|
len = rp_decode_service_request(
|
||||||
rp_decode_service_request(&apdu[offset], apdu_len - offset, rpdata);
|
&apdu[apdu_len], apdu_size - apdu_len, rpdata);
|
||||||
|
if (len > 0) {
|
||||||
|
apdu_len += len;
|
||||||
|
} else {
|
||||||
|
apdu_len = len;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return len;
|
return apdu_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rp_ack_decode_apdu(uint8_t *apdu,
|
static int rp_ack_decode_apdu(uint8_t *apdu,
|
||||||
int apdu_len, /* total length of the apdu */
|
int apdu_size,
|
||||||
uint8_t *invoke_id,
|
uint8_t *invoke_id,
|
||||||
BACNET_READ_PROPERTY_DATA *rpdata)
|
BACNET_READ_PROPERTY_DATA *rpdata)
|
||||||
{
|
{
|
||||||
int len = 0;
|
int len = 0;
|
||||||
int offset = 0;
|
int apdu_len = 0;
|
||||||
|
|
||||||
if (!apdu)
|
if (!apdu) {
|
||||||
return -1;
|
return BACNET_STATUS_ERROR;
|
||||||
|
}
|
||||||
|
if (apdu_size <= 3) {
|
||||||
|
return BACNET_STATUS_ERROR;
|
||||||
|
}
|
||||||
/* optional checking - most likely was already done prior to this call */
|
/* optional checking - most likely was already done prior to this call */
|
||||||
if (apdu[0] != PDU_TYPE_COMPLEX_ACK)
|
if (apdu[0] != PDU_TYPE_COMPLEX_ACK) {
|
||||||
return -1;
|
return BACNET_STATUS_ERROR;
|
||||||
|
}
|
||||||
*invoke_id = apdu[1];
|
*invoke_id = apdu[1];
|
||||||
if (apdu[2] != SERVICE_CONFIRMED_READ_PROPERTY)
|
if (apdu[2] != SERVICE_CONFIRMED_READ_PROPERTY) {
|
||||||
return -1;
|
return BACNET_STATUS_ERROR;
|
||||||
offset = 3;
|
}
|
||||||
if (apdu_len > offset) {
|
apdu_len = 3;
|
||||||
|
if (apdu_size > apdu_len) {
|
||||||
len = rp_ack_decode_service_request(
|
len = rp_ack_decode_service_request(
|
||||||
&apdu[offset], apdu_len - offset, rpdata);
|
&apdu[apdu_len], apdu_size - apdu_len, rpdata);
|
||||||
|
if (len > 0) {
|
||||||
|
apdu_len += len;
|
||||||
|
} else {
|
||||||
|
apdu_len = len;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return len;
|
return apdu_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_ZTEST_NEW_API)
|
#if defined(CONFIG_ZTEST_NEW_API)
|
||||||
@@ -80,12 +102,11 @@ static void testReadPropertyAck(void)
|
|||||||
{
|
{
|
||||||
uint8_t apdu[480] = { 0 };
|
uint8_t apdu[480] = { 0 };
|
||||||
uint8_t apdu2[480] = { 0 };
|
uint8_t apdu2[480] = { 0 };
|
||||||
int len = 0;
|
int apdu_len = 0, test_len = 0, null_len = 0;
|
||||||
int apdu_len = 0;
|
|
||||||
uint8_t invoke_id = 1;
|
uint8_t invoke_id = 1;
|
||||||
uint8_t test_invoke_id = 0;
|
uint8_t test_invoke_id = 0;
|
||||||
BACNET_READ_PROPERTY_DATA rpdata;
|
BACNET_READ_PROPERTY_DATA rpdata = { 0 };
|
||||||
BACNET_READ_PROPERTY_DATA test_data;
|
BACNET_READ_PROPERTY_DATA test_data = { 0 };
|
||||||
BACNET_OBJECT_TYPE object_type = OBJECT_DEVICE;
|
BACNET_OBJECT_TYPE object_type = OBJECT_DEVICE;
|
||||||
uint32_t object_instance = 0;
|
uint32_t object_instance = 0;
|
||||||
BACNET_OBJECT_TYPE object = 0;
|
BACNET_OBJECT_TYPE object = 0;
|
||||||
@@ -99,13 +120,16 @@ static void testReadPropertyAck(void)
|
|||||||
&apdu2[0], rpdata.object_type, rpdata.object_instance);
|
&apdu2[0], rpdata.object_type, rpdata.object_instance);
|
||||||
rpdata.application_data = &apdu2[0];
|
rpdata.application_data = &apdu2[0];
|
||||||
|
|
||||||
len = rp_ack_encode_apdu(&apdu[0], invoke_id, &rpdata);
|
null_len = rp_ack_encode_apdu(NULL, invoke_id, &rpdata);
|
||||||
zassert_not_equal(len, 0, NULL);
|
apdu_len = rp_ack_encode_apdu(&apdu[0], invoke_id, &rpdata);
|
||||||
zassert_not_equal(len, -1, NULL);
|
zassert_equal(
|
||||||
apdu_len = len;
|
apdu_len, null_len, "apdu_len=%d null_len=%d", apdu_len, null_len);
|
||||||
len = rp_ack_decode_apdu(&apdu[0], apdu_len, /* total length of the apdu */
|
zassert_not_equal(apdu_len, 0, NULL);
|
||||||
&test_invoke_id, &test_data);
|
zassert_not_equal(apdu_len, BACNET_STATUS_ERROR, NULL);
|
||||||
zassert_not_equal(len, -1, NULL);
|
test_len =
|
||||||
|
rp_ack_decode_apdu(&apdu[0], apdu_len, &test_invoke_id, &test_data);
|
||||||
|
zassert_equal(apdu_len, test_len, NULL);
|
||||||
|
zassert_not_equal(test_len, -1, NULL);
|
||||||
zassert_equal(test_invoke_id, invoke_id, NULL);
|
zassert_equal(test_invoke_id, invoke_id, NULL);
|
||||||
|
|
||||||
zassert_equal(test_data.object_type, rpdata.object_type, NULL);
|
zassert_equal(test_data.object_type, rpdata.object_type, NULL);
|
||||||
@@ -117,11 +141,22 @@ static void testReadPropertyAck(void)
|
|||||||
|
|
||||||
/* since object property == object_id, decode the application data using
|
/* since object property == object_id, decode the application data using
|
||||||
the appropriate decode function */
|
the appropriate decode function */
|
||||||
len =
|
test_len =
|
||||||
decode_object_id(test_data.application_data, &object, &object_instance);
|
decode_object_id(test_data.application_data, &object, &object_instance);
|
||||||
object_type = object;
|
object_type = object;
|
||||||
zassert_equal(object_type, rpdata.object_type, NULL);
|
zassert_equal(object_type, rpdata.object_type, NULL);
|
||||||
zassert_equal(object_instance, rpdata.object_instance, NULL);
|
zassert_equal(object_instance, rpdata.object_instance, NULL);
|
||||||
|
while (apdu_len) {
|
||||||
|
apdu_len--;
|
||||||
|
if ((apdu_len <= 15) && (apdu_len >= 11)) {
|
||||||
|
/* boundary of optional parameters, so becomes valid */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
test_len =
|
||||||
|
rp_ack_decode_apdu(&apdu[0], apdu_len, &test_invoke_id, &test_data);
|
||||||
|
zassert_true(
|
||||||
|
test_len < 0, "test_len=%d apdu_len=%d", test_len, apdu_len);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_ZTEST_NEW_API)
|
#if defined(CONFIG_ZTEST_NEW_API)
|
||||||
@@ -131,8 +166,7 @@ static void testReadProperty(void)
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
uint8_t apdu[480] = { 0 };
|
uint8_t apdu[480] = { 0 };
|
||||||
int len = 0;
|
int apdu_len = 0, test_len = 0, null_len = 0;
|
||||||
int apdu_len = 0;
|
|
||||||
uint8_t invoke_id = 128;
|
uint8_t invoke_id = 128;
|
||||||
uint8_t test_invoke_id = 0;
|
uint8_t test_invoke_id = 0;
|
||||||
BACNET_READ_PROPERTY_DATA rpdata;
|
BACNET_READ_PROPERTY_DATA rpdata;
|
||||||
@@ -142,16 +176,27 @@ static void testReadProperty(void)
|
|||||||
rpdata.object_instance = 1;
|
rpdata.object_instance = 1;
|
||||||
rpdata.object_property = PROP_OBJECT_IDENTIFIER;
|
rpdata.object_property = PROP_OBJECT_IDENTIFIER;
|
||||||
rpdata.array_index = BACNET_ARRAY_ALL;
|
rpdata.array_index = BACNET_ARRAY_ALL;
|
||||||
len = rp_encode_apdu(&apdu[0], invoke_id, &rpdata);
|
null_len = rp_encode_apdu(NULL, invoke_id, &rpdata);
|
||||||
zassert_not_equal(len, 0, NULL);
|
apdu_len = rp_encode_apdu(&apdu[0], invoke_id, &rpdata);
|
||||||
apdu_len = len;
|
zassert_equal(
|
||||||
|
apdu_len, null_len, "apdu_len=%d null_len=%d", apdu_len, null_len);
|
||||||
|
zassert_not_equal(apdu_len, 0, NULL);
|
||||||
|
|
||||||
len = rp_decode_apdu(&apdu[0], apdu_len, &test_invoke_id, &test_data);
|
test_len = rp_decode_apdu(&apdu[0], apdu_len, &test_invoke_id, &test_data);
|
||||||
zassert_not_equal(len, -1, NULL);
|
zassert_equal(
|
||||||
|
apdu_len, test_len, "apdu_len=%d test_len=%d", apdu_len, test_len);
|
||||||
|
zassert_not_equal(test_len, -1, NULL);
|
||||||
zassert_equal(test_data.object_type, rpdata.object_type, NULL);
|
zassert_equal(test_data.object_type, rpdata.object_type, NULL);
|
||||||
zassert_equal(test_data.object_instance, rpdata.object_instance, NULL);
|
zassert_equal(test_data.object_instance, rpdata.object_instance, NULL);
|
||||||
zassert_equal(test_data.object_property, rpdata.object_property, NULL);
|
zassert_equal(test_data.object_property, rpdata.object_property, NULL);
|
||||||
zassert_equal(test_data.array_index, rpdata.array_index, NULL);
|
zassert_equal(test_data.array_index, rpdata.array_index, NULL);
|
||||||
|
while (apdu_len) {
|
||||||
|
apdu_len--;
|
||||||
|
test_len =
|
||||||
|
rp_decode_apdu(&apdu[0], apdu_len, &test_invoke_id, &test_data);
|
||||||
|
zassert_true(
|
||||||
|
test_len < 0, "test_len=%d apdu_len=%d", test_len, apdu_len);
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -159,16 +204,13 @@ static void testReadProperty(void)
|
|||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#if defined(CONFIG_ZTEST_NEW_API)
|
#if defined(CONFIG_ZTEST_NEW_API)
|
||||||
ZTEST_SUITE(rp_tests, NULL, NULL, NULL, NULL, NULL);
|
ZTEST_SUITE(rp_tests, NULL, NULL, NULL, NULL, NULL);
|
||||||
#else
|
#else
|
||||||
void test_main(void)
|
void test_main(void)
|
||||||
{
|
{
|
||||||
ztest_test_suite(rp_tests,
|
ztest_test_suite(rp_tests, ztest_unit_test(testReadProperty),
|
||||||
ztest_unit_test(testReadProperty),
|
ztest_unit_test(testReadPropertyAck));
|
||||||
ztest_unit_test(testReadPropertyAck)
|
|
||||||
);
|
|
||||||
|
|
||||||
ztest_run_test_suite(rp_tests);
|
ztest_run_test_suite(rp_tests);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user