From 85d58bd68897343cfd66cbeaff126df4c1bd972b Mon Sep 17 00:00:00 2001 From: skarg Date: Mon, 14 Jan 2008 23:26:20 +0000 Subject: [PATCH] Correcting COV subscribe - almost working... --- bacnet-stack/demo/handler/h_cov.c | 47 +++++++++++++++++++++++++------ bacnet-stack/demo/server/main.c | 1 + bacnet-stack/demo/ucov/main.c | 21 +++++++------- bacnet-stack/include/cov.h | 2 +- bacnet-stack/src/cov.c | 4 +-- 5 files changed, 54 insertions(+), 21 deletions(-) diff --git a/bacnet-stack/demo/handler/h_cov.c b/bacnet-stack/demo/handler/h_cov.c index 29ff0343..faff66c0 100644 --- a/bacnet-stack/demo/handler/h_cov.c +++ b/bacnet-stack/demo/handler/h_cov.c @@ -61,6 +61,7 @@ typedef struct BACnet_COV_Subscription { BACNET_OBJECT_ID monitoredObjectIdentifier; bool issueConfirmedNotifications; /* optional */ uint32_t lifetime; /* optional */ + bool send_requested; } BACNET_COV_SUBSCRIPTION; #define MAX_COV_SUBCRIPTIONS 32 @@ -80,18 +81,24 @@ void handler_cov_init( COV_Subscriptions[index].monitoredObjectIdentifier.instance = 0; COV_Subscriptions[index].issueConfirmedNotifications = false; COV_Subscriptions[index].lifetime = 0; + COV_Subscriptions[index].send_requested = false; } } static bool cov_list_subscribe( 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; int index; int first_invalid_index = -1; bool found = true; + /* unable to subscribe - resources? */ + /* unable to cancel subscription - other? */ + /* existing? - match Object ID and Process ID */ for (index = 0; index < MAX_COV_SUBCRIPTIONS; index++) { if ((COV_Subscriptions[index].valid) && @@ -109,6 +116,7 @@ static bool cov_list_subscribe( COV_Subscriptions[index].issueConfirmedNotifications = cov_data->issueConfirmedNotifications; COV_Subscriptions[index].lifetime = cov_data->lifetime; + COV_Subscriptions[index].send_requested = true; } break; } else { @@ -132,7 +140,17 @@ static bool cov_list_subscribe( COV_Subscriptions[index].issueConfirmedNotifications = cov_data->issueConfirmedNotifications; COV_Subscriptions[index].lifetime = cov_data->lifetime; + COV_Subscriptions[index].send_requested = true; } 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; } @@ -152,6 +170,9 @@ static bool cov_send_request( BACNET_COV_DATA cov_data; BACNET_PROPERTY_VALUE value_list[2]; +#if PRINT_ENABLED + fprintf(stderr, "COVnotification: requested\n"); +#endif datalink_get_my_address(&my_address); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); pdu_len = @@ -172,6 +193,7 @@ static bool cov_send_request( cov_data.timeRemaining = cov_subscription->lifetime; /* encode the value list */ + cov_data.listOfValues = &value_list[0]; value_list[0].next = &value_list[1]; value_list[1].next = NULL; switch (cov_subscription->monitoredObjectIdentifier.type) { @@ -239,6 +261,11 @@ void handler_cov_task( lifetime_seconds = COV_Subscriptions[index].lifetime; if (lifetime_seconds >= 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 { COV_Subscriptions[index].lifetime = 0; } @@ -253,16 +280,18 @@ void handler_cov_task( switch (object_id.type) { case OBJECT_BINARY_INPUT: if (Binary_Input_Change_Of_Value(object_id.instance)) { - status = cov_send_request(&COV_Subscriptions[index]); - if (status) { - Binary_Input_Change_Of_Value_Clear( - object_id.instance); - } + COV_Subscriptions[index].send_requested = true; + Binary_Input_Change_Of_Value_Clear( + object_id.instance); } break; default: 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) { case OBJECT_BINARY_INPUT: status = true; - status = cov_list_subscribe(src, cov_data); + status = cov_list_subscribe(src, cov_data, + error_class, error_code); break; default: - /* FIXME: what is the ERROR? */ + *error_class = ERROR_CLASS_OBJECT; + *error_code = ERROR_CODE_UNKNOWN_OBJECT; break; } diff --git a/bacnet-stack/demo/server/main.c b/bacnet-stack/demo/server/main.c index 5e71d16f..2b60da6e 100644 --- a/bacnet-stack/demo/server/main.c +++ b/bacnet-stack/demo/server/main.c @@ -181,6 +181,7 @@ int main( /* at least one second has passed */ elapsed_seconds = current_seconds - last_seconds; if (elapsed_seconds) { + last_seconds = current_seconds; dcc_timer_seconds(elapsed_seconds); Load_Control_State_Machine_Handler(); elapsed_milliseconds = elapsed_seconds * 1000; diff --git a/bacnet-stack/demo/ucov/main.c b/bacnet-stack/demo/ucov/main.c index e15739a0..921a0b27 100644 --- a/bacnet-stack/demo/ucov/main.c +++ b/bacnet-stack/demo/ucov/main.c @@ -73,6 +73,7 @@ int main( char *value_string = NULL; bool status = false; BACNET_COV_DATA cov_data; + BACNET_PROPERTY_VALUE value_list; uint8_t tag; if (argc < 7) { @@ -134,19 +135,21 @@ int main( cov_data.monitoredObjectIdentifier.type = strtol(argv[3], NULL, 0); cov_data.monitoredObjectIdentifier.instance = strtol(argv[4], 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); value_string = argv[8]; /* optional priority */ if (argc > 9) - cov_data.listOfValues.priority = strtol(argv[9], NULL, 0); + value_list.priority = strtol(argv[9], NULL, 0); else - cov_data.listOfValues.priority = BACNET_NO_PRIORITY; + value_list.priority = BACNET_NO_PRIORITY; /* optional index */ if (argc > 10) - cov_data.listOfValues.propertyArrayIndex = strtol(argv[10], NULL, 0); + value_list.propertyArrayIndex = strtol(argv[10], NULL, 0); else - cov_data.listOfValues.propertyArrayIndex = BACNET_ARRAY_ALL; + value_list.propertyArrayIndex = BACNET_ARRAY_ALL; if (cov_data.initiatingDeviceIdentifier >= BACNET_MAX_INSTANCE) { fprintf(stderr, "device-instance=%u - it must be less than %u\r\n", @@ -165,9 +168,9 @@ int main( BACNET_MAX_INSTANCE + 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", - cov_data.listOfValues.propertyIdentifier, + cov_data.listOfValues->propertyIdentifier, MAX_BACNET_PROPERTY_ID + 1); return 1; } @@ -178,7 +181,7 @@ int main( } status = bacapp_parse_application_data(tag, value_string, - &cov_data.listOfValues.value); + &cov_data.listOfValues->value); if (!status) { /* FIXME: show the expected entry format for the tag */ fprintf(stderr, "unable to parse the tag value\r\n"); @@ -189,8 +192,6 @@ int main( Init_Service_Handlers(); if (!datalink_init(getenv("BACNET_IFACE"))) return 1; - /* only one value in our value list */ - cov_data.listOfValues.next = NULL; ucov_notify_send(&Handler_Transmit_Buffer[0], &cov_data); return 0; diff --git a/bacnet-stack/include/cov.h b/bacnet-stack/include/cov.h index e0aab321..f0c64f60 100644 --- a/bacnet-stack/include/cov.h +++ b/bacnet-stack/include/cov.h @@ -54,7 +54,7 @@ typedef struct BACnet_COV_Data { BACNET_OBJECT_ID monitoredObjectIdentifier; uint32_t timeRemaining; /* seconds */ /* simple linked list of values */ - BACNET_PROPERTY_VALUE listOfValues; + BACNET_PROPERTY_VALUE *listOfValues; } BACNET_COV_DATA; typedef struct BACnet_Property_Reference { diff --git a/bacnet-stack/src/cov.c b/bacnet-stack/src/cov.c index 22fa1ab9..a6e03ab4 100644 --- a/bacnet-stack/src/cov.c +++ b/bacnet-stack/src/cov.c @@ -84,7 +84,7 @@ static int notify_encode_adpu( /* FIXME: for small implementations, we might try a partial approach like the rpm.c where the values are encoded with a separate function */ - value = &data->listOfValues; + value = data->listOfValues; while (value != NULL) { /* tag 0 - propertyIdentifier */ len = @@ -228,7 +228,7 @@ int cov_notify_decode_service_request( /* a tag number of 4 is not extended so only one octet */ len++; /* the first value includes a pointer to the next value, etc */ - value = &data->listOfValues; + value = data->listOfValues; while (value != NULL) { /* tag 0 - propertyIdentifier */ if (decode_is_context_tag(&apdu[len], 0)) {