Created an automatic way to determine the services supported for the device object by using the handlers list.
This commit is contained in:
@@ -42,6 +42,56 @@
|
|||||||
#include "tsm.h"
|
#include "tsm.h"
|
||||||
#include "iam.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
|
// Confirmed Function Handlers
|
||||||
// If they are not set, they are handled by a reject message
|
// If they are not set, they are handled by a reject message
|
||||||
static confirmed_function
|
static confirmed_function
|
||||||
@@ -55,6 +105,56 @@ void apdu_set_confirmed_handler(
|
|||||||
Confirmed_Function[service_choice] = pFunction;
|
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
|
// Allow the APDU handler to automatically reject
|
||||||
static confirmed_function Unrecognized_Service_Handler;
|
static confirmed_function Unrecognized_Service_Handler;
|
||||||
|
|
||||||
@@ -80,6 +180,17 @@ void apdu_set_unconfirmed_handler(
|
|||||||
Unconfirmed_Function[service_choice] = pFunction;
|
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
|
// Confirmed ACK Function Handlers
|
||||||
static void *Confirmed_ACK_Function[MAX_BACNET_CONFIRMED_SERVICE];
|
static void *Confirmed_ACK_Function[MAX_BACNET_CONFIRMED_SERVICE];
|
||||||
|
|
||||||
|
|||||||
@@ -144,10 +144,21 @@ void apdu_set_confirmed_handler(
|
|||||||
BACNET_CONFIRMED_SERVICE service_choice,
|
BACNET_CONFIRMED_SERVICE service_choice,
|
||||||
confirmed_function pFunction);
|
confirmed_function pFunction);
|
||||||
|
|
||||||
|
/* returns true if the handler is set */
|
||||||
|
bool apdu_confirmed_handler(
|
||||||
|
BACNET_CONFIRMED_SERVICE service_choice);
|
||||||
|
|
||||||
void apdu_set_unconfirmed_handler(
|
void apdu_set_unconfirmed_handler(
|
||||||
BACNET_UNCONFIRMED_SERVICE service_choice,
|
BACNET_UNCONFIRMED_SERVICE service_choice,
|
||||||
unconfirmed_function pFunction);
|
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(
|
void apdu_set_error_handler(
|
||||||
BACNET_CONFIRMED_SERVICE service_choice,
|
BACNET_CONFIRMED_SERVICE service_choice,
|
||||||
error_function pFunction);
|
error_function pFunction);
|
||||||
|
|||||||
@@ -394,7 +394,7 @@ int Device_Encode_Property_APDU(
|
|||||||
int object_type = 0;
|
int object_type = 0;
|
||||||
uint32_t instance = 0;
|
uint32_t instance = 0;
|
||||||
unsigned count = 0;
|
unsigned count = 0;
|
||||||
|
|
||||||
switch (property)
|
switch (property)
|
||||||
{
|
{
|
||||||
case PROP_OBJECT_IDENTIFIER:
|
case PROP_OBJECT_IDENTIFIER:
|
||||||
@@ -463,20 +463,18 @@ int Device_Encode_Property_APDU(
|
|||||||
apdu_len = encode_tagged_unsigned(&apdu[0], 1);
|
apdu_len = encode_tagged_unsigned(&apdu[0], 1);
|
||||||
break;
|
break;
|
||||||
case PROP_PROTOCOL_SERVICES_SUPPORTED:
|
case PROP_PROTOCOL_SERVICES_SUPPORTED:
|
||||||
|
/* Note: list of services that are executed, not initiated. */
|
||||||
bitstring_init(&bit_string);
|
bitstring_init(&bit_string);
|
||||||
for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++)
|
for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++)
|
||||||
{
|
{
|
||||||
// bitstring_set_bit(&bit_string, i, apdu_service_supported(i));
|
/* automatic lookup based on handlers set */
|
||||||
// initialize all the services to not-supported
|
bitstring_set_bit(&bit_string, (uint8_t)i, apdu_service_supported(i));
|
||||||
bitstring_set_bit(&bit_string, (uint8_t)i, false);
|
|
||||||
}
|
}
|
||||||
/* 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);
|
apdu_len = encode_tagged_bitstring(&apdu[0], &bit_string);
|
||||||
break;
|
break;
|
||||||
case PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED:
|
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);
|
bitstring_init(&bit_string);
|
||||||
for (i = 0; i < MAX_ASHRAE_OBJECT_TYPE; i++)
|
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_DEVICE, true);
|
||||||
bitstring_set_bit(&bit_string, OBJECT_ANALOG_INPUT, true);
|
bitstring_set_bit(&bit_string, OBJECT_ANALOG_INPUT, true);
|
||||||
bitstring_set_bit(&bit_string, OBJECT_ANALOG_OUTPUT, 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);
|
apdu_len = encode_tagged_bitstring(&apdu[0], &bit_string);
|
||||||
break;
|
break;
|
||||||
case PROP_OBJECT_LIST:
|
case PROP_OBJECT_LIST:
|
||||||
|
|||||||
Reference in New Issue
Block a user