Enhanced the COV Notify service by adding confirmed to the unconfirmed encoding and decoding.
This commit is contained in:
@@ -557,7 +557,7 @@ typedef enum {
|
||||
EVENT_CHANGE_OF_LIFE_SAFETY = 8,
|
||||
EVENT_EXTENDED = 9,
|
||||
EVENT_BUFFER_READY = 10,
|
||||
EVENT_UNSIGNED_RANGE = 11,
|
||||
EVENT_UNSIGNED_RANGE = 11
|
||||
/* Enumerated values 0-63 are reserved for definition by ASHRAE. */
|
||||
/* Enumerated values 64-65535 may be used by others subject to */
|
||||
/* the procedures and constraints described in Clause 23. */
|
||||
@@ -648,7 +648,7 @@ typedef enum {
|
||||
SILENCED_STATE_UNSILENCED = 0,
|
||||
SILENCED_STATE_AUDIBLE_SILENCED = 1,
|
||||
SILENCED_STATE_VISIBLE_SILENCED = 2,
|
||||
SILENCED_STATE_ALL_SILENCED = 3,
|
||||
SILENCED_STATE_ALL_SILENCED = 3
|
||||
/* Enumerated values 0-63 are reserved for definition by ASHRAE. */
|
||||
/* Enumerated values 64-65535 may be used by others subject to */
|
||||
/* procedures and constraints described in Clause 23. */
|
||||
|
||||
+149
-40
@@ -37,21 +37,25 @@
|
||||
#include "bacdef.h"
|
||||
#include "bacapp.h"
|
||||
#include "cov.h"
|
||||
#include "device.h"
|
||||
#include "datalink.h"
|
||||
#include "npdu.h"
|
||||
|
||||
/* encode service */
|
||||
|
||||
int cov_encode_apdu(uint8_t * apdu, BACNET_COV_DATA * data)
|
||||
/* Change-Of-Value Services
|
||||
COV Subscribe
|
||||
COV Subscribe Property
|
||||
COV Notification
|
||||
Unconfirmed COV Notification
|
||||
*/
|
||||
static int notify_encode_adpu(uint8_t * apdu, BACNET_COV_DATA * data)
|
||||
{
|
||||
int len = 0; /* length of each encoding */
|
||||
int apdu_len = 0; /* total length of the apdu, return value */
|
||||
BACNET_PROPERTY_VALUE *value = NULL; /* value in list */
|
||||
|
||||
if (apdu && data) {
|
||||
apdu[0] = PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST;
|
||||
apdu[1] = SERVICE_UNCONFIRMED_COV_NOTIFICATION; /* service choice */
|
||||
apdu_len = 2;
|
||||
|
||||
if (apdu) {
|
||||
/* tag 0 - subscriberProcessIdentifier */
|
||||
len = encode_context_unsigned(&apdu[apdu_len],
|
||||
0, data->subscriberProcessIdentifier);
|
||||
@@ -75,7 +79,7 @@ int cov_encode_apdu(uint8_t * apdu, BACNET_COV_DATA * data)
|
||||
apdu_len += len;
|
||||
/* the first value includes a pointer to the next value, etc */
|
||||
/* FIXME: for small implementations, we might try a partial
|
||||
approach like the rpm.c where the values are added with
|
||||
approach like the rpm.c where the values are encoded with
|
||||
a separate function */
|
||||
value = &data->listOfValues;
|
||||
while (value != NULL) {
|
||||
@@ -115,8 +119,45 @@ int cov_encode_apdu(uint8_t * apdu, BACNET_COV_DATA * data)
|
||||
return apdu_len;
|
||||
}
|
||||
|
||||
int ccov_notify_encode_apdu(uint8_t * apdu,
|
||||
uint8_t invoke_id, BACNET_COV_DATA * data)
|
||||
{
|
||||
int len = 0; /* length of each encoding */
|
||||
int apdu_len = 0; /* total length of the apdu, return value */
|
||||
uint16_t max_apdu = Device_Max_APDU_Length_Accepted();
|
||||
|
||||
if (apdu) {
|
||||
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_COV_NOTIFICATION;
|
||||
apdu_len = 4;
|
||||
len = notify_encode_adpu(&apdu[apdu_len], data);
|
||||
apdu_len += len;
|
||||
}
|
||||
|
||||
return apdu_len;
|
||||
}
|
||||
|
||||
int ucov_notify_encode_apdu(uint8_t * apdu, BACNET_COV_DATA * data)
|
||||
{
|
||||
int len = 0; /* length of each encoding */
|
||||
int apdu_len = 0; /* total length of the apdu, return value */
|
||||
|
||||
if (apdu && data) {
|
||||
apdu[0] = PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST;
|
||||
apdu[1] = SERVICE_UNCONFIRMED_COV_NOTIFICATION; /* service choice */
|
||||
apdu_len = 2;
|
||||
len = notify_encode_adpu(&apdu[apdu_len], data);
|
||||
apdu_len += len;
|
||||
}
|
||||
|
||||
return apdu_len;
|
||||
}
|
||||
|
||||
/* decode the service request only */
|
||||
int cov_decode_service_request(uint8_t * apdu,
|
||||
/* COV and Unconfirmed COV are the same */
|
||||
int cov_notify_decode_service_request(uint8_t * apdu,
|
||||
unsigned apdu_len, BACNET_COV_DATA * data)
|
||||
{
|
||||
int len = 0; /* return value */
|
||||
@@ -233,27 +274,58 @@ int cov_decode_service_request(uint8_t * apdu,
|
||||
return len;
|
||||
}
|
||||
|
||||
int cov_decode_apdu(uint8_t * apdu,
|
||||
unsigned apdu_len, BACNET_COV_DATA * data)
|
||||
int ccov_notify_decode_apdu(uint8_t * apdu,
|
||||
unsigned apdu_len,
|
||||
uint8_t * invoke_id,
|
||||
BACNET_COV_DATA * data)
|
||||
{
|
||||
int len = 0;
|
||||
unsigned offset = 0;
|
||||
|
||||
if (!apdu)
|
||||
return -1;
|
||||
/* optional checking - most likely was already done prior to this call */
|
||||
if (apdu[0] != PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST)
|
||||
return -1;
|
||||
if (apdu[1] != SERVICE_UNCONFIRMED_COV_NOTIFICATION)
|
||||
return -1;
|
||||
if (apdu[0] != PDU_TYPE_CONFIRMED_SERVICE_REQUEST)
|
||||
return -2;
|
||||
/* apdu[1] = encode_max_segs_max_apdu(0, Device_Max_APDU_Length_Accepted()); */
|
||||
*invoke_id = apdu[2]; /* invoke id - filled in by net layer */
|
||||
if (apdu[3] != SERVICE_CONFIRMED_COV_NOTIFICATION)
|
||||
return -3;
|
||||
offset = 4;
|
||||
|
||||
/* optional limits - must be used as a pair */
|
||||
if (apdu_len > 2) {
|
||||
len = cov_decode_service_request(&apdu[2], apdu_len - 2, data);
|
||||
if (apdu_len > offset) {
|
||||
len = cov_notify_decode_service_request(
|
||||
&apdu[offset], apdu_len - offset, data);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int cov_send(uint8_t * buffer, BACNET_COV_DATA * data)
|
||||
int ucov_notify_decode_apdu(uint8_t * apdu,
|
||||
unsigned apdu_len, BACNET_COV_DATA * data)
|
||||
{
|
||||
int len = 0;
|
||||
unsigned offset = 0;
|
||||
|
||||
if (!apdu)
|
||||
return -1;
|
||||
/* optional checking - most likely was already done prior to this call */
|
||||
if (apdu[0] != PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST)
|
||||
return -2;
|
||||
if (apdu[1] != SERVICE_UNCONFIRMED_COV_NOTIFICATION)
|
||||
return -3;
|
||||
/* optional limits - must be used as a pair */
|
||||
offset = 2;
|
||||
if (apdu_len > offset) {
|
||||
len = cov_notify_decode_service_request(
|
||||
&apdu[offset], apdu_len - offset, data);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int ucov_notify_send(uint8_t * buffer, BACNET_COV_DATA * data)
|
||||
{
|
||||
int pdu_len = 0;
|
||||
BACNET_ADDRESS dest;
|
||||
@@ -263,11 +335,12 @@ int cov_send(uint8_t * buffer, BACNET_COV_DATA * data)
|
||||
datalink_get_broadcast_address(&dest);
|
||||
|
||||
/* encode the NPDU portion of the packet */
|
||||
pdu_len = npdu_encode_apdu(&buffer[0], &dest, NULL, false /* true for confirmed messages */,
|
||||
pdu_len = npdu_encode_apdu(&buffer[0], &dest, NULL,
|
||||
false /* true for confirmed messages */,
|
||||
MESSAGE_PRIORITY_NORMAL);
|
||||
|
||||
/* encode the APDU portion of the packet */
|
||||
pdu_len += cov_encode_apdu(&buffer[pdu_len], data);
|
||||
pdu_len += ucov_notify_encode_apdu(&buffer[pdu_len], data);
|
||||
|
||||
bytes_sent = datalink_send_pdu(&dest, /* destination address */
|
||||
&buffer[0], pdu_len); /* number of bytes of data */
|
||||
@@ -301,38 +374,73 @@ void datalink_get_broadcast_address(BACNET_ADDRESS * dest)
|
||||
{
|
||||
}
|
||||
|
||||
void testCOVData(Test * pTest, BACNET_COV_DATA * data)
|
||||
/* dummy function stubs */
|
||||
uint16_t Device_Max_APDU_Length_Accepted(void)
|
||||
{
|
||||
return MAX_APDU;
|
||||
}
|
||||
|
||||
void testCOVNotifyData(Test * pTest,
|
||||
BACNET_COV_DATA * data,
|
||||
BACNET_COV_DATA * test_data)
|
||||
{
|
||||
ct_test(pTest,
|
||||
test_data->subscriberProcessIdentifier ==
|
||||
data->subscriberProcessIdentifier);
|
||||
ct_test(pTest,
|
||||
test_data->initiatingDeviceIdentifier ==
|
||||
data->initiatingDeviceIdentifier);
|
||||
ct_test(pTest,
|
||||
test_data->monitoredObjectIdentifier.type ==
|
||||
data->monitoredObjectIdentifier.type);
|
||||
ct_test(pTest,
|
||||
test_data->monitoredObjectIdentifier.instance ==
|
||||
data->monitoredObjectIdentifier.instance);
|
||||
ct_test(pTest,
|
||||
test_data->timeRemaining == data->timeRemaining);
|
||||
/* FIXME: test the listOfValues in some clever manner */
|
||||
}
|
||||
|
||||
void testUCOVNotifyData(Test * pTest, BACNET_COV_DATA * data)
|
||||
{
|
||||
uint8_t apdu[480] = { 0 };
|
||||
int len = 0;
|
||||
int apdu_len = 0;
|
||||
BACNET_COV_DATA test_data;
|
||||
|
||||
len = cov_encode_apdu(&apdu[0], data);
|
||||
len = ucov_notify_encode_apdu(&apdu[0], data);
|
||||
ct_test(pTest, len > 0);
|
||||
apdu_len = len;
|
||||
|
||||
test_data.listOfValues.next = NULL;
|
||||
len = ucov_notify_decode_apdu(&apdu[0], apdu_len, &test_data);
|
||||
ct_test(pTest, len != -1);
|
||||
testCOVNotifyData(pTest, data, &test_data);
|
||||
}
|
||||
|
||||
void testCCOVNotifyData(Test * pTest, uint8_t invoke_id, BACNET_COV_DATA * data)
|
||||
{
|
||||
uint8_t apdu[480] = { 0 };
|
||||
int len = 0;
|
||||
int apdu_len = 0;
|
||||
BACNET_COV_DATA test_data;
|
||||
uint8_t test_invoke_id = 0;
|
||||
|
||||
len = ccov_notify_encode_apdu(&apdu[0], invoke_id, data);
|
||||
ct_test(pTest, len != 0);
|
||||
apdu_len = len;
|
||||
|
||||
test_data.listOfValues.next = NULL;
|
||||
len = cov_decode_apdu(&apdu[0], apdu_len, &test_data);
|
||||
ct_test(pTest, len != -1);
|
||||
ct_test(pTest,
|
||||
test_data.subscriberProcessIdentifier ==
|
||||
data->subscriberProcessIdentifier);
|
||||
ct_test(pTest,
|
||||
test_data.initiatingDeviceIdentifier ==
|
||||
data->initiatingDeviceIdentifier);
|
||||
ct_test(pTest,
|
||||
test_data.monitoredObjectIdentifier.type ==
|
||||
data->monitoredObjectIdentifier.type);
|
||||
ct_test(pTest,
|
||||
test_data.monitoredObjectIdentifier.instance ==
|
||||
data->monitoredObjectIdentifier.instance);
|
||||
ct_test(pTest, test_data.timeRemaining == data->timeRemaining);
|
||||
/* FIXME: test the listOfValues in some clever manner */
|
||||
len = ccov_notify_decode_apdu(&apdu[0], apdu_len,
|
||||
&test_invoke_id, &test_data);
|
||||
ct_test(pTest, len > 0);
|
||||
ct_test(pTest, test_invoke_id == invoke_id);
|
||||
testCOVNotifyData(pTest, data, &test_data);
|
||||
}
|
||||
|
||||
void testCOV(Test * pTest)
|
||||
void testCOVNotify(Test * pTest)
|
||||
{
|
||||
uint8_t invoke_id = 12;
|
||||
BACNET_COV_DATA data;
|
||||
/* BACNET_PROPERTY_VALUE value2; */
|
||||
|
||||
@@ -349,7 +457,8 @@ void testCOV(Test * pTest)
|
||||
data.listOfValues.priority = 0;
|
||||
data.listOfValues.next = NULL;
|
||||
|
||||
testCOVData(pTest, &data);
|
||||
testUCOVNotifyData(pTest, &data);
|
||||
testCCOVNotifyData(pTest, invoke_id, &data);
|
||||
|
||||
/* FIXME: add more values to the list of values */
|
||||
}
|
||||
@@ -362,7 +471,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
pTest = ct_create("BACnet COV", NULL);
|
||||
/* individual tests */
|
||||
rc = ct_addTestFunction(pTest, testCOV);
|
||||
rc = ct_addTestFunction(pTest, testCOVNotify);
|
||||
assert(rc);
|
||||
|
||||
ct_setStream(pTest, stdout);
|
||||
|
||||
+17
-6
@@ -61,21 +61,32 @@ typedef struct BACnet_COV_Data {
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* encode service - use -1 for limit if you want unlimited */
|
||||
int cov_encode_apdu(uint8_t * apdu, BACNET_COV_DATA * data);
|
||||
int ucov_notify_encode_apdu(uint8_t * apdu, BACNET_COV_DATA * data);
|
||||
|
||||
int cov_decode_service_request(uint8_t * apdu,
|
||||
int ucov_notify_decode_apdu(uint8_t * apdu,
|
||||
unsigned apdu_len, BACNET_COV_DATA * data);
|
||||
|
||||
int cov_decode_apdu(uint8_t * apdu,
|
||||
int ucov_notify_send(uint8_t * buffer, BACNET_COV_DATA * data);
|
||||
|
||||
int ccov_notify_encode_apdu(uint8_t * apdu,
|
||||
uint8_t invoke_id, BACNET_COV_DATA * data);
|
||||
|
||||
int ccov_notify_decode_apdu(uint8_t * apdu,
|
||||
unsigned apdu_len,
|
||||
uint8_t * invoke_id,
|
||||
BACNET_COV_DATA * data);
|
||||
|
||||
/* common for both confirmed and unconfirmed */
|
||||
int cov_notify_decode_service_request(uint8_t * apdu,
|
||||
unsigned apdu_len, BACNET_COV_DATA * data);
|
||||
|
||||
int cov_send(uint8_t * buffer, BACNET_COV_DATA * data);
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef TEST
|
||||
#include "ctest.h"
|
||||
void testCOV(Test * pTest);
|
||||
void testCOVNotify(Test * pTest);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -4,7 +4,7 @@ BASEDIR = .
|
||||
#CFLAGS = -Wall -I.
|
||||
# -g for debugging with gdb
|
||||
#CFLAGS = -Wall -I. -g
|
||||
CFLAGS = -Wall -I. -Itest -DTEST -DTEST_COV -g
|
||||
CFLAGS = -Wall -I. -Itest -Idemo/object -DTEST -DTEST_COV -g
|
||||
|
||||
SRCS = bacdcode.c \
|
||||
bacstr.c \
|
||||
|
||||
@@ -212,7 +212,7 @@ int main(int argc, char *argv[])
|
||||
/* only one value in our value list */
|
||||
cov_data.listOfValues.next = NULL;
|
||||
|
||||
cov_send(&Handler_Transmit_Buffer[0],&cov_data);
|
||||
ucov_notify_send(&Handler_Transmit_Buffer[0],&cov_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user