Did a little refactoring for object properties.
This commit is contained in:
@@ -55,7 +55,6 @@ static const int Analog_Input_Properties_Required[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const int Analog_Input_Properties_Optional[] = {
|
static const int Analog_Input_Properties_Optional[] = {
|
||||||
PROP_DESCRIPTION,
|
|
||||||
-1
|
-1
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -151,7 +150,6 @@ int Analog_Input_Read_Property(
|
|||||||
{
|
{
|
||||||
int apdu_len = 0; /* return value */
|
int apdu_len = 0; /* return value */
|
||||||
BACNET_BIT_STRING bit_string;
|
BACNET_BIT_STRING bit_string;
|
||||||
BACNET_CHARACTER_STRING char_string;
|
|
||||||
uint8_t *apdu = NULL;
|
uint8_t *apdu = NULL;
|
||||||
|
|
||||||
if ((rpdata == NULL) ||
|
if ((rpdata == NULL) ||
|
||||||
@@ -161,24 +159,7 @@ int Analog_Input_Read_Property(
|
|||||||
}
|
}
|
||||||
apdu = rpdata->application_data;
|
apdu = rpdata->application_data;
|
||||||
switch (rpdata->object_property) {
|
switch (rpdata->object_property) {
|
||||||
case PROP_OBJECT_IDENTIFIER:
|
/* object id, object name, object type are handled in Device object */
|
||||||
apdu_len =
|
|
||||||
encode_application_object_id(&apdu[0], OBJECT_ANALOG_INPUT,
|
|
||||||
rpdata->object_instance);
|
|
||||||
break;
|
|
||||||
/* note: Name and Description don't have to be the same.
|
|
||||||
You could make Description writable and different */
|
|
||||||
case PROP_OBJECT_NAME:
|
|
||||||
case PROP_DESCRIPTION:
|
|
||||||
characterstring_init_ansi(&char_string,
|
|
||||||
Analog_Input_Name(rpdata->object_instance));
|
|
||||||
apdu_len =
|
|
||||||
encode_application_character_string(&apdu[0], &char_string);
|
|
||||||
break;
|
|
||||||
case PROP_OBJECT_TYPE:
|
|
||||||
apdu_len =
|
|
||||||
encode_application_enumerated(&apdu[0], OBJECT_ANALOG_INPUT);
|
|
||||||
break;
|
|
||||||
case PROP_PRESENT_VALUE:
|
case PROP_PRESENT_VALUE:
|
||||||
apdu_len =
|
apdu_len =
|
||||||
encode_application_real(&apdu[0],
|
encode_application_real(&apdu[0],
|
||||||
|
|||||||
@@ -63,7 +63,6 @@ static const int Analog_Value_Properties_Required[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const int Analog_Value_Properties_Optional[] = {
|
static const int Analog_Value_Properties_Optional[] = {
|
||||||
PROP_DESCRIPTION,
|
|
||||||
#if 0
|
#if 0
|
||||||
PROP_PRIORITY_ARRAY,
|
PROP_PRIORITY_ARRAY,
|
||||||
PROP_RELINQUISH_DEFAULT,
|
PROP_RELINQUISH_DEFAULT,
|
||||||
@@ -201,7 +200,6 @@ int Analog_Value_Read_Property(
|
|||||||
{
|
{
|
||||||
int apdu_len = 0; /* return value */
|
int apdu_len = 0; /* return value */
|
||||||
BACNET_BIT_STRING bit_string;
|
BACNET_BIT_STRING bit_string;
|
||||||
BACNET_CHARACTER_STRING char_string;
|
|
||||||
float real_value = 1.414F;
|
float real_value = 1.414F;
|
||||||
#if 0
|
#if 0
|
||||||
unsigned object_index = 0;
|
unsigned object_index = 0;
|
||||||
@@ -210,29 +208,13 @@ int Analog_Value_Read_Property(
|
|||||||
#endif
|
#endif
|
||||||
uint8_t *apdu = NULL;
|
uint8_t *apdu = NULL;
|
||||||
|
|
||||||
if ((rpdata == NULL) ||
|
if ((rpdata->application_data == NULL) ||
|
||||||
(rpdata->application_data == NULL) ||
|
|
||||||
(rpdata->application_data_len == 0)) {
|
(rpdata->application_data_len == 0)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
apdu = rpdata->application_data;
|
apdu = rpdata->application_data;
|
||||||
switch (rpdata->object_property) {
|
switch (rpdata->object_property) {
|
||||||
case PROP_OBJECT_IDENTIFIER:
|
/* object id, object name, object type are handled in Device object */
|
||||||
apdu_len =
|
|
||||||
encode_application_object_id(&apdu[0], OBJECT_ANALOG_VALUE,
|
|
||||||
rpdata->object_instance);
|
|
||||||
break;
|
|
||||||
case PROP_OBJECT_NAME:
|
|
||||||
case PROP_DESCRIPTION:
|
|
||||||
characterstring_init_ansi(&char_string,
|
|
||||||
Analog_Value_Name(rpdata->object_instance));
|
|
||||||
apdu_len =
|
|
||||||
encode_application_character_string(&apdu[0], &char_string);
|
|
||||||
break;
|
|
||||||
case PROP_OBJECT_TYPE:
|
|
||||||
apdu_len =
|
|
||||||
encode_application_enumerated(&apdu[0], OBJECT_ANALOG_VALUE);
|
|
||||||
break;
|
|
||||||
case PROP_PRESENT_VALUE:
|
case PROP_PRESENT_VALUE:
|
||||||
real_value = Analog_Value_Present_Value(rpdata->object_instance);
|
real_value = Analog_Value_Present_Value(rpdata->object_instance);
|
||||||
apdu_len = encode_application_real(&apdu[0], real_value);
|
apdu_len = encode_application_real(&apdu[0], real_value);
|
||||||
|
|||||||
@@ -55,7 +55,6 @@ static const int Binary_Input_Properties_Required[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const int Binary_Input_Properties_Optional[] = {
|
static const int Binary_Input_Properties_Optional[] = {
|
||||||
PROP_DESCRIPTION,
|
|
||||||
-1
|
-1
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -178,35 +177,17 @@ int Binary_Input_Read_Property(
|
|||||||
{
|
{
|
||||||
int apdu_len = 0; /* return value */
|
int apdu_len = 0; /* return value */
|
||||||
BACNET_BIT_STRING bit_string;
|
BACNET_BIT_STRING bit_string;
|
||||||
BACNET_CHARACTER_STRING char_string;
|
|
||||||
BACNET_POLARITY polarity = POLARITY_NORMAL;
|
BACNET_POLARITY polarity = POLARITY_NORMAL;
|
||||||
BACNET_BINARY_PV value = BINARY_INACTIVE;
|
BACNET_BINARY_PV value = BINARY_INACTIVE;
|
||||||
uint8_t *apdu = NULL;
|
uint8_t *apdu = NULL;
|
||||||
|
|
||||||
if ((rpdata == NULL) ||
|
if ((rpdata->application_data == NULL) ||
|
||||||
(rpdata->application_data == NULL) ||
|
|
||||||
(rpdata->application_data_len == 0)) {
|
(rpdata->application_data_len == 0)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
apdu = rpdata->application_data;
|
apdu = rpdata->application_data;
|
||||||
switch (rpdata->object_property) {
|
switch (rpdata->object_property) {
|
||||||
case PROP_OBJECT_IDENTIFIER:
|
/* object id, object name, object type are handled in Device object */
|
||||||
apdu_len =
|
|
||||||
encode_application_object_id(&apdu[0], OBJECT_BINARY_INPUT,
|
|
||||||
rpdata->object_instance);
|
|
||||||
break;
|
|
||||||
case PROP_OBJECT_NAME:
|
|
||||||
case PROP_DESCRIPTION:
|
|
||||||
/* note: object name must be unique in our device */
|
|
||||||
characterstring_init_ansi(&char_string,
|
|
||||||
Binary_Input_Name(rpdata->object_instance));
|
|
||||||
apdu_len =
|
|
||||||
encode_application_character_string(&apdu[0], &char_string);
|
|
||||||
break;
|
|
||||||
case PROP_OBJECT_TYPE:
|
|
||||||
apdu_len =
|
|
||||||
encode_application_enumerated(&apdu[0], OBJECT_BINARY_INPUT);
|
|
||||||
break;
|
|
||||||
case PROP_PRESENT_VALUE:
|
case PROP_PRESENT_VALUE:
|
||||||
value = Binary_Input_Present_Value(rpdata->object_instance);
|
value = Binary_Input_Present_Value(rpdata->object_instance);
|
||||||
apdu_len = encode_application_enumerated(&apdu[0], value);
|
apdu_len = encode_application_enumerated(&apdu[0], value);
|
||||||
|
|||||||
@@ -272,31 +272,13 @@ int Binary_Output_Read_Property(
|
|||||||
bool state = false;
|
bool state = false;
|
||||||
uint8_t *apdu = NULL;
|
uint8_t *apdu = NULL;
|
||||||
|
|
||||||
if ((rpdata == NULL) ||
|
if ((rpdata->application_data == NULL) ||
|
||||||
(rpdata->application_data == NULL) ||
|
|
||||||
(rpdata->application_data_len == 0)) {
|
(rpdata->application_data_len == 0)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
apdu = rpdata->application_data;
|
apdu = rpdata->application_data;
|
||||||
switch (rpdata->object_property) {
|
switch (rpdata->object_property) {
|
||||||
case PROP_OBJECT_IDENTIFIER:
|
/* object id, object name, object type are handled in Device object */
|
||||||
apdu_len =
|
|
||||||
encode_application_object_id(&apdu[0], OBJECT_BINARY_OUTPUT,
|
|
||||||
rpdata->object_instance);
|
|
||||||
break;
|
|
||||||
/* note: Name and Description don't have to be the same.
|
|
||||||
You could make Description writable and different */
|
|
||||||
case PROP_OBJECT_NAME:
|
|
||||||
case PROP_DESCRIPTION:
|
|
||||||
characterstring_init_ansi(&char_string,
|
|
||||||
Binary_Output_Name(rpdata->object_instance));
|
|
||||||
apdu_len =
|
|
||||||
encode_application_character_string(&apdu[0], &char_string);
|
|
||||||
break;
|
|
||||||
case PROP_OBJECT_TYPE:
|
|
||||||
apdu_len =
|
|
||||||
encode_application_enumerated(&apdu[0], OBJECT_BINARY_OUTPUT);
|
|
||||||
break;
|
|
||||||
case PROP_PRESENT_VALUE:
|
case PROP_PRESENT_VALUE:
|
||||||
present_value = Binary_Output_Present_Value(rpdata->object_instance);
|
present_value = Binary_Output_Present_Value(rpdata->object_instance);
|
||||||
apdu_len = encode_application_enumerated(&apdu[0], present_value);
|
apdu_len = encode_application_enumerated(&apdu[0], present_value);
|
||||||
|
|||||||
@@ -108,155 +108,6 @@ static struct object_functions {
|
|||||||
{MAX_BACNET_OBJECT_TYPE, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
|
{MAX_BACNET_OBJECT_TYPE, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Encodes the property APDU and returns the length,
|
|
||||||
or sets the error, and returns -1 */
|
|
||||||
int Device_Objects_Read_Property(
|
|
||||||
BACNET_READ_PROPERTY_DATA *rpdata)
|
|
||||||
{
|
|
||||||
int apdu_len = -1;
|
|
||||||
unsigned index = 0;
|
|
||||||
struct object_functions *pObject = NULL;
|
|
||||||
bool found = false;
|
|
||||||
|
|
||||||
/* initialize the default return values */
|
|
||||||
rpdata->error_class = ERROR_CLASS_OBJECT;
|
|
||||||
rpdata->error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
|
||||||
pObject = &Object_Table[0];
|
|
||||||
while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) {
|
|
||||||
/* handle each object type */
|
|
||||||
if (pObject->Object_Type == rpdata->object_type) {
|
|
||||||
found = true;
|
|
||||||
if (pObject->Object_Valid_Instance &&
|
|
||||||
pObject->Object_Valid_Instance(rpdata->object_instance)) {
|
|
||||||
if (pObject->Object_Read_Property) {
|
|
||||||
apdu_len = pObject->Object_Read_Property(rpdata);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
rpdata->error_class = ERROR_CLASS_OBJECT;
|
|
||||||
rpdata->error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
index++;
|
|
||||||
pObject = &Object_Table[index];
|
|
||||||
}
|
|
||||||
if (!found) {
|
|
||||||
rpdata->error_class = ERROR_CLASS_OBJECT;
|
|
||||||
rpdata->error_code = ERROR_CODE_UNSUPPORTED_OBJECT_TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return apdu_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Device_Objects_Write_Property(
|
|
||||||
BACNET_WRITE_PROPERTY_DATA * wp_data)
|
|
||||||
{
|
|
||||||
int apdu_len = -1;
|
|
||||||
unsigned index = 0;
|
|
||||||
struct object_functions *pObject = NULL;
|
|
||||||
bool found = false;
|
|
||||||
|
|
||||||
/* initialize the default return values */
|
|
||||||
wp_data->error_class = ERROR_CLASS_OBJECT;
|
|
||||||
wp_data->error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
|
||||||
pObject = &Object_Table[0];
|
|
||||||
while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) {
|
|
||||||
/* handle each object type */
|
|
||||||
if (pObject->Object_Type == wp_data->object_type) {
|
|
||||||
found = true;
|
|
||||||
if (pObject->Object_Valid_Instance &&
|
|
||||||
pObject->Object_Valid_Instance(wp_data->object_instance)) {
|
|
||||||
if (pObject->Object_Write_Property) {
|
|
||||||
apdu_len = pObject->Object_Write_Property(wp_data);
|
|
||||||
} else {
|
|
||||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
|
||||||
wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
wp_data->error_class = ERROR_CLASS_OBJECT;
|
|
||||||
wp_data->error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
index++;
|
|
||||||
pObject = &Object_Table[index];
|
|
||||||
}
|
|
||||||
if (!found) {
|
|
||||||
wp_data->error_class = ERROR_CLASS_OBJECT;
|
|
||||||
wp_data->error_code = ERROR_CODE_UNSUPPORTED_OBJECT_TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return apdu_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned property_list_count(
|
|
||||||
const int *pList)
|
|
||||||
{
|
|
||||||
unsigned property_count = 0;
|
|
||||||
|
|
||||||
if (pList) {
|
|
||||||
while (*pList != -1) {
|
|
||||||
property_count++;
|
|
||||||
pList++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return property_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* for a given object type, returns the special property list */
|
|
||||||
static void Device_Objects_Property_List(
|
|
||||||
BACNET_OBJECT_TYPE object_type,
|
|
||||||
struct special_property_list_t *pPropertyList)
|
|
||||||
{
|
|
||||||
rpm_property_lists_function object_property_list = NULL;
|
|
||||||
unsigned index = 0;
|
|
||||||
struct object_functions *pObject = NULL;
|
|
||||||
bool found = false;
|
|
||||||
|
|
||||||
pPropertyList->Required.pList = NULL;
|
|
||||||
pPropertyList->Optional.pList = NULL;
|
|
||||||
pPropertyList->Proprietary.pList = NULL;
|
|
||||||
pObject = &Object_Table[0];
|
|
||||||
while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) {
|
|
||||||
/* handle each object type */
|
|
||||||
if (pObject->Object_Type == object_type) {
|
|
||||||
found = true;
|
|
||||||
object_property_list = pObject->Object_RPM_List;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
index++;
|
|
||||||
pObject = &Object_Table[index];
|
|
||||||
}
|
|
||||||
if (found && object_property_list) {
|
|
||||||
object_property_list(
|
|
||||||
&pPropertyList->Required.pList,
|
|
||||||
&pPropertyList->Optional.pList,
|
|
||||||
&pPropertyList->Proprietary.pList);
|
|
||||||
}
|
|
||||||
/* fill the count */
|
|
||||||
if (pPropertyList->Required.pList) {
|
|
||||||
pPropertyList->Required.count =
|
|
||||||
property_list_count(pPropertyList->Required.pList);
|
|
||||||
} else {
|
|
||||||
pPropertyList->Required.count = 0;
|
|
||||||
}
|
|
||||||
if (pPropertyList->Optional.pList) {
|
|
||||||
pPropertyList->Optional.count =
|
|
||||||
property_list_count(pPropertyList->Optional.pList);
|
|
||||||
} else {
|
|
||||||
pPropertyList->Optional.count = 0;
|
|
||||||
}
|
|
||||||
if (pPropertyList->Proprietary.pList) {
|
|
||||||
pPropertyList->Proprietary.count =
|
|
||||||
property_list_count(pPropertyList->Proprietary.pList);
|
|
||||||
} else {
|
|
||||||
pPropertyList->Proprietary.count = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* note: you really only need to define variables for
|
/* note: you really only need to define variables for
|
||||||
properties that are writable or that may change.
|
properties that are writable or that may change.
|
||||||
The properties that are constant can be hard coded
|
The properties that are constant can be hard coded
|
||||||
@@ -306,6 +157,179 @@ static const int Device_Properties_Proprietary[] = {
|
|||||||
-1
|
-1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct object_functions * Device_Objects_Find_Functions(
|
||||||
|
BACNET_OBJECT_TYPE Object_Type)
|
||||||
|
{
|
||||||
|
struct object_functions *pObject = NULL;
|
||||||
|
|
||||||
|
pObject = &Object_Table[0];
|
||||||
|
while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) {
|
||||||
|
/* handle each object type */
|
||||||
|
if (pObject->Object_Type == Object_Type) {
|
||||||
|
return(pObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
pObject++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int Read_Property_Common(
|
||||||
|
struct object_functions *pObject,
|
||||||
|
BACNET_READ_PROPERTY_DATA *rpdata)
|
||||||
|
{
|
||||||
|
int apdu_len = -1;
|
||||||
|
BACNET_CHARACTER_STRING char_string;
|
||||||
|
char *pString = "";
|
||||||
|
uint8_t *apdu = NULL;
|
||||||
|
|
||||||
|
if ((rpdata->application_data == NULL) ||
|
||||||
|
(rpdata->application_data_len == 0)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
apdu = rpdata->application_data;
|
||||||
|
switch (rpdata->object_property) {
|
||||||
|
case PROP_OBJECT_IDENTIFIER:
|
||||||
|
/* Device Object exception: requested instance
|
||||||
|
may not match our instance if a wildcard */
|
||||||
|
if (rpdata->object_type == OBJECT_DEVICE) {
|
||||||
|
rpdata->object_instance = Object_Instance_Number;
|
||||||
|
}
|
||||||
|
apdu_len =
|
||||||
|
encode_application_object_id(&apdu[0],
|
||||||
|
rpdata->object_type,
|
||||||
|
rpdata->object_instance);
|
||||||
|
break;
|
||||||
|
case PROP_OBJECT_NAME:
|
||||||
|
if (pObject->Object_Name) {
|
||||||
|
pString = pObject->Object_Name(rpdata->object_instance);
|
||||||
|
}
|
||||||
|
characterstring_init_ansi(&char_string, pString);
|
||||||
|
apdu_len =
|
||||||
|
encode_application_character_string(&apdu[0], &char_string);
|
||||||
|
break;
|
||||||
|
case PROP_OBJECT_TYPE:
|
||||||
|
apdu_len = encode_application_enumerated(&apdu[0],
|
||||||
|
rpdata->object_type);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (pObject->Object_Read_Property) {
|
||||||
|
apdu_len = pObject->Object_Read_Property(rpdata);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return apdu_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Encodes the property APDU and returns the length,
|
||||||
|
or sets the error, and returns -1 */
|
||||||
|
int Device_Objects_Read_Property(
|
||||||
|
BACNET_READ_PROPERTY_DATA *rpdata)
|
||||||
|
{
|
||||||
|
int apdu_len = -1;
|
||||||
|
struct object_functions *pObject = NULL;
|
||||||
|
|
||||||
|
/* initialize the default return values */
|
||||||
|
pObject = Device_Objects_Find_Functions(rpdata->object_type);
|
||||||
|
if (pObject) {
|
||||||
|
if (pObject->Object_Valid_Instance &&
|
||||||
|
pObject->Object_Valid_Instance(rpdata->object_instance)) {
|
||||||
|
apdu_len = Read_Property_Common(pObject, rpdata);
|
||||||
|
} else {
|
||||||
|
rpdata->error_class = ERROR_CLASS_OBJECT;
|
||||||
|
rpdata->error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rpdata->error_class = ERROR_CLASS_OBJECT;
|
||||||
|
rpdata->error_code = ERROR_CODE_UNSUPPORTED_OBJECT_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return apdu_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Device_Objects_Write_Property(
|
||||||
|
BACNET_WRITE_PROPERTY_DATA * wp_data)
|
||||||
|
{
|
||||||
|
int apdu_len = -1;
|
||||||
|
struct object_functions *pObject = NULL;
|
||||||
|
|
||||||
|
/* initialize the default return values */
|
||||||
|
pObject = Device_Objects_Find_Functions(wp_data->object_type);
|
||||||
|
if (pObject) {
|
||||||
|
if (pObject->Object_Valid_Instance &&
|
||||||
|
pObject->Object_Valid_Instance(wp_data->object_instance)) {
|
||||||
|
if (pObject->Object_Write_Property) {
|
||||||
|
apdu_len = pObject->Object_Write_Property(wp_data);
|
||||||
|
} else {
|
||||||
|
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||||
|
wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
wp_data->error_class = ERROR_CLASS_OBJECT;
|
||||||
|
wp_data->error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
wp_data->error_class = ERROR_CLASS_OBJECT;
|
||||||
|
wp_data->error_code = ERROR_CODE_UNSUPPORTED_OBJECT_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return apdu_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned property_list_count(
|
||||||
|
const int *pList)
|
||||||
|
{
|
||||||
|
unsigned property_count = 0;
|
||||||
|
|
||||||
|
if (pList) {
|
||||||
|
while (*pList != -1) {
|
||||||
|
property_count++;
|
||||||
|
pList++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return property_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* for a given object type, returns the special property list */
|
||||||
|
static void Device_Objects_Property_List(
|
||||||
|
BACNET_OBJECT_TYPE object_type,
|
||||||
|
struct special_property_list_t *pPropertyList)
|
||||||
|
{
|
||||||
|
struct object_functions *pObject = NULL;
|
||||||
|
|
||||||
|
pPropertyList->Required.pList = NULL;
|
||||||
|
pPropertyList->Optional.pList = NULL;
|
||||||
|
pPropertyList->Proprietary.pList = NULL;
|
||||||
|
|
||||||
|
/* If we can find an entry for the required object type
|
||||||
|
* and there is an Object_List_RPM fn ptr then call it
|
||||||
|
* to populate the pointers to the individual list counters.
|
||||||
|
*/
|
||||||
|
|
||||||
|
pObject = Device_Objects_Find_Functions(object_type);
|
||||||
|
if ((pObject != NULL) && (pObject->Object_RPM_List != NULL)) {
|
||||||
|
pObject->Object_RPM_List(
|
||||||
|
&pPropertyList->Required.pList,
|
||||||
|
&pPropertyList->Optional.pList,
|
||||||
|
&pPropertyList->Proprietary.pList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fetch the counts if available otherwise zero them */
|
||||||
|
pPropertyList->Required.count = pPropertyList->Required.pList == NULL
|
||||||
|
? 0 : property_list_count(pPropertyList->Required.pList);
|
||||||
|
|
||||||
|
pPropertyList->Optional.count = pPropertyList->Optional.pList == NULL
|
||||||
|
? 0 : property_list_count(pPropertyList->Optional.pList);
|
||||||
|
|
||||||
|
pPropertyList->Proprietary.count = pPropertyList->Proprietary.pList == NULL
|
||||||
|
? 0 : property_list_count(pPropertyList->Proprietary.pList);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
void Device_Property_Lists(
|
void Device_Property_Lists(
|
||||||
const int **pRequired,
|
const int **pRequired,
|
||||||
const int **pOptional,
|
const int **pOptional,
|
||||||
@@ -352,7 +376,6 @@ void Device_Reinit(
|
|||||||
void Device_Init(
|
void Device_Init(
|
||||||
void)
|
void)
|
||||||
{
|
{
|
||||||
unsigned index = 0; /* loop counter */
|
|
||||||
struct object_functions *pObject = NULL;
|
struct object_functions *pObject = NULL;
|
||||||
|
|
||||||
handler_read_property_function_set(Device_Objects_Read_Property);
|
handler_read_property_function_set(Device_Objects_Read_Property);
|
||||||
@@ -365,8 +388,7 @@ void Device_Init(
|
|||||||
if (pObject->Object_Init) {
|
if (pObject->Object_Init) {
|
||||||
pObject->Object_Init();
|
pObject->Object_Init();
|
||||||
}
|
}
|
||||||
index++;
|
pObject++;
|
||||||
pObject = &Object_Table[index];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Reinitialize_State = REINITIALIZED_STATE_IDLE;
|
Reinitialize_State = REINITIALIZED_STATE_IDLE;
|
||||||
@@ -477,7 +499,6 @@ unsigned Device_Object_List_Count(
|
|||||||
void)
|
void)
|
||||||
{
|
{
|
||||||
unsigned count = 0; /* number of objects */
|
unsigned count = 0; /* number of objects */
|
||||||
unsigned index = 0; /* loop counter */
|
|
||||||
struct object_functions *pObject = NULL;
|
struct object_functions *pObject = NULL;
|
||||||
|
|
||||||
/* initialize the default return values */
|
/* initialize the default return values */
|
||||||
@@ -486,8 +507,7 @@ unsigned Device_Object_List_Count(
|
|||||||
if (pObject->Object_Count) {
|
if (pObject->Object_Count) {
|
||||||
count += pObject->Object_Count();
|
count += pObject->Object_Count();
|
||||||
}
|
}
|
||||||
index++;
|
pObject++;
|
||||||
pObject = &Object_Table[index];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
@@ -501,7 +521,6 @@ bool Device_Object_List_Identifier(
|
|||||||
bool status = false;
|
bool status = false;
|
||||||
unsigned count = 0;
|
unsigned count = 0;
|
||||||
unsigned object_index = 0;
|
unsigned object_index = 0;
|
||||||
unsigned index = 0; /* loop counter */
|
|
||||||
struct object_functions *pObject = NULL;
|
struct object_functions *pObject = NULL;
|
||||||
|
|
||||||
/* array index zero is length - so invalid */
|
/* array index zero is length - so invalid */
|
||||||
@@ -523,8 +542,7 @@ bool Device_Object_List_Identifier(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
index++;
|
pObject++;
|
||||||
pObject = &Object_Table[index];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
@@ -569,18 +587,11 @@ char *Device_Valid_Object_Id(
|
|||||||
uint32_t object_instance)
|
uint32_t object_instance)
|
||||||
{
|
{
|
||||||
char *name = NULL; /* return value */
|
char *name = NULL; /* return value */
|
||||||
unsigned index = 0; /* loop counter */
|
|
||||||
struct object_functions *pObject = NULL;
|
struct object_functions *pObject = NULL;
|
||||||
|
|
||||||
pObject = &Object_Table[0];
|
pObject = Device_Objects_Find_Functions(object_type);
|
||||||
while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) {
|
if ((pObject) && (pObject->Object_Name)) {
|
||||||
if ((pObject->Object_Type == object_type) &&
|
name = pObject->Object_Name(object_instance);
|
||||||
(pObject->Object_Name)) {
|
|
||||||
name = pObject->Object_Name(object_instance);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
index++;
|
|
||||||
pObject = &Object_Table[index];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return name;
|
return name;
|
||||||
@@ -601,27 +612,12 @@ int Device_Read_Property(
|
|||||||
uint8_t *apdu = NULL;
|
uint8_t *apdu = NULL;
|
||||||
struct object_functions *pObject = NULL;
|
struct object_functions *pObject = NULL;
|
||||||
|
|
||||||
if ((rpdata == NULL) ||
|
if ((rpdata->application_data == NULL) ||
|
||||||
(rpdata->application_data == NULL) ||
|
|
||||||
(rpdata->application_data_len == 0)) {
|
(rpdata->application_data_len == 0)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
apdu = rpdata->application_data;
|
apdu = rpdata->application_data;
|
||||||
switch (rpdata->object_property) {
|
switch (rpdata->object_property) {
|
||||||
case PROP_OBJECT_IDENTIFIER:
|
|
||||||
apdu_len =
|
|
||||||
encode_application_object_id(&apdu[0], OBJECT_DEVICE,
|
|
||||||
Object_Instance_Number);
|
|
||||||
break;
|
|
||||||
case PROP_OBJECT_NAME:
|
|
||||||
characterstring_init(&char_string, My_Object_Name_Encoding,
|
|
||||||
(char *) &My_Object_Name[0], My_Object_Name_Length);
|
|
||||||
apdu_len =
|
|
||||||
encode_application_character_string(&apdu[0], &char_string);
|
|
||||||
break;
|
|
||||||
case PROP_OBJECT_TYPE:
|
|
||||||
apdu_len = encode_application_enumerated(&apdu[0], OBJECT_DEVICE);
|
|
||||||
break;
|
|
||||||
case PROP_DESCRIPTION:
|
case PROP_DESCRIPTION:
|
||||||
characterstring_init_ansi(&char_string, "BACnet Development Kit");
|
characterstring_init_ansi(&char_string, "BACnet Development Kit");
|
||||||
apdu_len =
|
apdu_len =
|
||||||
@@ -691,8 +687,7 @@ int Device_Read_Property(
|
|||||||
(pObject->Object_Count() > 0)) {
|
(pObject->Object_Count() > 0)) {
|
||||||
bitstring_set_bit(&bit_string, pObject->Object_Type, true);
|
bitstring_set_bit(&bit_string, pObject->Object_Type, true);
|
||||||
}
|
}
|
||||||
i++;
|
pObject++;
|
||||||
pObject = &Object_Table[i];
|
|
||||||
}
|
}
|
||||||
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
|
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user