From 2eb5d05ce89116bd83c2c3d6fd9f7111c3c2b46d Mon Sep 17 00:00:00 2001 From: skarg Date: Wed, 25 Jan 2006 12:14:33 +0000 Subject: [PATCH] Created an automatic way to determine the services supported for the device object by using the handlers list. --- bacnet-stack/apdu.c | 111 ++++++++++++++++++++++++++++++ bacnet-stack/apdu.h | 11 +++ bacnet-stack/demo/object/device.c | 17 ++--- 3 files changed, 131 insertions(+), 8 deletions(-) diff --git a/bacnet-stack/apdu.c b/bacnet-stack/apdu.c index c2d9ec8e..4d17af5e 100644 --- a/bacnet-stack/apdu.c +++ b/bacnet-stack/apdu.c @@ -42,6 +42,56 @@ #include "tsm.h" #include "iam.h" +/* a simple table for crossing the services supported */ +static BACNET_SERVICES_SUPPORTED confirmed_service_supported[MAX_BACNET_CONFIRMED_SERVICE] = +{ + SERVICE_SUPPORTED_ACKNOWLEDGE_ALARM, + SERVICE_SUPPORTED_CONFIRMED_COV_NOTIFICATION, + SERVICE_SUPPORTED_CONFIRMED_EVENT_NOTIFICATION, + SERVICE_SUPPORTED_GET_ALARM_SUMMARY, + SERVICE_SUPPORTED_GET_ENROLLMENT_SUMMARY, + SERVICE_SUPPORTED_SUBSCRIBE_COV, + SERVICE_SUPPORTED_ATOMIC_READ_FILE, + SERVICE_SUPPORTED_ATOMIC_WRITE_FILE, + SERVICE_SUPPORTED_ADD_LIST_ELEMENT, + SERVICE_SUPPORTED_REMOVE_LIST_ELEMENT, + SERVICE_SUPPORTED_CREATE_OBJECT, + SERVICE_SUPPORTED_DELETE_OBJECT, + SERVICE_SUPPORTED_READ_PROPERTY, + SERVICE_SUPPORTED_READ_PROPERTY_CONDITIONAL, + SERVICE_SUPPORTED_READ_PROPERTY_MULTIPLE, + SERVICE_SUPPORTED_WRITE_PROPERTY, + SERVICE_SUPPORTED_WRITE_PROPERTY_MULTIPLE, + SERVICE_SUPPORTED_DEVICE_COMMUNICATION_CONTROL, + SERVICE_SUPPORTED_PRIVATE_TRANSFER, + SERVICE_SUPPORTED_TEXT_MESSAGE, + SERVICE_SUPPORTED_REINITIALIZE_DEVICE, + SERVICE_SUPPORTED_VT_OPEN, + SERVICE_SUPPORTED_VT_CLOSE, + SERVICE_SUPPORTED_VT_DATA, + SERVICE_SUPPORTED_AUTHENTICATE, + SERVICE_SUPPORTED_REQUEST_KEY, + SERVICE_SUPPORTED_READ_RANGE, + SERVICE_SUPPORTED_LIFE_SAFETY_OPERATION, + SERVICE_SUPPORTED_SUBSCRIBE_COV_PROPERTY, + SERVICE_SUPPORTED_GET_EVENT_INFORMATION +}; + +/* a simple table for crossing the services supported */ +static BACNET_SERVICES_SUPPORTED unconfirmed_service_supported[MAX_BACNET_UNCONFIRMED_SERVICE] = +{ + SERVICE_SUPPORTED_I_AM, + SERVICE_SUPPORTED_I_HAVE, + SERVICE_SUPPORTED_UNCONFIRMED_COV_NOTIFICATION, + SERVICE_SUPPORTED_UNCONFIRMED_EVENT_NOTIFICATION, + SERVICE_SUPPORTED_UNCONFIRMED_PRIVATE_TRANSFER, + SERVICE_SUPPORTED_UNCONFIRMED_TEXT_MESSAGE, + SERVICE_SUPPORTED_TIME_SYNCHRONIZATION, + SERVICE_SUPPORTED_WHO_HAS, + SERVICE_SUPPORTED_WHO_IS, + SERVICE_SUPPORTED_UTC_TIME_SYNCHRONIZATION +}; + // Confirmed Function Handlers // If they are not set, they are handled by a reject message static confirmed_function @@ -55,6 +105,56 @@ void apdu_set_confirmed_handler( Confirmed_Function[service_choice] = pFunction; } +/* returns true if the handler is set */ +bool apdu_confirmed_handler( + BACNET_CONFIRMED_SERVICE service_choice) +{ + bool status = false; + if ((service_choice < MAX_BACNET_CONFIRMED_SERVICE) && + (Confirmed_Function[service_choice] != NULL)) + status = true; + + return status; +} + +bool apdu_service_supported(BACNET_SERVICES_SUPPORTED service_supported) +{ + int i = 0; + bool status = false; + bool found = false; + int service = 0; + + if (service_supported < MAX_BACNET_SERVICES_SUPPORTED) + { + /* is it a confirmed service? */ + for (i = 0; i < MAX_BACNET_CONFIRMED_SERVICE; i++) + { + if (confirmed_service_supported[i] == service_supported) + { + if (apdu_confirmed_handler(i)) + status = true; + found = true; + break; + } + } + + if (!found) + { + /* is it an unconfirmed service? */ + for (i = 0; i < MAX_BACNET_UNCONFIRMED_SERVICE; i++) + { + if (unconfirmed_service_supported[i] == service_supported) + { + if (apdu_unconfirmed_handler(i)) + status = true; + break; + } + } + } + } + return status; +} + // Allow the APDU handler to automatically reject static confirmed_function Unrecognized_Service_Handler; @@ -80,6 +180,17 @@ void apdu_set_unconfirmed_handler( Unconfirmed_Function[service_choice] = pFunction; } +bool apdu_unconfirmed_handler( + BACNET_UNCONFIRMED_SERVICE service_choice) +{ + bool status = false; + + if ((service_choice < MAX_BACNET_UNCONFIRMED_SERVICE) && + (Unconfirmed_Function[service_choice] != NULL)) + status = true; + + return status; +} // Confirmed ACK Function Handlers static void *Confirmed_ACK_Function[MAX_BACNET_CONFIRMED_SERVICE]; diff --git a/bacnet-stack/apdu.h b/bacnet-stack/apdu.h index 4a2335d9..0f8ded8f 100644 --- a/bacnet-stack/apdu.h +++ b/bacnet-stack/apdu.h @@ -144,10 +144,21 @@ void apdu_set_confirmed_handler( BACNET_CONFIRMED_SERVICE service_choice, confirmed_function pFunction); +/* returns true if the handler is set */ +bool apdu_confirmed_handler( + BACNET_CONFIRMED_SERVICE service_choice); + void apdu_set_unconfirmed_handler( BACNET_UNCONFIRMED_SERVICE service_choice, unconfirmed_function pFunction); +/* returns true if the handler is set */ +bool apdu_unconfirmed_handler( + BACNET_UNCONFIRMED_SERVICE service_choice); + +/* returns true if the service is supported by a handler */ +bool apdu_service_supported(BACNET_SERVICES_SUPPORTED service_supported); + void apdu_set_error_handler( BACNET_CONFIRMED_SERVICE service_choice, error_function pFunction); diff --git a/bacnet-stack/demo/object/device.c b/bacnet-stack/demo/object/device.c index e1ee2afd..dd0e237e 100644 --- a/bacnet-stack/demo/object/device.c +++ b/bacnet-stack/demo/object/device.c @@ -394,7 +394,7 @@ int Device_Encode_Property_APDU( int object_type = 0; uint32_t instance = 0; unsigned count = 0; - + switch (property) { case PROP_OBJECT_IDENTIFIER: @@ -463,20 +463,18 @@ int Device_Encode_Property_APDU( apdu_len = encode_tagged_unsigned(&apdu[0], 1); break; case PROP_PROTOCOL_SERVICES_SUPPORTED: + /* Note: list of services that are executed, not initiated. */ bitstring_init(&bit_string); for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++) { - // bitstring_set_bit(&bit_string, i, apdu_service_supported(i)); - // initialize all the services to not-supported - bitstring_set_bit(&bit_string, (uint8_t)i, false); + /* automatic lookup based on handlers set */ + bitstring_set_bit(&bit_string, (uint8_t)i, apdu_service_supported(i)); } - /* FIXME: set only the services that YOUR device executes */ - bitstring_set_bit(&bit_string, SERVICE_SUPPORTED_WHO_IS, true); - bitstring_set_bit(&bit_string, SERVICE_SUPPORTED_I_AM, true); - bitstring_set_bit(&bit_string, SERVICE_SUPPORTED_READ_PROPERTY, true); apdu_len = encode_tagged_bitstring(&apdu[0], &bit_string); break; case PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED: + /* Note: this is the list of objects that can be in this device, + not a list of objects that this device can access */ bitstring_init(&bit_string); for (i = 0; i < MAX_ASHRAE_OBJECT_TYPE; i++) { @@ -487,6 +485,9 @@ int Device_Encode_Property_APDU( bitstring_set_bit(&bit_string, OBJECT_DEVICE, true); bitstring_set_bit(&bit_string, OBJECT_ANALOG_INPUT, true); bitstring_set_bit(&bit_string, OBJECT_ANALOG_OUTPUT, true); + #if BACFILE + bitstring_set_bit(&bit_string, OBJECT_FILE, true); + #endif apdu_len = encode_tagged_bitstring(&apdu[0], &bit_string); break; case PROP_OBJECT_LIST: