Changed WhoHas and I-Have to use CharacterString instead of forcing ANSI X34 and C Strings. Affected all demos and ports object name, so I changed the object name function name to make sure it was noticed.
This commit is contained in:
@@ -152,19 +152,21 @@ void Analog_Input_Present_Value_Set(
|
||||
}
|
||||
}
|
||||
|
||||
char *Analog_Input_Name(
|
||||
uint32_t object_instance)
|
||||
bool Analog_Input_Object_Name(
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING *object_name)
|
||||
{
|
||||
static char text_string[32] = ""; /* okay for single thread */
|
||||
unsigned int index;
|
||||
bool status = false;
|
||||
|
||||
index = Analog_Input_Instance_To_Index(object_instance);
|
||||
if (index < MAX_ANALOG_INPUTS) {
|
||||
sprintf(text_string, "ANALOG INPUT %lu", (unsigned long) index);
|
||||
return text_string;
|
||||
status = characterstring_init_ansi(object_name, text_string);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return status;
|
||||
}
|
||||
|
||||
/* return apdu length, or BACNET_STATUS_ERROR on error */
|
||||
@@ -190,8 +192,7 @@ int Analog_Input_Read_Property(
|
||||
break;
|
||||
case PROP_OBJECT_NAME:
|
||||
case PROP_DESCRIPTION:
|
||||
characterstring_init_ansi(&char_string,
|
||||
Analog_Input_Name(rpdata->object_instance));
|
||||
Analog_Input_Object_Name(rpdata->object_instance, &char_string);
|
||||
apdu_len =
|
||||
encode_application_character_string(&apdu[0], &char_string);
|
||||
break;
|
||||
|
||||
@@ -50,8 +50,9 @@ extern "C" {
|
||||
bool Analog_Input_Object_Instance_Add(
|
||||
uint32_t instance);
|
||||
|
||||
char *Analog_Input_Name(
|
||||
uint32_t object_instance);
|
||||
bool Analog_Input_Object_Name(
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING *object_name);
|
||||
bool Analog_Input_Name_Set(
|
||||
uint32_t object_instance,
|
||||
char *new_name);
|
||||
@@ -94,6 +95,6 @@ extern "C" {
|
||||
#define ANALOG_INPUT_OBJ_FUNCTIONS \
|
||||
OBJECT_ANALOG_INPUT, Analog_Input_Init, Analog_Input_Count, \
|
||||
Analog_Input_Index_To_Instance, Analog_Input_Valid_Instance, \
|
||||
Analog_Input_Name, Analog_Input_Read_Property, NULL, \
|
||||
Analog_Input_Object_Name, Analog_Input_Read_Property, NULL, \
|
||||
Analog_Input_Property_Lists, NULL, NULL
|
||||
#endif
|
||||
|
||||
@@ -253,18 +253,20 @@ bool Analog_Output_Present_Value_Relinquish(
|
||||
}
|
||||
|
||||
/* note: the object name must be unique within this device */
|
||||
char *Analog_Output_Name(
|
||||
uint32_t object_instance)
|
||||
bool Analog_Output_Object_Name(
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING *object_name)
|
||||
{
|
||||
static char text_string[32] = ""; /* okay for single thread */
|
||||
bool status = false;
|
||||
|
||||
if (object_instance < MAX_ANALOG_OUTPUTS) {
|
||||
sprintf(text_string, "ANALOG OUTPUT %lu",
|
||||
(unsigned long) object_instance);
|
||||
return text_string;
|
||||
status = characterstring_init_ansi(object_name, text_string);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return status;
|
||||
}
|
||||
|
||||
/* return apdu len, or BACNET_STATUS_ERROR on error */
|
||||
@@ -294,8 +296,7 @@ int Analog_Output_Read_Property(
|
||||
break;
|
||||
case PROP_OBJECT_NAME:
|
||||
case PROP_DESCRIPTION:
|
||||
characterstring_init_ansi(&char_string,
|
||||
Analog_Output_Name(rpdata->object_instance));
|
||||
Analog_Output_Object_Name(rpdata->object_instance, &char_string);
|
||||
apdu_len =
|
||||
encode_application_character_string(&apdu[0], &char_string);
|
||||
break;
|
||||
|
||||
@@ -63,8 +63,9 @@ extern "C" {
|
||||
uint32_t object_instance,
|
||||
unsigned priority);
|
||||
|
||||
char *Analog_Output_Name(
|
||||
uint32_t object_instance);
|
||||
bool Analog_Output_Object_Name(
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING *object_name);
|
||||
bool Analog_Output_Name_Set(
|
||||
uint32_t object_instance,
|
||||
char *new_name);
|
||||
@@ -102,7 +103,7 @@ extern "C" {
|
||||
#define ANALOG_OUTPUT_OBJ_FUNCTIONS \
|
||||
OBJECT_ANALOG_OUTPUT, Analog_Output_Init, Analog_Output_Count, \
|
||||
Analog_Output_Index_To_Instance, Analog_Output_Valid_Instance, \
|
||||
Analog_Output_Name, Analog_Output_Read_Property, \
|
||||
Analog_Output_Object_Name, Analog_Output_Read_Property, \
|
||||
Analog_Output_Write_Property, Analog_Output_Property_Lists, \
|
||||
NULL, NULL
|
||||
#endif
|
||||
|
||||
@@ -201,18 +201,20 @@ float Analog_Value_Present_Value(
|
||||
}
|
||||
|
||||
/* note: the object name must be unique within this device */
|
||||
char *Analog_Value_Name(
|
||||
uint32_t object_instance)
|
||||
bool Analog_Value_Object_Name(
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING *object_name)
|
||||
{
|
||||
static char text_string[32] = ""; /* okay for single thread */
|
||||
bool status = false;
|
||||
|
||||
if (object_instance < MAX_ANALOG_VALUES) {
|
||||
sprintf(text_string, "ANALOG VALUE %lu",
|
||||
(unsigned long) object_instance);
|
||||
return text_string;
|
||||
status = characterstring_init_ansi(object_name, text_string);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return status;
|
||||
}
|
||||
|
||||
/* return apdu len, or BACNET_STATUS_ERROR on error */
|
||||
@@ -242,8 +244,7 @@ int Analog_Value_Read_Property(
|
||||
break;
|
||||
case PROP_OBJECT_NAME:
|
||||
case PROP_DESCRIPTION:
|
||||
characterstring_init_ansi(&char_string,
|
||||
Analog_Value_Name(rpdata->object_instance));
|
||||
Analog_Value_Object_Name(rpdata->object_instance, &char_string);
|
||||
apdu_len =
|
||||
encode_application_character_string(&apdu[0], &char_string);
|
||||
break;
|
||||
|
||||
@@ -47,8 +47,10 @@ extern "C" {
|
||||
unsigned index);
|
||||
unsigned Analog_Value_Instance_To_Index(
|
||||
uint32_t object_instance);
|
||||
char *Analog_Value_Name(
|
||||
uint32_t object_instance);
|
||||
|
||||
bool Analog_Value_Object_Name(
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING *object_name);
|
||||
|
||||
int Analog_Value_Read_Property(
|
||||
BACNET_READ_PROPERTY_DATA * rpdata);
|
||||
@@ -78,7 +80,7 @@ extern "C" {
|
||||
#define ANALOG_VALUE_OBJ_FUNCTIONS \
|
||||
OBJECT_ANALOG_VALUE, Analog_Value_Init, Analog_Value_Count, \
|
||||
Analog_Value_Index_To_Instance, Analog_Value_Valid_Instance, \
|
||||
Analog_Value_Name, Analog_Value_Read_Property, \
|
||||
Analog_Value_Object_Name, Analog_Value_Read_Property, \
|
||||
Analog_Value_Write_Property, Analog_Value_Property_Lists, NULL, \
|
||||
NULL
|
||||
#endif
|
||||
|
||||
@@ -283,18 +283,20 @@ static void Binary_Input_Out_Of_Service_Set(
|
||||
return;
|
||||
}
|
||||
|
||||
char *Binary_Input_Name(
|
||||
uint32_t object_instance)
|
||||
bool Binary_Input_Object_Name(
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING *object_name)
|
||||
{
|
||||
static char text_string[32] = ""; /* okay for single thread */
|
||||
bool status = false;
|
||||
|
||||
if (object_instance < MAX_BINARY_INPUTS) {
|
||||
sprintf(text_string, "BINARY INPUT %lu",
|
||||
(unsigned long) object_instance);
|
||||
return text_string;
|
||||
status = characterstring_init_ansi(object_name, text_string);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return status;
|
||||
}
|
||||
|
||||
BACNET_POLARITY Binary_Input_Polarity(
|
||||
@@ -346,8 +348,7 @@ int Binary_Input_Read_Property(
|
||||
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));
|
||||
Binary_Input_Object_Name(rpdata->object_instance, &char_string);
|
||||
apdu_len =
|
||||
encode_application_character_string(&apdu[0], &char_string);
|
||||
break;
|
||||
|
||||
@@ -52,8 +52,9 @@ extern "C" {
|
||||
bool Binary_Input_Object_Instance_Add(
|
||||
uint32_t instance);
|
||||
|
||||
char *Binary_Input_Name(
|
||||
uint32_t object_instance);
|
||||
bool Binary_Input_Object_Name(
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING *object_name);
|
||||
bool Binary_Input_Name_Set(
|
||||
uint32_t object_instance,
|
||||
char *new_name);
|
||||
@@ -116,6 +117,6 @@ extern "C" {
|
||||
#define BINARY_INPUT_OBJ_FUNCTIONS \
|
||||
OBJECT_BINARY_INPUT, Binary_Input_Init, Binary_Input_Count, \
|
||||
Binary_Input_Index_To_Instance, Binary_Input_Valid_Instance, \
|
||||
Binary_Input_Name, Binary_Input_Read_Property, NULL, \
|
||||
Binary_Input_Object_Name, Binary_Input_Read_Property, NULL, \
|
||||
Binary_Input_Property_Lists, NULL, NULL
|
||||
#endif
|
||||
|
||||
@@ -177,18 +177,20 @@ BACNET_BINARY_PV Binary_Output_Present_Value(
|
||||
}
|
||||
|
||||
/* note: the object name must be unique within this device */
|
||||
char *Binary_Output_Name(
|
||||
uint32_t object_instance)
|
||||
bool Binary_Output_Object_Name(
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING *object_name)
|
||||
{
|
||||
static char text_string[32] = ""; /* okay for single thread */
|
||||
bool status = false;
|
||||
|
||||
if (object_instance < MAX_BINARY_OUTPUTS) {
|
||||
sprintf(text_string, "BINARY OUTPUT %lu",
|
||||
(unsigned long) object_instance);
|
||||
return text_string;
|
||||
status = characterstring_init_ansi(object_name, text_string);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return status;
|
||||
}
|
||||
|
||||
/* return apdu len, or BACNET_STATUS_ERROR on error */
|
||||
@@ -221,8 +223,7 @@ int Binary_Output_Read_Property(
|
||||
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));
|
||||
Binary_Output_Object_Name(rpdata->object_instance, &char_string);
|
||||
apdu_len =
|
||||
encode_application_character_string(&apdu[0], &char_string);
|
||||
break;
|
||||
|
||||
@@ -55,8 +55,9 @@ extern "C" {
|
||||
bool Binary_Output_Object_Instance_Add(
|
||||
uint32_t instance);
|
||||
|
||||
char *Binary_Output_Name(
|
||||
uint32_t object_instance);
|
||||
bool Binary_Output_Object_Name(
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING *object_name);
|
||||
bool Binary_Output_Name_Set(
|
||||
uint32_t object_instance,
|
||||
char *new_name);
|
||||
@@ -111,7 +112,7 @@ extern "C" {
|
||||
#define BINARY_OUTPUT_OBJ_FUNCTIONS \
|
||||
OBJECT_BINARY_OUTPUT, Binary_Output_Init, Binary_Output_Count, \
|
||||
Binary_Output_Index_To_Instance, Binary_Output_Valid_Instance, \
|
||||
Binary_Output_Name, Binary_Output_Read_Property, \
|
||||
Binary_Output_Object_Name, Binary_Output_Read_Property, \
|
||||
Binary_Output_Write_Property, Binary_Output_Property_Lists, \
|
||||
NULL, NULL
|
||||
#endif
|
||||
|
||||
@@ -174,18 +174,20 @@ static BACNET_BINARY_PV Binary_Value_Present_Value(
|
||||
}
|
||||
|
||||
/* note: the object name must be unique within this device */
|
||||
char *Binary_Value_Name(
|
||||
uint32_t object_instance)
|
||||
bool Binary_Value_Object_Name(
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING *object_name)
|
||||
{
|
||||
static char text_string[32] = ""; /* okay for single thread */
|
||||
bool status = false;
|
||||
|
||||
if (object_instance < MAX_BINARY_VALUES) {
|
||||
sprintf(text_string, "BINARY VALUE %lu",
|
||||
(unsigned long) object_instance);
|
||||
return text_string;
|
||||
status = characterstring_init_ansi(object_name, text_string);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return status;
|
||||
}
|
||||
|
||||
/* return apdu len, or BACNET_STATUS_ERROR on error */
|
||||
@@ -217,8 +219,7 @@ int Binary_Value_Read_Property(
|
||||
You could make Description writable and different */
|
||||
case PROP_OBJECT_NAME:
|
||||
case PROP_DESCRIPTION:
|
||||
characterstring_init_ansi(&char_string,
|
||||
Binary_Value_Name(rpdata->object_instance));
|
||||
Binary_Value_Object_Name(rpdata->object_instance, &char_string);
|
||||
apdu_len =
|
||||
encode_application_character_string(&apdu[0], &char_string);
|
||||
break;
|
||||
|
||||
@@ -48,8 +48,10 @@ extern "C" {
|
||||
unsigned index);
|
||||
unsigned Binary_Value_Instance_To_Index(
|
||||
uint32_t object_instance);
|
||||
char *Binary_Value_Name(
|
||||
uint32_t object_instance);
|
||||
|
||||
bool Binary_Value_Object_Name(
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING *object_name);
|
||||
|
||||
void Binary_Value_Init(
|
||||
void);
|
||||
@@ -72,7 +74,7 @@ extern "C" {
|
||||
#define BINARY_VALUE_OBJ_FUNCTIONS \
|
||||
OBJECT_BINARY_VALUE, Binary_Value_Init, Binary_Value_Count, \
|
||||
Binary_Value_Index_To_Instance, Binary_Value_Valid_Instance, \
|
||||
Binary_Value_Name, Binary_Value_Read_Property, \
|
||||
Binary_Value_Object_Name, Binary_Value_Read_Property, \
|
||||
Binary_Value_Write_Property, Binary_Value_Property_Lists, NULL, \
|
||||
NULL
|
||||
#endif
|
||||
|
||||
@@ -289,7 +289,7 @@ void Device_Property_Lists(
|
||||
into the read-property encoding. */
|
||||
|
||||
static uint32_t Object_Instance_Number = 260001;
|
||||
static char My_Object_Name[MAX_DEV_NAME_LEN + 1] = "SimpleServer";
|
||||
static BACNET_CHARACTER_STRING My_Object_Name;
|
||||
static BACNET_DEVICE_STATUS System_Status = STATUS_OPERATIONAL;
|
||||
static char *Vendor_Name = BACNET_VENDOR_NAME;
|
||||
static uint16_t Vendor_Identifier = BACNET_VENDOR_ID;
|
||||
@@ -384,37 +384,28 @@ bool Device_Valid_Object_Instance_Number(
|
||||
(object_id == BACNET_MAX_INSTANCE));
|
||||
}
|
||||
|
||||
char *Device_Name(
|
||||
uint32_t object_instance)
|
||||
bool Device_Object_Name(
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING *object_name)
|
||||
{
|
||||
bool status = false;
|
||||
|
||||
if (object_instance == Object_Instance_Number) {
|
||||
return My_Object_Name;
|
||||
status = characterstring_copy(object_name, &My_Object_Name);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *Device_Object_Name(
|
||||
void)
|
||||
{
|
||||
return My_Object_Name;
|
||||
return status;
|
||||
}
|
||||
|
||||
bool Device_Set_Object_Name(
|
||||
const char *name,
|
||||
size_t length)
|
||||
BACNET_CHARACTER_STRING *object_name)
|
||||
{
|
||||
bool status = false; /*return value */
|
||||
|
||||
/* FIXME: All the object names in a device must be unique.
|
||||
Disallow setting the Device Object Name to any objects in
|
||||
the device. */
|
||||
if (length < sizeof(My_Object_Name)) {
|
||||
if (!characterstring_same(&My_Object_Name, object_name)) {
|
||||
/* Make the change and update the database revision */
|
||||
memmove(My_Object_Name, name, length);
|
||||
My_Object_Name[length] = 0;
|
||||
status = characterstring_copy(&My_Object_Name, object_name);
|
||||
Device_Inc_Database_Revision();
|
||||
status = true;
|
||||
}
|
||||
|
||||
return status;
|
||||
@@ -737,7 +728,7 @@ bool Device_Object_List_Identifier(
|
||||
* @return True on success or else False if not found.
|
||||
*/
|
||||
bool Device_Valid_Object_Name(
|
||||
const char *object_name,
|
||||
BACNET_CHARACTER_STRING *object_name1,
|
||||
int *object_type,
|
||||
uint32_t * object_instance)
|
||||
{
|
||||
@@ -746,14 +737,17 @@ bool Device_Valid_Object_Name(
|
||||
uint32_t instance;
|
||||
unsigned max_objects = 0, i = 0;
|
||||
bool check_id = false;
|
||||
char *name = NULL;
|
||||
BACNET_CHARACTER_STRING object_name2;
|
||||
struct object_functions *pObject = NULL;
|
||||
|
||||
max_objects = Device_Object_List_Count();
|
||||
for (i = 0; i < max_objects; i++) {
|
||||
check_id = Device_Object_List_Identifier(i, &type, &instance);
|
||||
if (check_id) {
|
||||
name = Device_Valid_Object_Id(type, instance);
|
||||
if (strcmp(name, object_name) == 0) {
|
||||
pObject = Device_Objects_Find_Functions(type);
|
||||
if ((pObject != NULL) && (pObject->Object_Name != NULL) &&
|
||||
(pObject->Object_Name(instance, &object_name2) &&
|
||||
characterstring_same(object_name1, &object_name2))) {
|
||||
found = true;
|
||||
if (object_type) {
|
||||
*object_type = type;
|
||||
@@ -774,18 +768,52 @@ bool Device_Valid_Object_Name(
|
||||
* @param object_instance [in] The object instance number to be looked up.
|
||||
* @return The Object Name or else NULL if not found
|
||||
*/
|
||||
char *Device_Valid_Object_Id(
|
||||
bool Device_Valid_Object_Id(
|
||||
int object_type,
|
||||
uint32_t object_instance)
|
||||
{
|
||||
char *name = NULL; /* return value */
|
||||
bool status = false; /* return value */
|
||||
struct object_functions *pObject = NULL;
|
||||
|
||||
pObject = Device_Objects_Find_Functions(object_type);
|
||||
if ((pObject != NULL) && (pObject->Object_Name != NULL))
|
||||
name = pObject->Object_Name(object_instance);
|
||||
if ((pObject != NULL) && (pObject->Object_Valid_Instance != NULL)) {
|
||||
status = pObject->Object_Valid_Instance(object_instance);
|
||||
}
|
||||
|
||||
return name;
|
||||
return status;
|
||||
}
|
||||
|
||||
/** copy a child object object_name value.
|
||||
* @param object_type [out] The BACNET_OBJECT_TYPE of the matching Object.
|
||||
* @param object_instance [out] The object instance number of the matching Object.
|
||||
* @param object_name [in] The desired Object Name to look for.
|
||||
* @return True on success or else False if not found.
|
||||
*/
|
||||
bool Device_Object_Name_Copy(
|
||||
int object_type,
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING *object_name)
|
||||
{
|
||||
struct object_functions *pObject = NULL;
|
||||
bool found = false;
|
||||
int type = 0;
|
||||
uint32_t instance;
|
||||
unsigned max_objects = 0, i = 0;
|
||||
bool check_id = false;
|
||||
|
||||
max_objects = Device_Object_List_Count();
|
||||
for (i = 0; i < max_objects; i++) {
|
||||
check_id = Device_Object_List_Identifier(i, &type, &instance);
|
||||
if (check_id) {
|
||||
pObject = Device_Objects_Find_Functions(type);
|
||||
if ((pObject != NULL) && (pObject->Object_Name != NULL)) {
|
||||
found = pObject->Object_Name(instance, object_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
static void Update_Current_Time(
|
||||
@@ -873,9 +901,8 @@ int Device_Read_Property_Local(
|
||||
Object_Instance_Number);
|
||||
break;
|
||||
case PROP_OBJECT_NAME:
|
||||
characterstring_init_ansi(&char_string, My_Object_Name);
|
||||
apdu_len =
|
||||
encode_application_character_string(&apdu[0], &char_string);
|
||||
encode_application_character_string(&apdu[0], &My_Object_Name);
|
||||
break;
|
||||
case PROP_OBJECT_TYPE:
|
||||
apdu_len = encode_application_enumerated(&apdu[0], OBJECT_DEVICE);
|
||||
@@ -1201,12 +1228,22 @@ bool Device_Write_Property_Local(
|
||||
break;
|
||||
case PROP_OBJECT_NAME:
|
||||
status =
|
||||
WPValidateString(&value, MAX_DEV_NAME_LEN, false,
|
||||
&wp_data->error_class, &wp_data->error_code);
|
||||
WPValidateString(&value,
|
||||
characterstring_capacity(&My_Object_Name),
|
||||
false,
|
||||
&wp_data->error_class, &wp_data->error_code);
|
||||
if (status) {
|
||||
Device_Set_Object_Name(characterstring_value(&value.type.
|
||||
Character_String),
|
||||
characterstring_length(&value.type.Character_String));
|
||||
/* All the object names in a device must be unique.
|
||||
Disallow setting the Device Object Name to any objects in
|
||||
the device. */
|
||||
if (Device_Valid_Object_Name(&value.type.Character_String,
|
||||
NULL, NULL)) {
|
||||
status = false;
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_DUPLICATE_NAME;
|
||||
} else {
|
||||
Device_Set_Object_Name(&value.type.Character_String);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PROP_LOCATION:
|
||||
@@ -1322,26 +1359,22 @@ bool Device_Write_Property(
|
||||
return (status);
|
||||
}
|
||||
|
||||
/** Initialize the group of object helper functions for any supported Object.
|
||||
/** Initialize the Device Object.
|
||||
Initialize the group of object helper functions for any supported Object.
|
||||
Initialize each of the Device Object child Object instances.
|
||||
* @ingroup ObjIntf
|
||||
* @param object_table [in,out] array of structure with object functions.
|
||||
* Each Child Object must provide some implementation of each of these
|
||||
* functions in order to properly support the default handlers.
|
||||
*/
|
||||
void Device_Initialize_Object_Functions(
|
||||
object_functions_t * object_table)
|
||||
{
|
||||
Object_Table = object_table;
|
||||
}
|
||||
|
||||
/** Initialize the Device Object and each of its child Object instances.
|
||||
* @ingroup ObjIntf
|
||||
*/
|
||||
void Device_Init(
|
||||
void)
|
||||
object_functions_t * object_table)
|
||||
{
|
||||
struct object_functions *pObject = NULL;
|
||||
|
||||
characterstring_init_ansi(&My_Object_Name, "SimpleServer");
|
||||
/* call all the child objects initialization functions */
|
||||
Object_Table = object_table;
|
||||
pObject = &Object_Table[0];
|
||||
while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) {
|
||||
if (pObject->Object_Init) {
|
||||
@@ -1412,8 +1445,6 @@ void Routing_Device_Init(
|
||||
{
|
||||
struct object_functions *pDevObject = NULL;
|
||||
|
||||
/* First, do the usual Device_Init() functions: */
|
||||
Device_Init();
|
||||
/* Initialize with our preset strings */
|
||||
Add_Routed_Device(first_object_instance, My_Object_Name, Description);
|
||||
|
||||
|
||||
@@ -71,10 +71,11 @@ typedef uint32_t(
|
||||
* is temporary and should be copied upon the return. It is
|
||||
* allocated by the system and does not need to be freed.
|
||||
*/
|
||||
typedef char *(
|
||||
typedef bool(
|
||||
*object_name_function)
|
||||
(
|
||||
uint32_t object_instance);
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING *object_name);
|
||||
|
||||
/** Look in the table of objects of this type, and see if this is a valid
|
||||
* instance number.
|
||||
@@ -179,8 +180,6 @@ extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
void Device_Init(
|
||||
void);
|
||||
void Device_Initialize_Object_Functions(
|
||||
object_functions_t * object_table);
|
||||
|
||||
bool Device_Reinitialize(
|
||||
@@ -217,8 +216,17 @@ extern "C" {
|
||||
void);
|
||||
uint32_t Device_Index_To_Instance(
|
||||
unsigned index);
|
||||
char *Device_Name(
|
||||
uint32_t object_instance);
|
||||
|
||||
bool Device_Object_Name(
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING *object_name);
|
||||
bool Device_Set_Object_Name(
|
||||
BACNET_CHARACTER_STRING *object_name);
|
||||
/* copy a child object name */
|
||||
bool Device_Object_Name_Copy(
|
||||
int object_type,
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING *object_name);
|
||||
|
||||
BACNET_DEVICE_STATUS Device_System_Status(
|
||||
void);
|
||||
@@ -249,12 +257,6 @@ extern "C" {
|
||||
const char *name,
|
||||
size_t length);
|
||||
|
||||
bool Device_Set_Object_Name(
|
||||
const char *name,
|
||||
size_t length);
|
||||
const char *Device_Object_Name(
|
||||
void);
|
||||
|
||||
const char *Device_Description(
|
||||
void);
|
||||
bool Device_Set_Description(
|
||||
@@ -283,10 +285,10 @@ extern "C" {
|
||||
void);
|
||||
|
||||
bool Device_Valid_Object_Name(
|
||||
const char *object_name,
|
||||
BACNET_CHARACTER_STRING *object_name,
|
||||
int *object_type,
|
||||
uint32_t * object_instance);
|
||||
char *Device_Valid_Object_Id(
|
||||
bool Device_Valid_Object_Id(
|
||||
int object_type,
|
||||
uint32_t object_instance);
|
||||
|
||||
@@ -362,7 +364,7 @@ extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#define DEVICE_OBJ_FUNCTIONS \
|
||||
OBJECT_DEVICE, NULL, Device_Count, Device_Index_To_Instance, \
|
||||
Device_Valid_Object_Instance_Number, Device_Name, \
|
||||
Device_Valid_Object_Instance_Number, Device_Object_Name, \
|
||||
Device_Read_Property_Local, Device_Write_Property_Local, \
|
||||
Device_Property_Lists, DeviceGetRRInfo, NULL
|
||||
/** @defgroup ObjFrmwk Object Framework
|
||||
|
||||
@@ -85,7 +85,7 @@ bool Routed_Device_Write_Property_Local(
|
||||
/****************************************************************************
|
||||
************* BACnet Routing Functionality (Optional) **********************
|
||||
****************************************************************************
|
||||
* It would be correct to view the routing functionality here as inheriting
|
||||
* It would be correct to view the routing functionality here as inheriting
|
||||
* and extending the regular Device Object functionality.
|
||||
****************************************************************************/
|
||||
|
||||
@@ -96,8 +96,8 @@ DEVICE_OBJECT_DATA Devices[MAX_NUM_DEVICES];
|
||||
/** Keep track of the number of managed devices, including the gateway */
|
||||
uint16_t Num_Managed_Devices = 0;
|
||||
/** Which Device entry are we currently managing.
|
||||
* Since we are not using actual class objects here, the best we can do is
|
||||
* keep this local variable which notes which of the Devices the current
|
||||
* Since we are not using actual class objects here, the best we can do is
|
||||
* keep this local variable which notes which of the Devices the current
|
||||
* request is addressing. Should default to 0, the main gateway Device.
|
||||
*/
|
||||
uint16_t iCurrent_Device_Idx = 0;
|
||||
@@ -127,9 +127,15 @@ uint16_t Add_Routed_Device(
|
||||
pDev->bacObj.mObject_Type = OBJECT_DEVICE;
|
||||
pDev->bacObj.Object_Instance_Number = Object_Instance;
|
||||
if (sObject_Name != NULL)
|
||||
Routed_Device_Set_Object_Name(sObject_Name, strlen(sObject_Name));
|
||||
Routed_Device_Set_Object_Name(
|
||||
CHARACTER_UTF8,
|
||||
sObject_Name,
|
||||
strlen(sObject_Name));
|
||||
else
|
||||
Routed_Device_Set_Object_Name("No Name", strlen("No Name"));
|
||||
Routed_Device_Set_Object_Name(
|
||||
CHARACTER_UTF8,
|
||||
"No Name",
|
||||
strlen("No Name"));
|
||||
if (sDescription != NULL)
|
||||
Routed_Device_Set_Description(sDescription, strlen(sDescription));
|
||||
else
|
||||
@@ -147,7 +153,7 @@ uint16_t Add_Routed_Device(
|
||||
* -1 is a special case meaning "whichever iCurrent_Device_Idx
|
||||
* is currently set to"
|
||||
* If valid idx, will set iCurrent_Device_Idx with the idx
|
||||
* @return Pointer to the requested Device Object data, or NULL if the idx
|
||||
* @return Pointer to the requested Device Object data, or NULL if the idx
|
||||
* is for an invalid row entry (eg, after the last good Device).
|
||||
*/
|
||||
DEVICE_OBJECT_DATA *Get_Routed_Device_Object(
|
||||
@@ -168,7 +174,7 @@ DEVICE_OBJECT_DATA *Get_Routed_Device_Object(
|
||||
* -1 is a special case meaning "whichever iCurrent_Device_Idx
|
||||
* is currently set to"
|
||||
* If valid idx, will set iCurrent_Device_Idx with the idx
|
||||
* @return Pointer to the requested Device Object BACnet address, or NULL if the idx
|
||||
* @return Pointer to the requested Device Object BACnet address, or NULL if the idx
|
||||
* is for an invalid row entry (eg, after the last good Device).
|
||||
*/
|
||||
BACNET_ADDRESS *Get_Routed_Device_Address(
|
||||
@@ -186,9 +192,9 @@ BACNET_ADDRESS *Get_Routed_Device_Address(
|
||||
|
||||
|
||||
/** Get the currently active BACnet address.
|
||||
* This is an implementation of the datalink_get_my_address() template for
|
||||
* This is an implementation of the datalink_get_my_address() template for
|
||||
* devices with routing.
|
||||
*
|
||||
*
|
||||
* @param my_address [out] Points to the currently active Device Object's
|
||||
* BACnet address.
|
||||
*/
|
||||
@@ -205,18 +211,18 @@ void routed_get_my_address(
|
||||
/** See if the Gateway or Routed Device at the given idx matches
|
||||
* the given MAC address.
|
||||
* Has the desirable side-effect of setting iCurrent_Device_Idx to the
|
||||
* given idx if a match is found, for use in the subsequent routing handling
|
||||
* given idx if a match is found, for use in the subsequent routing handling
|
||||
* functions here.
|
||||
*
|
||||
*
|
||||
* @param idx [in] Index into Devices[] array being requested.
|
||||
* 0 is for the main, gateway Device entry.
|
||||
* @param address_len [in] Length of the mac_adress[] field.
|
||||
* If 0, then this is a MAC broadcast. Otherwise, size is determined
|
||||
* by the DLL type (eg, 6 for BIP and 2 for MSTP).
|
||||
* @param mac_adress [in] The desired MAC address of a Device;
|
||||
*
|
||||
* @return True if the MAC addresses match (or the address_len is 0,
|
||||
* meaning MAC broadcast, so it's an automatic match).
|
||||
*
|
||||
* @return True if the MAC addresses match (or the address_len is 0,
|
||||
* meaning MAC broadcast, so it's an automatic match).
|
||||
* Else False if no match or invalid idx is given.
|
||||
*/
|
||||
bool Routed_Device_Address_Lookup(
|
||||
@@ -248,29 +254,29 @@ bool Routed_Device_Address_Lookup(
|
||||
}
|
||||
|
||||
|
||||
/** Find the next Gateway or Routed Device at the given MAC address,
|
||||
/** Find the next Gateway or Routed Device at the given MAC address,
|
||||
* starting the search at the "cursor".
|
||||
* Has the desirable side-effect of setting internal iCurrent_Device_Idx
|
||||
* if a match is found, for use in the subsequent routing handling
|
||||
* Has the desirable side-effect of setting internal iCurrent_Device_Idx
|
||||
* if a match is found, for use in the subsequent routing handling
|
||||
* functions.
|
||||
*
|
||||
*
|
||||
* @param dest [in] The BACNET_ADDRESS of the message's destination.
|
||||
* If the Length of the mac_adress[] field is 0, then this is a MAC
|
||||
* If the Length of the mac_adress[] field is 0, then this is a MAC
|
||||
* broadcast. Otherwise, size is determined
|
||||
* by the DLL type (eg, 6 for BIP and 2 for MSTP).
|
||||
* @param DNET_list [in] List of our reachable downstream BACnet Network numbers.
|
||||
* Normally just one valid entry; terminated with a -1 value.
|
||||
* @param cursor [in,out] The concept of the cursor is that it is a starting
|
||||
* "hint" for the search; on return, it is updated to provide the
|
||||
* cursor value to use with a subsequent GetNext call, or it
|
||||
* cursor value to use with a subsequent GetNext call, or it
|
||||
* equals -1 if there are no further matches.
|
||||
* Set it to 0 on entry to access the main, gateway Device entry, or
|
||||
* to start looping through the routed devices.
|
||||
* Otherwise, its returned value is implementation-dependent and the
|
||||
* Otherwise, its returned value is implementation-dependent and the
|
||||
* calling function should not alter or interpret it.
|
||||
*
|
||||
*
|
||||
* @return True if the MAC addresses match (or if BACNET_BROADCAST_NETWORK and
|
||||
* the dest->len is 0, meaning MAC bcast, so it's an automatic match).
|
||||
* the dest->len is 0, meaning MAC bcast, so it's an automatic match).
|
||||
* Else False if no match or invalid idx is given; the cursor will
|
||||
* be returned as -1 in these cases.
|
||||
*/
|
||||
@@ -289,14 +295,14 @@ bool Routed_Device_GetNext(
|
||||
if ((idx < 0) || (idx >= MAX_NUM_DEVICES))
|
||||
idx = -1;
|
||||
|
||||
/* Next, see if it's a BACnet broadcast.
|
||||
/* Next, see if it's a BACnet broadcast.
|
||||
* For broadcasts, all Devices get a chance at it.
|
||||
*/
|
||||
else if (dest->net == BACNET_BROADCAST_NETWORK) {
|
||||
/* Just take the entry indexed by the cursor */
|
||||
bSuccess = Routed_Device_Address_Lookup(idx++, dest->len, dest->adr);
|
||||
}
|
||||
/* Or see if it's for the main Gateway Device, because
|
||||
/* Or see if it's for the main Gateway Device, because
|
||||
* there's no routing info.
|
||||
*/
|
||||
else if (dest->net == 0) {
|
||||
@@ -335,15 +341,15 @@ bool Routed_Device_GetNext(
|
||||
|
||||
/** Check if the destination network is reachable - is it our virtual network,
|
||||
* or local or else broadcast.
|
||||
*
|
||||
*
|
||||
* @param dest_net [in] The BACnet network number of a message's destination.
|
||||
* Success if it is our virtual network number, or 0 (local for the
|
||||
* Success if it is our virtual network number, or 0 (local for the
|
||||
* gateway, or 0xFFFF for a broadcast network number.
|
||||
* @param DNET_list [in] List of our reachable downstream BACnet Network numbers.
|
||||
* Normally just one valid entry; terminated with a -1 value.
|
||||
* @return True if matches our virtual network, or is for the local network
|
||||
* @return True if matches our virtual network, or is for the local network
|
||||
* Device (the gateway), or is BACNET_BROADCAST_NETWORK, which is
|
||||
* an automatic match.
|
||||
* an automatic match.
|
||||
* Else False if not a reachable network.
|
||||
*/
|
||||
bool Routed_Device_Is_Valid_Network(
|
||||
@@ -356,7 +362,7 @@ bool Routed_Device_Is_Valid_Network(
|
||||
/* First, see if it's a BACnet broadcast (automatic pass). */
|
||||
if (dest_net == BACNET_BROADCAST_NETWORK)
|
||||
bSuccess = true;
|
||||
/* Or see if it's for the main Gateway Device, because
|
||||
/* Or see if it's for the main Gateway Device, because
|
||||
* there's no routing info.
|
||||
*/
|
||||
else if (dest_net == 0)
|
||||
@@ -378,12 +384,12 @@ uint32_t Routed_Device_Index_To_Instance(
|
||||
return Devices[iCurrent_Device_Idx].bacObj.Object_Instance_Number;
|
||||
}
|
||||
|
||||
/** See if the requested Object instance matches that for the currently
|
||||
* indexed Device Object.
|
||||
* iCurrent_Device_Idx must have been set to point to this Device Object
|
||||
/** See if the requested Object instance matches that for the currently
|
||||
* indexed Device Object.
|
||||
* iCurrent_Device_Idx must have been set to point to this Device Object
|
||||
* before this function is called.
|
||||
* @param object_id [in] Object ID of the desired Device object.
|
||||
* If the wildcard value (BACNET_MAX_INSTANCE), always matches.
|
||||
* If the wildcard value (BACNET_MAX_INSTANCE), always matches.
|
||||
* @return True if Object ID matches the present Device, else False.
|
||||
*/
|
||||
bool Routed_Device_Valid_Object_Instance_Number(
|
||||
@@ -497,8 +503,9 @@ bool Routed_Device_Write_Property_Local(
|
||||
WPValidateString(&value, MAX_DEV_NAME_LEN, false,
|
||||
&wp_data->error_class, &wp_data->error_code);
|
||||
if (status) {
|
||||
Routed_Device_Set_Object_Name(characterstring_value
|
||||
(&value.type.Character_String),
|
||||
Routed_Device_Set_Object_Name(
|
||||
characterstring_encoding(&value.type.Character_String),
|
||||
characterstring_value(&value.type.Character_String),
|
||||
characterstring_length(&value.type.Character_String));
|
||||
}
|
||||
break;
|
||||
@@ -512,9 +519,9 @@ bool Routed_Device_Write_Property_Local(
|
||||
/* methods to manipulate the data */
|
||||
|
||||
/** Return the Object Instance number for the currently active Device Object.
|
||||
* This is an overload of the important, widely used
|
||||
* This is an overload of the important, widely used
|
||||
* Device_Object_Instance_Number() function.
|
||||
*
|
||||
*
|
||||
* @return The Instance number of the currently active Device.
|
||||
*/
|
||||
uint32_t Routed_Device_Object_Instance_Number(
|
||||
@@ -538,24 +545,24 @@ bool Routed_Device_Set_Object_Instance_Number(
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/** Sets the Object Name for a routed Device (or the gateway).
|
||||
* Uses local variable iCurrent_Device_Idx to know which Device
|
||||
* is to be updated.
|
||||
* @param name [in] Text for the new Object Name.
|
||||
* @param length [in] Length of name[] text.
|
||||
* @param object_name [in] Character String for the new Object Name.
|
||||
* @return True if succeed in updating Object Name, else False.
|
||||
*/
|
||||
bool Routed_Device_Set_Object_Name(
|
||||
const char *name,
|
||||
size_t length)
|
||||
uint8_t encoding,
|
||||
const char *value,
|
||||
size_t length);
|
||||
{
|
||||
bool status = false; /*return value */
|
||||
DEVICE_OBJECT_DATA *pDev = &Devices[iCurrent_Device_Idx];
|
||||
|
||||
if (length < MAX_DEV_NAME_LEN) {
|
||||
if ((encoding == CHARACTER_UTF8) &&
|
||||
(length < MAX_DEV_NAME_LEN)) {
|
||||
/* Make the change and update the database revision */
|
||||
memmove(pDev->bacObj.Object_Name, name, length);
|
||||
memmove(pDev->bacObj.Object_Name, value, length);
|
||||
pDev->bacObj.Object_Name[length] = 0;
|
||||
Routed_Device_Inc_Database_Revision();
|
||||
status = true;
|
||||
@@ -581,7 +588,7 @@ bool Routed_Device_Set_Description(
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/*
|
||||
* Shortcut for incrementing database revision as this is potentially
|
||||
* the most common operation if changing object names and ids is
|
||||
* implemented.
|
||||
|
||||
@@ -272,17 +272,19 @@ static BACNET_SHED_STATE Load_Control_Present_Value(
|
||||
}
|
||||
|
||||
/* note: the object name must be unique within this device */
|
||||
char *Load_Control_Name(
|
||||
uint32_t object_instance)
|
||||
bool Load_Control_Object_Name(
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING *object_name)
|
||||
{
|
||||
static char text_string[32] = ""; /* okay for single thread */
|
||||
bool status = false;
|
||||
|
||||
if (object_instance < MAX_LOAD_CONTROLS) {
|
||||
sprintf(text_string, "LOAD CONTROL %u", object_instance);
|
||||
return text_string;
|
||||
status = characterstring_init_ansi(object_name, text_string);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return status;
|
||||
}
|
||||
|
||||
static void Update_Current_Time(
|
||||
@@ -706,8 +708,7 @@ int Load_Control_Read_Property(
|
||||
break;
|
||||
case PROP_OBJECT_NAME:
|
||||
case PROP_DESCRIPTION:
|
||||
characterstring_init_ansi(&char_string,
|
||||
Load_Control_Name(rpdata->object_instance));
|
||||
Load_Control_Object_Name(rpdata->object_instance, &char_string);
|
||||
apdu_len =
|
||||
encode_application_character_string(&apdu[0], &char_string);
|
||||
break;
|
||||
|
||||
@@ -51,8 +51,10 @@ extern "C" {
|
||||
unsigned index);
|
||||
unsigned Load_Control_Instance_To_Index(
|
||||
uint32_t object_instance);
|
||||
char *Load_Control_Name(
|
||||
uint32_t object_instance);
|
||||
|
||||
bool Load_Control_Object_Name(
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING *object_name);
|
||||
|
||||
void Load_Control_Init(
|
||||
void);
|
||||
@@ -77,7 +79,7 @@ extern "C" {
|
||||
#define LOAD_CONTROL_OBJ_FUNCTIONS \
|
||||
OBJECT_LOAD_CONTROL, Load_Control_Init, Load_Control_Count, \
|
||||
Load_Control_Index_To_Instance, Load_Control_Valid_Instance, \
|
||||
Load_Control_Name, Load_Control_Read_Property, \
|
||||
Load_Control_Object_Name, Load_Control_Read_Property, \
|
||||
Load_Control_Write_Property, Load_Control_Property_Lists, NULL, \
|
||||
NULL
|
||||
#endif
|
||||
|
||||
@@ -173,17 +173,19 @@ static BACNET_LIFE_SAFETY_STATE Life_Safety_Point_Present_Value(
|
||||
}
|
||||
|
||||
/* note: the object name must be unique within this device */
|
||||
char *Life_Safety_Point_Name(
|
||||
uint32_t object_instance)
|
||||
bool Life_Safety_Point_Object_Name(
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING *object_name)
|
||||
{
|
||||
static char text_string[32] = ""; /* okay for single thread */
|
||||
bool status = false;
|
||||
|
||||
if (object_instance < MAX_LIFE_SAFETY_POINTS) {
|
||||
sprintf(text_string, "LS POINT %u", object_instance);
|
||||
return text_string;
|
||||
status = characterstring_init_ansi(object_name, text_string);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return status;
|
||||
}
|
||||
|
||||
/* return apdu len, or BACNET_STATUS_ERROR on error */
|
||||
@@ -216,8 +218,7 @@ int Life_Safety_Point_Read_Property(
|
||||
break;
|
||||
case PROP_OBJECT_NAME:
|
||||
case PROP_DESCRIPTION:
|
||||
characterstring_init_ansi(&char_string,
|
||||
Life_Safety_Point_Name(rpdata->object_instance));
|
||||
Life_Safety_Point_Object_Name(rpdata->object_instance, &char_string);
|
||||
apdu_len =
|
||||
encode_application_character_string(&apdu[0], &char_string);
|
||||
break;
|
||||
|
||||
@@ -48,8 +48,9 @@ extern "C" {
|
||||
unsigned index);
|
||||
unsigned Life_Safety_Point_Instance_To_Index(
|
||||
uint32_t object_instance);
|
||||
char *Life_Safety_Point_Name(
|
||||
uint32_t object_instance);
|
||||
bool Life_Safety_Point_Object_Name(
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING *object_name);
|
||||
void Life_Safety_Point_Init(
|
||||
void);
|
||||
|
||||
@@ -71,7 +72,7 @@ extern "C" {
|
||||
#define LIFE_SAFETY_POINT_OBJ_FUNCTIONS \
|
||||
OBJECT_LIFE_SAFETY_POINT, Life_Safety_Point_Init, \
|
||||
Life_Safety_Point_Count, Life_Safety_Point_Index_To_Instance, \
|
||||
Life_Safety_Point_Valid_Instance, Life_Safety_Point_Name, \
|
||||
Life_Safety_Point_Valid_Instance, Life_Safety_Point_Object_Name, \
|
||||
Life_Safety_Point_Read_Property, \
|
||||
Life_Safety_Point_Write_Property, \
|
||||
Life_Safety_Point_Property_Lists, NULL, NULL
|
||||
|
||||
@@ -225,18 +225,19 @@ bool Multistate_Input_Description_Set(
|
||||
return status;
|
||||
}
|
||||
|
||||
char *Multistate_Input_Name(
|
||||
uint32_t object_instance)
|
||||
bool Multistate_Input_Object_Name(
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING *object_name)
|
||||
{
|
||||
unsigned index = 0; /* offset from instance lookup */
|
||||
char *pName = NULL; /* return value */
|
||||
bool status = false;
|
||||
|
||||
index = Multistate_Input_Instance_To_Index(object_instance);
|
||||
if (index < MAX_MULTISTATE_INPUTS) {
|
||||
pName = Object_Name[index];
|
||||
status = characterstring_init_ansi(object_name, Object_Name[index]);
|
||||
}
|
||||
|
||||
return pName;
|
||||
return status;
|
||||
}
|
||||
|
||||
/* note: the object name must be unique within this device */
|
||||
@@ -347,8 +348,7 @@ int Multistate_Input_Read_Property(
|
||||
/* note: Name and Description don't have to be the same.
|
||||
You could make Description writable and different */
|
||||
case PROP_OBJECT_NAME:
|
||||
characterstring_init_ansi(&char_string,
|
||||
Multistate_Input_Name(rpdata->object_instance));
|
||||
Multistate_Input_Object_Name(rpdata->object_instance, &char_string);
|
||||
apdu_len =
|
||||
encode_application_character_string(&apdu[0], &char_string);
|
||||
break;
|
||||
|
||||
@@ -59,11 +59,14 @@ extern "C" {
|
||||
/* optional API */
|
||||
bool Multistate_Input_Object_Instance_Add(
|
||||
uint32_t instance);
|
||||
char *Multistate_Input_Name(
|
||||
uint32_t object_instance);
|
||||
|
||||
bool Multistate_Input_Object_Name(
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING *object_name);
|
||||
bool Multistate_Input_Name_Set(
|
||||
uint32_t object_instance,
|
||||
char *new_name);
|
||||
|
||||
uint32_t Multistate_Input_Present_Value(
|
||||
uint32_t object_instance);
|
||||
bool Multistate_Input_Present_Value_Set(
|
||||
@@ -96,7 +99,7 @@ extern "C" {
|
||||
#define MULTI_STATE_INPUT_OBJ_FUNCTIONS \
|
||||
OBJECT_MULTI_STATE_INPUT, Multistate_Input_Init, \
|
||||
Multistate_Input_Count, Multistate_Input_Index_To_Instance, \
|
||||
Multistate_Input_Valid_Instance, Multistate_Input_Name, \
|
||||
Multistate_Input_Valid_Instance, Multistate_Input_Object_Name, \
|
||||
Multistate_Input_Read_Property, \
|
||||
Multistate_Input_Write_Property, \
|
||||
Multistate_Input_Property_Lists, NULL, NULL
|
||||
|
||||
@@ -180,17 +180,19 @@ static uint32_t Multistate_Output_Present_Value(
|
||||
}
|
||||
|
||||
/* note: the object name must be unique within this device */
|
||||
char *Multistate_Output_Name(
|
||||
uint32_t object_instance)
|
||||
bool Multistate_Output_Object_Name(
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING *object_name)
|
||||
{
|
||||
static char text_string[32] = ""; /* okay for single thread */
|
||||
bool status = false;
|
||||
|
||||
if (object_instance < MAX_MULTISTATE_OUTPUTS) {
|
||||
sprintf(text_string, "MULTISTATE OUTPUT %u", object_instance);
|
||||
return text_string;
|
||||
status = characterstring_init_ansi(object_name, text_string);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return status;
|
||||
}
|
||||
|
||||
/* return apdu len, or BACNET_STATUS_ERROR on error */
|
||||
@@ -222,8 +224,7 @@ int Multistate_Output_Read_Property(
|
||||
You could make Description writable and different */
|
||||
case PROP_OBJECT_NAME:
|
||||
case PROP_DESCRIPTION:
|
||||
characterstring_init_ansi(&char_string,
|
||||
Multistate_Output_Name(rpdata->object_instance));
|
||||
Multistate_Output_Object_Name(rpdata->object_instance, &char_string);
|
||||
apdu_len =
|
||||
encode_application_character_string(&apdu[0], &char_string);
|
||||
break;
|
||||
|
||||
@@ -48,8 +48,10 @@ extern "C" {
|
||||
unsigned index);
|
||||
unsigned Multistate_Output_Instance_To_Index(
|
||||
uint32_t object_instance);
|
||||
char *Multistate_Output_Name(
|
||||
uint32_t object_instance);
|
||||
|
||||
bool Multistate_Output_Object_Name(
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING *object_name);
|
||||
|
||||
void Multistate_Output_Init(
|
||||
void);
|
||||
@@ -72,7 +74,7 @@ extern "C" {
|
||||
#define MULTI_STATE_OUTPUT_OBJ_FUNCTIONS \
|
||||
OBJECT_MULTI_STATE_OUTPUT, Multistate_Output_Init, \
|
||||
Multistate_Output_Count, Multistate_Output_Index_To_Instance, \
|
||||
Multistate_Output_Valid_Instance, Multistate_Output_Name, \
|
||||
Multistate_Output_Valid_Instance, Multistate_Output_Object_Name, \
|
||||
Multistate_Output_Read_Property, \
|
||||
Multistate_Output_Write_Property, \
|
||||
Multistate_Output_Property_Lists, NULL, NULL
|
||||
|
||||
@@ -80,7 +80,7 @@ static const int Trend_Log_Properties_Optional[] = {
|
||||
PROP_COV_RESUBSCRIPTION_INTERVAL,
|
||||
PROP_CLIENT_COV_INCREMENT, */
|
||||
|
||||
/* Required if intrinsic reporting supported
|
||||
/* Required if intrinsic reporting supported
|
||||
PROP_NOTIFICATION_THRESHOLD,
|
||||
PROP_RECORDS_SINCE_NOTIFICATION,
|
||||
PROP_LAST_NOTIFY_RECORD,
|
||||
@@ -179,7 +179,7 @@ void Trend_Log_Init(
|
||||
/* initialize all the values */
|
||||
|
||||
for (iLog = 0; iLog < MAX_TREND_LOGS; iLog++) {
|
||||
/*
|
||||
/*
|
||||
* Do we need to do anything here?
|
||||
* Trend logs are usually assumed to survive over resets
|
||||
* and are frequently implemented using Battery Backed RAM
|
||||
@@ -257,17 +257,19 @@ void Trend_Log_Init(
|
||||
* on the assumption that there is a 1 to 1 correspondance. If there
|
||||
* is not we need to convert to index before proceeding.
|
||||
*/
|
||||
char *Trend_Log_Name(
|
||||
uint32_t object_instance)
|
||||
bool Trend_Log_Object_Name(
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING *object_name)
|
||||
{
|
||||
static char text_string[32] = ""; /* okay for single thread */
|
||||
bool status = false;
|
||||
|
||||
if (object_instance < MAX_TREND_LOGS) {
|
||||
sprintf(text_string, "Trend Log %u", object_instance);
|
||||
return text_string;
|
||||
status = characterstring_init_ansi(object_name, text_string);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
@@ -298,8 +300,7 @@ int Trend_Log_Read_Property(
|
||||
|
||||
case PROP_DESCRIPTION:
|
||||
case PROP_OBJECT_NAME:
|
||||
characterstring_init_ansi(&char_string,
|
||||
Trend_Log_Name(rpdata->object_instance));
|
||||
Trend_Log_Object_Name(rpdata->object_instance, &char_string);
|
||||
apdu_len =
|
||||
encode_application_character_string(&apdu[0], &char_string);
|
||||
break;
|
||||
@@ -496,14 +497,14 @@ bool Trend_Log_Write_Property(
|
||||
/* To do: what actions do we need to take on writing ? */
|
||||
if (value.type.Boolean == false) {
|
||||
if (bEffectiveEnable == true) {
|
||||
/* Only insert record if we really were
|
||||
/* Only insert record if we really were
|
||||
enabled i.e. times and enable flags */
|
||||
TL_Insert_Status_Rec(log_index,
|
||||
LOG_STATUS_LOG_DISABLED, true);
|
||||
}
|
||||
} else {
|
||||
if (TL_Is_Enabled(log_index)) {
|
||||
/* Have really gone from disabled to enabled as
|
||||
/* Have really gone from disabled to enabled as
|
||||
* enable flag and times were correct
|
||||
*/
|
||||
TL_Insert_Status_Rec(log_index,
|
||||
@@ -563,7 +564,7 @@ bool Trend_Log_Write_Property(
|
||||
break;
|
||||
|
||||
case PROP_LOGGING_TYPE:
|
||||
/* logic
|
||||
/* logic
|
||||
* triggered and polled options.
|
||||
*/
|
||||
status =
|
||||
@@ -1016,7 +1017,7 @@ time_t TL_BAC_Time_To_Local(
|
||||
|
||||
LocalTime.tm_year = SourceTime->date.year - 1900; /* We store BACnet year in full format */
|
||||
/* Some clients send a date of all 0s to indicate start of epoch
|
||||
* even though this is not a valid date. Pick this up here and
|
||||
* even though this is not a valid date. Pick this up here and
|
||||
* correct the day and month for the local time functions.
|
||||
*/
|
||||
iTemp =
|
||||
@@ -1151,7 +1152,7 @@ int TL_encode_by_position(
|
||||
* start index/positive count and then process as
|
||||
* normal. This assumes that the order to return items
|
||||
* is always first to last, if this is not true we will
|
||||
* have to handle this differently.
|
||||
* have to handle this differently.
|
||||
*
|
||||
* Note: We need to be careful about how we convert these
|
||||
* values due to the mix of signed and unsigned types - don't
|
||||
@@ -1184,7 +1185,7 @@ int TL_encode_by_position(
|
||||
while (uiIndex <= uiTarget) {
|
||||
if (uiRemaining < TL_MAX_ENC) {
|
||||
/*
|
||||
* Can't fit any more in! We just set the result flag to say there
|
||||
* Can't fit any more in! We just set the result flag to say there
|
||||
* was more and drop out of the loop early
|
||||
*/
|
||||
bitstring_set_bit(&pRequest->ResultFlags, RESULT_FLAG_MORE_ITEMS,
|
||||
@@ -1318,7 +1319,7 @@ int TL_encode_by_sequence(
|
||||
while (uiSequence != uiEnd + 1) {
|
||||
if (uiRemaining < TL_MAX_ENC) {
|
||||
/*
|
||||
* Can't fit any more in! We just set the result flag to say there
|
||||
* Can't fit any more in! We just set the result flag to say there
|
||||
* was more and drop out of the loop early
|
||||
*/
|
||||
bitstring_set_bit(&pRequest->ResultFlags, RESULT_FLAG_MORE_ITEMS,
|
||||
@@ -1410,7 +1411,7 @@ int TL_encode_by_time(
|
||||
pRequest->Count = -pRequest->Count; /* Conveert to +ve count */
|
||||
/* If count would bring us back beyond the limits
|
||||
* Of the buffer then pin it to the start of the buffer
|
||||
* otherwise adjust starting point and sequence number
|
||||
* otherwise adjust starting point and sequence number
|
||||
* appropriately.
|
||||
*/
|
||||
iTemp = pRequest->Count - 1;
|
||||
@@ -1450,7 +1451,7 @@ int TL_encode_by_time(
|
||||
while (iCount != 0) {
|
||||
if (uiRemaining < TL_MAX_ENC) {
|
||||
/*
|
||||
* Can't fit any more in! We just set the result flag to say there
|
||||
* Can't fit any more in! We just set the result flag to say there
|
||||
* was more and drop out of the loop early
|
||||
*/
|
||||
bitstring_set_bit(&pRequest->ResultFlags, RESULT_FLAG_MORE_ITEMS,
|
||||
@@ -1819,7 +1820,7 @@ void trend_log_timer(
|
||||
/* Also record value if we have waited more than a period
|
||||
* since the last reading. This ensures we take a reading as
|
||||
* soon as possible after a power down if we have been off for
|
||||
* more than a single period.
|
||||
* more than a single period.
|
||||
*/
|
||||
TL_fetch_property(iCount);
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ extern "C" {
|
||||
time_t tLastDataTime;
|
||||
} TL_LOG_INFO;
|
||||
|
||||
/*
|
||||
/*
|
||||
* Data types associated with a BACnet Log Record. We use these for managing the
|
||||
* log buffer but they are also the tag numbers to use when encoding/decoding
|
||||
* the log datum field.
|
||||
@@ -139,8 +139,9 @@ extern "C" {
|
||||
bool Trend_Log_Object_Instance_Add(
|
||||
uint32_t instance);
|
||||
|
||||
char *Trend_Log_Name(
|
||||
uint32_t object_instance);
|
||||
bool Trend_Log_Object_Name(
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING *object_name);
|
||||
|
||||
int Trend_Log_Read_Property(
|
||||
BACNET_READ_PROPERTY_DATA * rpdata);
|
||||
@@ -199,7 +200,7 @@ extern "C" {
|
||||
#define TRENDLOG_OBJ_FUNCTIONS \
|
||||
OBJECT_TRENDLOG, Trend_Log_Init, Trend_Log_Count, \
|
||||
Trend_Log_Index_To_Instance, Trend_Log_Valid_Instance, \
|
||||
Trend_Log_Name, Trend_Log_Read_Property, \
|
||||
Trend_Log_Object_Name, Trend_Log_Read_Property, \
|
||||
Trend_Log_Write_Property, Trend_Log_Property_Lists, \
|
||||
TrendLogGetRRInfo, NULL
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user