diff --git a/bacnet-stack/demo/handler/h_cov.c b/bacnet-stack/demo/handler/h_cov.c index b540c0a4..ab2b4e03 100644 --- a/bacnet-stack/demo/handler/h_cov.c +++ b/bacnet-stack/demo/handler/h_cov.c @@ -31,6 +31,7 @@ #include "txbuf.h" #include "bacdef.h" #include "bacdcode.h" +#include "bacaddr.h" #include "apdu.h" #include "npdu.h" #include "abort.h" @@ -54,6 +55,7 @@ of an object that have been specified in the standard. */ typedef struct BACnet_COV_Subscription { bool valid; + BACNET_ADDRESS dest; uint32_t subscriberProcessIdentifier; BACNET_OBJECT_ID monitoredObjectIdentifier; bool issueConfirmedNotifications; /* optional */ @@ -70,6 +72,7 @@ void handler_cov_init( for (index = 0; index < MAX_COV_SUBCRIPTIONS; index++) { COV_Subscriptions[index].valid = false; + COV_Subscriptions[index].dest.mac_len = 0; COV_Subscriptions[index].subscriberProcessIdentifier = 0; COV_Subscriptions[index].monitoredObjectIdentifier.type = OBJECT_ANALOG_INPUT; @@ -101,12 +104,12 @@ static bool cov_list_subscribe( if (cov_data->cancellationRequest) { COV_Subscriptions[index].valid = false; } else { + bacnet_address_copy(&COV_Subscriptions[index].dest, src); COV_Subscriptions[index].issueConfirmedNotifications = cov_data->issueConfirmedNotifications; COV_Subscriptions[index].lifetime = cov_data->lifetime; } - /* FIXME: update SRC address */ break; } else { if (first_invalid_index < 0) { @@ -118,9 +121,8 @@ static bool cov_list_subscribe( (!cov_data->cancellationRequest)) { index = first_invalid_index; found = true; - if (!cov_data->cancellationRequest) { - COV_Subscriptions[index].valid = true; - } + COV_Subscriptions[index].valid = true; + bacnet_address_copy(&COV_Subscriptions[index].dest, src); COV_Subscriptions[index].monitoredObjectIdentifier.type = cov_data->monitoredObjectIdentifier.type; COV_Subscriptions[index].monitoredObjectIdentifier.instance = @@ -131,7 +133,6 @@ static bool cov_list_subscribe( cov_data->issueConfirmedNotifications; COV_Subscriptions[index].lifetime = cov_data->lifetime; - /* FIXME: add SRC address */ } else { found = false; } @@ -144,8 +145,38 @@ static bool cov_list_subscribe( void handler_cov_task( uint32_t elapsed_milliseconds) { - /* handle timeouts */ - /* handle COV notifications */ + int index; + int lifetime_milliseconds; + BACNET_OBJECT_ID object_id; + + + /* existing? - match Object ID and Process ID */ + for (index = 0; index < MAX_COV_SUBCRIPTIONS; index++) { + if (COV_Subscriptions[index].valid) { + /* handle timeouts */ + lifetime_milliseconds = COV_Subscriptions[index].lifetime; + if (lifetime_milliseconds >= elapsed_milliseconds) { + COV_Subscriptions[index].lifetime -= elapsed_milliseconds; + } else { + COV_Subscriptions[index].lifetime = 0; + } + if (COV_Subscriptions[index].lifetime == 0) { + COV_Subscriptions[index].valid = false; + } + /* handle COV notifications */ + object_id.type = COV_Subscriptions[index].monitoredObjectIdentifier.type; + object_id.instance = COV_Subscriptions[index].monitoredObjectIdentifier.instance; + switch (object_id.type) { + case OBJECT_BINARY_INPUT: + if (Binary_Input_Change_Of_Value(object_id.instance)) { + /* FIXME: send confirmed or unconfirmed request */ + } + break; + default: + break; + } + } + } } static bool cov_subscribe( diff --git a/bacnet-stack/demo/object/bi.c b/bacnet-stack/demo/object/bi.c index a2469169..feb1b6e2 100644 --- a/bacnet-stack/demo/object/bi.c +++ b/bacnet-stack/demo/object/bi.c @@ -40,6 +40,8 @@ static BACNET_BINARY_PV Present_Value[MAX_BINARY_INPUTS]; /* out of service decouples physical input from Present_Value */ static bool Out_Of_Service[MAX_BINARY_INPUTS]; +/* Change of Value flag */ +static bool Change_Of_Value[MAX_BINARY_INPUTS]; /* These three arrays are used by the ReadPropertyMultiple handler */ static const int Binary_Input_Properties_Required[] = { @@ -168,6 +170,19 @@ static bool Binary_Input_Out_Of_Service( return value; } +bool Binary_Input_Change_Of_Value( + uint32_t object_instance) +{ + bool status = false; + + index = Binary_Input_Instance_To_Index(object_instance); + if (index < MAX_BINARY_INPUTS) { + status = Change_Of_Value[index]; + } + + return status; +} + static void Binary_Input_Present_Value_Set( uint32_t object_instance, BACNET_BINARY_PV value) @@ -176,8 +191,12 @@ static void Binary_Input_Present_Value_Set( Binary_Input_Init(); index = Binary_Input_Instance_To_Index(object_instance); - if (index < MAX_BINARY_INPUTS) + if (index < MAX_BINARY_INPUTS) { + if (Present_Value[index] != value) { + Change_Of_Value[index] = true; + } Present_Value[index] = value; + } return; } @@ -191,6 +210,9 @@ static void Binary_Input_Out_Of_Service_Set( Binary_Input_Init(); index = Binary_Input_Instance_To_Index(object_instance); if (index < MAX_BINARY_INPUTS) + if (Out_Of_Service[index] != value) { + Change_Of_Value[index] = true; + } Out_Of_Service[index] = value; return; @@ -257,7 +279,11 @@ int Binary_Input_Encode_Property_APDU( bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false); bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false); bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false); - bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false); + if (Binary_Input_Out_Of_Service(object_instance)) { + bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, true); + } else { + bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false); + } apdu_len = encode_application_bitstring(&apdu[0], &bit_string); break; case PROP_EVENT_STATE: diff --git a/bacnet-stack/include/bi.h b/bacnet-stack/include/bi.h index be36b36b..4f6a7ac0 100644 --- a/bacnet-stack/include/bi.h +++ b/bacnet-stack/include/bi.h @@ -45,7 +45,8 @@ extern "C" { unsigned index); char *Binary_Input_Name( uint32_t object_instance); - + bool Binary_Input_Change_Of_Value( + uint32_t object_instance); int Binary_Input_Encode_Property_APDU( uint8_t * apdu, uint32_t object_instance,