Did a little refactoring for object properties.

This commit is contained in:
skarg
2010-02-16 22:48:09 +00:00
parent b60af74651
commit 2b2077a329
5 changed files with 188 additions and 267 deletions
+1 -20
View File
@@ -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],
+2 -20
View File
@@ -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);
+2 -21
View File
@@ -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);
+2 -20
View File
@@ -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);
+181 -186
View File
@@ -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;