Correcting COV subscribe - almost working...

This commit is contained in:
skarg
2008-01-14 23:26:20 +00:00
parent b698ba0cdd
commit 85d58bd688
5 changed files with 54 additions and 21 deletions
+39 -8
View File
@@ -61,6 +61,7 @@ typedef struct BACnet_COV_Subscription {
BACNET_OBJECT_ID monitoredObjectIdentifier; BACNET_OBJECT_ID monitoredObjectIdentifier;
bool issueConfirmedNotifications; /* optional */ bool issueConfirmedNotifications; /* optional */
uint32_t lifetime; /* optional */ uint32_t lifetime; /* optional */
bool send_requested;
} BACNET_COV_SUBSCRIPTION; } BACNET_COV_SUBSCRIPTION;
#define MAX_COV_SUBCRIPTIONS 32 #define MAX_COV_SUBCRIPTIONS 32
@@ -80,18 +81,24 @@ void handler_cov_init(
COV_Subscriptions[index].monitoredObjectIdentifier.instance = 0; COV_Subscriptions[index].monitoredObjectIdentifier.instance = 0;
COV_Subscriptions[index].issueConfirmedNotifications = false; COV_Subscriptions[index].issueConfirmedNotifications = false;
COV_Subscriptions[index].lifetime = 0; COV_Subscriptions[index].lifetime = 0;
COV_Subscriptions[index].send_requested = false;
} }
} }
static bool cov_list_subscribe( static bool cov_list_subscribe(
BACNET_ADDRESS * src, BACNET_ADDRESS * src,
BACNET_SUBSCRIBE_COV_DATA * cov_data) BACNET_SUBSCRIBE_COV_DATA * cov_data,
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code)
{ {
bool existing_entry = false; bool existing_entry = false;
int index; int index;
int first_invalid_index = -1; int first_invalid_index = -1;
bool found = true; bool found = true;
/* unable to subscribe - resources? */
/* unable to cancel subscription - other? */
/* existing? - match Object ID and Process ID */ /* existing? - match Object ID and Process ID */
for (index = 0; index < MAX_COV_SUBCRIPTIONS; index++) { for (index = 0; index < MAX_COV_SUBCRIPTIONS; index++) {
if ((COV_Subscriptions[index].valid) && if ((COV_Subscriptions[index].valid) &&
@@ -109,6 +116,7 @@ static bool cov_list_subscribe(
COV_Subscriptions[index].issueConfirmedNotifications = COV_Subscriptions[index].issueConfirmedNotifications =
cov_data->issueConfirmedNotifications; cov_data->issueConfirmedNotifications;
COV_Subscriptions[index].lifetime = cov_data->lifetime; COV_Subscriptions[index].lifetime = cov_data->lifetime;
COV_Subscriptions[index].send_requested = true;
} }
break; break;
} else { } else {
@@ -132,7 +140,17 @@ static bool cov_list_subscribe(
COV_Subscriptions[index].issueConfirmedNotifications = COV_Subscriptions[index].issueConfirmedNotifications =
cov_data->issueConfirmedNotifications; cov_data->issueConfirmedNotifications;
COV_Subscriptions[index].lifetime = cov_data->lifetime; COV_Subscriptions[index].lifetime = cov_data->lifetime;
COV_Subscriptions[index].send_requested = true;
} else { } else {
if (first_invalid_index < 0) {
/* Out of resources */
*error_class = ERROR_CLASS_RESOURCES;
*error_code = ERROR_CODE_OTHER;
} else {
/* Unable to cancel request of unsubscribed object */
*error_class = ERROR_CLASS_OBJECT;
*error_code = ERROR_CODE_OTHER;
}
found = false; found = false;
} }
@@ -152,6 +170,9 @@ static bool cov_send_request(
BACNET_COV_DATA cov_data; BACNET_COV_DATA cov_data;
BACNET_PROPERTY_VALUE value_list[2]; BACNET_PROPERTY_VALUE value_list[2];
#if PRINT_ENABLED
fprintf(stderr, "COVnotification: requested\n");
#endif
datalink_get_my_address(&my_address); datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len =
@@ -172,6 +193,7 @@ static bool cov_send_request(
cov_data.timeRemaining = cov_data.timeRemaining =
cov_subscription->lifetime; cov_subscription->lifetime;
/* encode the value list */ /* encode the value list */
cov_data.listOfValues = &value_list[0];
value_list[0].next = &value_list[1]; value_list[0].next = &value_list[1];
value_list[1].next = NULL; value_list[1].next = NULL;
switch (cov_subscription->monitoredObjectIdentifier.type) { switch (cov_subscription->monitoredObjectIdentifier.type) {
@@ -239,6 +261,11 @@ 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
fprintf(stderr,"COVtask: subscription[%d].lifetime=%d\n",
index,
COV_Subscriptions[index].lifetime);
#endif
} else { } else {
COV_Subscriptions[index].lifetime = 0; COV_Subscriptions[index].lifetime = 0;
} }
@@ -253,16 +280,18 @@ void handler_cov_task(
switch (object_id.type) { switch (object_id.type) {
case OBJECT_BINARY_INPUT: case OBJECT_BINARY_INPUT:
if (Binary_Input_Change_Of_Value(object_id.instance)) { if (Binary_Input_Change_Of_Value(object_id.instance)) {
status = cov_send_request(&COV_Subscriptions[index]); COV_Subscriptions[index].send_requested = true;
if (status) { Binary_Input_Change_Of_Value_Clear(
Binary_Input_Change_Of_Value_Clear( object_id.instance);
object_id.instance);
}
} }
break; break;
default: default:
break; break;
} }
if (COV_Subscriptions[index].send_requested) {
status = cov_send_request(&COV_Subscriptions[index]);
COV_Subscriptions[index].send_requested = false;
}
} }
} }
} }
@@ -278,10 +307,12 @@ static bool cov_subscribe(
switch (cov_data->monitoredObjectIdentifier.type) { switch (cov_data->monitoredObjectIdentifier.type) {
case OBJECT_BINARY_INPUT: case OBJECT_BINARY_INPUT:
status = true; status = true;
status = cov_list_subscribe(src, cov_data); status = cov_list_subscribe(src, cov_data,
error_class, error_code);
break; break;
default: default:
/* FIXME: what is the ERROR? */ *error_class = ERROR_CLASS_OBJECT;
*error_code = ERROR_CODE_UNKNOWN_OBJECT;
break; break;
} }
+1
View File
@@ -181,6 +181,7 @@ int main(
/* at least one second has passed */ /* at least one second has passed */
elapsed_seconds = current_seconds - last_seconds; elapsed_seconds = current_seconds - last_seconds;
if (elapsed_seconds) { if (elapsed_seconds) {
last_seconds = current_seconds;
dcc_timer_seconds(elapsed_seconds); dcc_timer_seconds(elapsed_seconds);
Load_Control_State_Machine_Handler(); Load_Control_State_Machine_Handler();
elapsed_milliseconds = elapsed_seconds * 1000; elapsed_milliseconds = elapsed_seconds * 1000;
+11 -10
View File
@@ -73,6 +73,7 @@ int main(
char *value_string = NULL; char *value_string = NULL;
bool status = false; bool status = false;
BACNET_COV_DATA cov_data; BACNET_COV_DATA cov_data;
BACNET_PROPERTY_VALUE value_list;
uint8_t tag; uint8_t tag;
if (argc < 7) { if (argc < 7) {
@@ -134,19 +135,21 @@ int main(
cov_data.monitoredObjectIdentifier.type = strtol(argv[3], NULL, 0); cov_data.monitoredObjectIdentifier.type = strtol(argv[3], NULL, 0);
cov_data.monitoredObjectIdentifier.instance = strtol(argv[4], NULL, 0); cov_data.monitoredObjectIdentifier.instance = strtol(argv[4], NULL, 0);
cov_data.timeRemaining = strtol(argv[5], NULL, 0); cov_data.timeRemaining = strtol(argv[5], NULL, 0);
cov_data.listOfValues.propertyIdentifier = strtol(argv[6], NULL, 0); cov_data.listOfValues = &value_list;
value_list.next = NULL;
value_list.propertyIdentifier = strtol(argv[6], NULL, 0);
tag = strtol(argv[7], NULL, 0); tag = strtol(argv[7], NULL, 0);
value_string = argv[8]; value_string = argv[8];
/* optional priority */ /* optional priority */
if (argc > 9) if (argc > 9)
cov_data.listOfValues.priority = strtol(argv[9], NULL, 0); value_list.priority = strtol(argv[9], NULL, 0);
else else
cov_data.listOfValues.priority = BACNET_NO_PRIORITY; value_list.priority = BACNET_NO_PRIORITY;
/* optional index */ /* optional index */
if (argc > 10) if (argc > 10)
cov_data.listOfValues.propertyArrayIndex = strtol(argv[10], NULL, 0); value_list.propertyArrayIndex = strtol(argv[10], NULL, 0);
else else
cov_data.listOfValues.propertyArrayIndex = BACNET_ARRAY_ALL; value_list.propertyArrayIndex = BACNET_ARRAY_ALL;
if (cov_data.initiatingDeviceIdentifier >= BACNET_MAX_INSTANCE) { if (cov_data.initiatingDeviceIdentifier >= BACNET_MAX_INSTANCE) {
fprintf(stderr, "device-instance=%u - it must be less than %u\r\n", fprintf(stderr, "device-instance=%u - it must be less than %u\r\n",
@@ -165,9 +168,9 @@ int main(
BACNET_MAX_INSTANCE + 1); BACNET_MAX_INSTANCE + 1);
return 1; return 1;
} }
if (cov_data.listOfValues.propertyIdentifier > MAX_BACNET_PROPERTY_ID) { if (cov_data.listOfValues->propertyIdentifier > MAX_BACNET_PROPERTY_ID) {
fprintf(stderr, "object-type=%u - it must be less than %u\r\n", fprintf(stderr, "object-type=%u - it must be less than %u\r\n",
cov_data.listOfValues.propertyIdentifier, cov_data.listOfValues->propertyIdentifier,
MAX_BACNET_PROPERTY_ID + 1); MAX_BACNET_PROPERTY_ID + 1);
return 1; return 1;
} }
@@ -178,7 +181,7 @@ int main(
} }
status = status =
bacapp_parse_application_data(tag, value_string, bacapp_parse_application_data(tag, value_string,
&cov_data.listOfValues.value); &cov_data.listOfValues->value);
if (!status) { if (!status) {
/* FIXME: show the expected entry format for the tag */ /* FIXME: show the expected entry format for the tag */
fprintf(stderr, "unable to parse the tag value\r\n"); fprintf(stderr, "unable to parse the tag value\r\n");
@@ -189,8 +192,6 @@ int main(
Init_Service_Handlers(); Init_Service_Handlers();
if (!datalink_init(getenv("BACNET_IFACE"))) if (!datalink_init(getenv("BACNET_IFACE")))
return 1; return 1;
/* only one value in our value list */
cov_data.listOfValues.next = NULL;
ucov_notify_send(&Handler_Transmit_Buffer[0], &cov_data); ucov_notify_send(&Handler_Transmit_Buffer[0], &cov_data);
return 0; return 0;
+1 -1
View File
@@ -54,7 +54,7 @@ typedef struct BACnet_COV_Data {
BACNET_OBJECT_ID monitoredObjectIdentifier; BACNET_OBJECT_ID monitoredObjectIdentifier;
uint32_t timeRemaining; /* seconds */ uint32_t timeRemaining; /* seconds */
/* simple linked list of values */ /* simple linked list of values */
BACNET_PROPERTY_VALUE listOfValues; BACNET_PROPERTY_VALUE *listOfValues;
} BACNET_COV_DATA; } BACNET_COV_DATA;
typedef struct BACnet_Property_Reference { typedef struct BACnet_Property_Reference {
+2 -2
View File
@@ -84,7 +84,7 @@ static int notify_encode_adpu(
/* FIXME: for small implementations, we might try a partial /* FIXME: for small implementations, we might try a partial
approach like the rpm.c where the values are encoded with approach like the rpm.c where the values are encoded with
a separate function */ a separate function */
value = &data->listOfValues; value = data->listOfValues;
while (value != NULL) { while (value != NULL) {
/* tag 0 - propertyIdentifier */ /* tag 0 - propertyIdentifier */
len = len =
@@ -228,7 +228,7 @@ int cov_notify_decode_service_request(
/* a tag number of 4 is not extended so only one octet */ /* a tag number of 4 is not extended so only one octet */
len++; len++;
/* the first value includes a pointer to the next value, etc */ /* the first value includes a pointer to the next value, etc */
value = &data->listOfValues; value = data->listOfValues;
while (value != NULL) { while (value != NULL) {
/* tag 0 - propertyIdentifier */ /* tag 0 - propertyIdentifier */
if (decode_is_context_tag(&apdu[len], 0)) { if (decode_is_context_tag(&apdu[len], 0)) {