Added COV subscription list to Device object. Untested.
This commit is contained in:
@@ -67,6 +67,142 @@ typedef struct BACnet_COV_Subscription {
|
|||||||
#define MAX_COV_SUBCRIPTIONS 32
|
#define MAX_COV_SUBCRIPTIONS 32
|
||||||
static BACNET_COV_SUBSCRIPTION COV_Subscriptions[MAX_COV_SUBCRIPTIONS];
|
static BACNET_COV_SUBSCRIPTION COV_Subscriptions[MAX_COV_SUBCRIPTIONS];
|
||||||
|
|
||||||
|
/*
|
||||||
|
BACnetCOVSubscription ::= SEQUENCE {
|
||||||
|
Recipient [0] BACnetRecipientProcess,
|
||||||
|
BACnetRecipient ::= CHOICE {
|
||||||
|
device [0] BACnetObjectIdentifier,
|
||||||
|
address [1] BACnetAddress
|
||||||
|
BACnetAddress ::= SEQUENCE {
|
||||||
|
network-number Unsigned16, -- A value of 0 indicates the local network
|
||||||
|
mac-address OCTET STRING -- A string of length 0 indicates a broadcast
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BACnetRecipientProcess ::= SEQUENCE {
|
||||||
|
recipient [0] BACnetRecipient,
|
||||||
|
processIdentifier [1] Unsigned32
|
||||||
|
}
|
||||||
|
MonitoredPropertyReference [1] BACnetObjectPropertyReference,
|
||||||
|
BACnetObjectPropertyReference ::= SEQUENCE {
|
||||||
|
objectIdentifier [0] BACnetObjectIdentifier,
|
||||||
|
propertyIdentifier [1] BACnetPropertyIdentifier,
|
||||||
|
propertyArrayIndex [2] Unsigned OPTIONAL -- used only with array datatype
|
||||||
|
-- if omitted with an array the entire array is referenced
|
||||||
|
}
|
||||||
|
IssueConfirmedNotifications [2] BOOLEAN,
|
||||||
|
TimeRemaining [3] Unsigned,
|
||||||
|
COVIncrement [4] REAL OPTIONAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int cov_encode_subscription(
|
||||||
|
uint8_t * apdu,
|
||||||
|
int max_apdu,
|
||||||
|
BACNET_COV_SUBSCRIPTION * cov_subscription)
|
||||||
|
{
|
||||||
|
int len = 0;
|
||||||
|
int apdu_len = 0;
|
||||||
|
BACNET_OCTET_STRING octet_string;
|
||||||
|
|
||||||
|
/* Recipient [0] BACnetRecipientProcess - opening */
|
||||||
|
len = encode_opening_tag(&apdu[apdu_len], 0);
|
||||||
|
apdu_len += len;
|
||||||
|
/* recipient [0] BACnetRecipient - opening */
|
||||||
|
len = encode_opening_tag(&apdu[apdu_len], 0);
|
||||||
|
apdu_len += len;
|
||||||
|
/* CHOICE - address [1] BACnetAddress - opening */
|
||||||
|
len = encode_opening_tag(&apdu[apdu_len], 1);
|
||||||
|
apdu_len += len;
|
||||||
|
/* network-number Unsigned16, */
|
||||||
|
/* -- A value of 0 indicates the local network */
|
||||||
|
len = encode_application_unsigned(
|
||||||
|
&apdu[apdu_len],
|
||||||
|
cov_subscription->dest.net);
|
||||||
|
apdu_len += len;
|
||||||
|
/* mac-address OCTET STRING */
|
||||||
|
/* -- A string of length 0 indicates a broadcast */
|
||||||
|
if (cov_subscription->dest.net) {
|
||||||
|
octetstring_init(&octet_string,
|
||||||
|
&cov_subscription->dest.adr[0],
|
||||||
|
cov_subscription->dest.len);
|
||||||
|
} else {
|
||||||
|
octetstring_init(&octet_string,
|
||||||
|
&cov_subscription->dest.mac[0],
|
||||||
|
cov_subscription->dest.mac_len);
|
||||||
|
}
|
||||||
|
len = encode_application_octet_string(
|
||||||
|
&apdu[apdu_len],
|
||||||
|
&octet_string);
|
||||||
|
apdu_len += len;
|
||||||
|
/* CHOICE - address [1] BACnetAddress - closing */
|
||||||
|
len = encode_closing_tag(&apdu[apdu_len], 1);
|
||||||
|
apdu_len += len;
|
||||||
|
/* recipient [0] BACnetRecipient - closing */
|
||||||
|
len = encode_closing_tag(&apdu[apdu_len], 0);
|
||||||
|
apdu_len += len;
|
||||||
|
/* processIdentifier [1] Unsigned32 */
|
||||||
|
len = encode_context_unsigned(&apdu[apdu_len],1,
|
||||||
|
cov_subscription->subscriberProcessIdentifier);
|
||||||
|
apdu_len += len;
|
||||||
|
/* Recipient [0] BACnetRecipientProcess - closing */
|
||||||
|
len = encode_closing_tag(&apdu[apdu_len], 0);
|
||||||
|
apdu_len += len;
|
||||||
|
/* MonitoredPropertyReference [1] BACnetObjectPropertyReference,*/
|
||||||
|
len = encode_opening_tag(&apdu[apdu_len], 1);
|
||||||
|
apdu_len += len;
|
||||||
|
/* objectIdentifier [0] */
|
||||||
|
len = encode_context_object_id(
|
||||||
|
&apdu[apdu_len],0,
|
||||||
|
cov_subscription->monitoredObjectIdentifier.type,
|
||||||
|
cov_subscription->monitoredObjectIdentifier.instance);
|
||||||
|
apdu_len += len;
|
||||||
|
/* propertyIdentifier [1] */
|
||||||
|
/* FIXME: we are monitoring 2 properties! How to encode? */
|
||||||
|
len = encode_context_enumerated(
|
||||||
|
&apdu[apdu_len],1,
|
||||||
|
PROP_PRESENT_VALUE);
|
||||||
|
apdu_len += len;
|
||||||
|
/* MonitoredPropertyReference [1] - closing */
|
||||||
|
len = encode_closing_tag(&apdu[apdu_len], 1);
|
||||||
|
apdu_len += len;
|
||||||
|
/* IssueConfirmedNotifications [2] BOOLEAN, */
|
||||||
|
len = encode_context_boolean(
|
||||||
|
&apdu[apdu_len],2,
|
||||||
|
cov_subscription->issueConfirmedNotifications);
|
||||||
|
apdu_len += len;
|
||||||
|
/* TimeRemaining [3] Unsigned, */
|
||||||
|
len = encode_context_unsigned(
|
||||||
|
&apdu[apdu_len],3,
|
||||||
|
cov_subscription->lifetime);
|
||||||
|
apdu_len += len;
|
||||||
|
|
||||||
|
return apdu_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int handler_cov_encode_subscriptions(
|
||||||
|
uint8_t * apdu, int max_apdu)
|
||||||
|
{
|
||||||
|
int len = 0;
|
||||||
|
int apdu_len = 0;
|
||||||
|
unsigned index = 0;
|
||||||
|
|
||||||
|
if (apdu) {
|
||||||
|
for (index = 0; index < MAX_COV_SUBCRIPTIONS; index++) {
|
||||||
|
if (COV_Subscriptions[index].valid) {
|
||||||
|
len = cov_encode_subscription(
|
||||||
|
&apdu[apdu_len],
|
||||||
|
max_apdu - apdu_len,
|
||||||
|
&COV_Subscriptions[index]);
|
||||||
|
apdu_len += len;
|
||||||
|
if (apdu_len > max_apdu) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return apdu_len;
|
||||||
|
}
|
||||||
|
|
||||||
void handler_cov_init(
|
void handler_cov_init(
|
||||||
void)
|
void)
|
||||||
{
|
{
|
||||||
@@ -261,7 +397,7 @@ void handler_cov_task(
|
|||||||
lifetime_seconds = COV_Subscriptions[index].lifetime;
|
lifetime_seconds = COV_Subscriptions[index].lifetime;
|
||||||
if (lifetime_seconds >= elapsed_seconds) {
|
if (lifetime_seconds >= elapsed_seconds) {
|
||||||
COV_Subscriptions[index].lifetime -= elapsed_seconds;
|
COV_Subscriptions[index].lifetime -= elapsed_seconds;
|
||||||
#if PRINT_ENABLED
|
#if 0
|
||||||
fprintf(stderr,"COVtask: subscription[%d].lifetime=%d\n",
|
fprintf(stderr,"COVtask: subscription[%d].lifetime=%d\n",
|
||||||
index,
|
index,
|
||||||
COV_Subscriptions[index].lifetime);
|
COV_Subscriptions[index].lifetime);
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
#include "wp.h" /* write property handling */
|
#include "wp.h" /* write property handling */
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "device.h" /* me */
|
#include "device.h" /* me */
|
||||||
|
#include "handlers.h"
|
||||||
#include "datalink.h"
|
#include "datalink.h"
|
||||||
#if defined(BACFILE)
|
#if defined(BACFILE)
|
||||||
#include "bacfile.h" /* object list dependency */
|
#include "bacfile.h" /* object list dependency */
|
||||||
@@ -875,6 +876,9 @@ int Device_Encode_Property_APDU(
|
|||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case PROP_ACTIVE_COV_SUBSCRIPTIONS:
|
case PROP_ACTIVE_COV_SUBSCRIPTIONS:
|
||||||
|
/* FIXME: the real max apdu should be passed into function */
|
||||||
|
apdu_len = handler_cov_encode_subscriptions(
|
||||||
|
&apdu[0], MAX_APDU);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
*error_class = ERROR_CLASS_PROPERTY;
|
*error_class = ERROR_CLASS_PROPERTY;
|
||||||
|
|||||||
@@ -29,3 +29,4 @@ R. splint the code. Make intelligent fixes.
|
|||||||
S. Fix src/mstp.c so that indent can parse it correctly.
|
S. Fix src/mstp.c so that indent can parse it correctly.
|
||||||
T. Add "inline" to static functions that are only used once.
|
T. Add "inline" to static functions that are only used once.
|
||||||
U. Modify code to compile with MISRA C rules.
|
U. Modify code to compile with MISRA C rules.
|
||||||
|
V. Change OBJECT_ID to only be 32 bits, and add macro handlers.
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "bacdef.h"
|
#include "bacdef.h"
|
||||||
|
#include "cov.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -45,10 +46,15 @@ extern "C" {
|
|||||||
unsigned index);
|
unsigned index);
|
||||||
char *Binary_Input_Name(
|
char *Binary_Input_Name(
|
||||||
uint32_t object_instance);
|
uint32_t object_instance);
|
||||||
|
|
||||||
bool Binary_Input_Change_Of_Value(
|
bool Binary_Input_Change_Of_Value(
|
||||||
uint32_t object_instance);
|
uint32_t object_instance);
|
||||||
void Binary_Input_Change_Of_Value_Clear(
|
void Binary_Input_Change_Of_Value_Clear(
|
||||||
uint32_t object_instance);
|
uint32_t object_instance);
|
||||||
|
bool Binary_Input_Encode_Value_List(
|
||||||
|
uint32_t object_instance,
|
||||||
|
BACNET_PROPERTY_VALUE *value_list);
|
||||||
|
|
||||||
int Binary_Input_Encode_Property_APDU(
|
int Binary_Input_Encode_Property_APDU(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
uint32_t object_instance,
|
uint32_t object_instance,
|
||||||
@@ -62,7 +68,6 @@ extern "C" {
|
|||||||
BACNET_ERROR_CLASS * error_class,
|
BACNET_ERROR_CLASS * error_class,
|
||||||
BACNET_ERROR_CODE * error_code);
|
BACNET_ERROR_CODE * error_code);
|
||||||
|
|
||||||
|
|
||||||
#ifdef TEST
|
#ifdef TEST
|
||||||
#include "ctest.h"
|
#include "ctest.h"
|
||||||
void testBinaryInput(
|
void testBinaryInput(
|
||||||
|
|||||||
@@ -150,6 +150,9 @@ extern "C" {
|
|||||||
BACNET_CONFIRMED_SERVICE_DATA * service_data);
|
BACNET_CONFIRMED_SERVICE_DATA * service_data);
|
||||||
void handler_cov_task(
|
void handler_cov_task(
|
||||||
uint32_t elapsed_seconds);
|
uint32_t elapsed_seconds);
|
||||||
|
int handler_cov_encode_subscriptions(
|
||||||
|
uint8_t * apdu, int max_apdu);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user