Ignore ReinitializeDevice and DeviceCommunicationControl service password (#518)
* Fix device object ReinitializeDevice service handling examples of no-password in the device. Add unit testing of device object ReinitializeDevice service. Add API for setting ReinitializeDevice device object password. * Fix DeviceCommunicationControl service handling example of no-password in the device. --------- Co-authored-by: Steve Karg <skarg@users.sourceforge.net>
This commit is contained in:
+46
-27
@@ -74,8 +74,8 @@ static object_functions_t My_Object_Table[] = {
|
||||
Device_Property_Lists, DeviceGetRRInfo, NULL /* Iterator */,
|
||||
NULL /* Value_Lists */, NULL /* COV */, NULL /* COV Clear */,
|
||||
NULL /* Intrinsic Reporting */, NULL /* Add_List_Element */,
|
||||
NULL /* Remove_List_Element */,
|
||||
NULL /* Create */, NULL /* Delete */, NULL /* Timer */ },
|
||||
NULL /* Remove_List_Element */, NULL /* Create */, NULL /* Delete */,
|
||||
NULL /* Timer */ },
|
||||
#if (BACNET_PROTOCOL_REVISION >= 17)
|
||||
{ OBJECT_NETWORK_PORT, Network_Port_Init, Network_Port_Count,
|
||||
Network_Port_Index_To_Instance, Network_Port_Valid_Instance,
|
||||
@@ -93,7 +93,7 @@ static object_functions_t My_Object_Table[] = {
|
||||
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
|
||||
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
|
||||
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
|
||||
NULL /* Create */, NULL /* Delete */ , NULL /* Timer */ },
|
||||
NULL /* Create */, NULL /* Delete */, NULL /* Timer */ },
|
||||
#if (BACNET_PROTOCOL_REVISION >= 14)
|
||||
{ OBJECT_LIGHTING_OUTPUT, Lighting_Output_Init, Lighting_Output_Count,
|
||||
Lighting_Output_Index_To_Instance, Lighting_Output_Valid_Instance,
|
||||
@@ -102,7 +102,7 @@ static object_functions_t My_Object_Table[] = {
|
||||
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
|
||||
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
|
||||
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
|
||||
Lighting_Output_Create, Lighting_Output_Delete, Lighting_Output_Timer},
|
||||
Lighting_Output_Create, Lighting_Output_Delete, Lighting_Output_Timer },
|
||||
{ OBJECT_CHANNEL, Channel_Init, Channel_Count, Channel_Index_To_Instance,
|
||||
Channel_Valid_Instance, Channel_Object_Name, Channel_Read_Property,
|
||||
Channel_Write_Property, Channel_Property_Lists,
|
||||
@@ -118,7 +118,7 @@ static object_functions_t My_Object_Table[] = {
|
||||
NULL /* Iterator */, NULL /* Value_Lists */, NULL /* COV */,
|
||||
NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
|
||||
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
|
||||
Color_Create, Color_Delete, Color_Timer},
|
||||
Color_Create, Color_Delete, Color_Timer },
|
||||
{ OBJECT_COLOR_TEMPERATURE, Color_Temperature_Init, Color_Temperature_Count,
|
||||
Color_Temperature_Index_To_Instance, Color_Temperature_Valid_Instance,
|
||||
Color_Temperature_Object_Name, Color_Temperature_Read_Property,
|
||||
@@ -127,7 +127,7 @@ static object_functions_t My_Object_Table[] = {
|
||||
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
|
||||
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
|
||||
Color_Temperature_Create, Color_Temperature_Delete,
|
||||
Color_Temperature_Timer},
|
||||
Color_Temperature_Timer },
|
||||
#endif
|
||||
{ MAX_BACNET_OBJECT_TYPE, NULL /* Init */, NULL /* Count */,
|
||||
NULL /* Index_To_Instance */, NULL /* Valid_Instance */,
|
||||
@@ -329,6 +329,24 @@ static uint32_t Database_Revision = 0;
|
||||
static BACNET_REINITIALIZED_STATE Reinitialize_State = BACNET_REINIT_IDLE;
|
||||
static const char *Reinit_Password = "filister";
|
||||
|
||||
/**
|
||||
* @brief Sets the ReinitializeDevice password
|
||||
*
|
||||
* The password shall be a null terminated C string of up to
|
||||
* 20 ASCII characters for those devices that require the password.
|
||||
*
|
||||
* For those devices that do not require a password, set to NULL or
|
||||
* point to a zero length C string (null terminated).
|
||||
*
|
||||
* @param the ReinitializeDevice password; can be NULL or empty string
|
||||
*/
|
||||
bool Device_Reinitialize_Password_Set(const char *password)
|
||||
{
|
||||
Reinit_Password = password;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Commands a Device re-initialization, to a given state.
|
||||
* The request's password must match for the operation to succeed.
|
||||
* This implementation provides a framework, but doesn't
|
||||
@@ -345,6 +363,7 @@ static const char *Reinit_Password = "filister";
|
||||
bool Device_Reinitialize(BACNET_REINITIALIZE_DEVICE_DATA *rd_data)
|
||||
{
|
||||
bool status = false;
|
||||
bool password_success = false;
|
||||
|
||||
/* From 16.4.1.1.2 Password
|
||||
This optional parameter shall be a CharacterString of up to
|
||||
@@ -352,12 +371,21 @@ bool Device_Reinitialize(BACNET_REINITIALIZE_DEVICE_DATA *rd_data)
|
||||
protection, the service request shall be denied if the parameter
|
||||
is absent or if the password is incorrect. For those devices that
|
||||
do not require a password, this parameter shall be ignored.*/
|
||||
if (Reinit_Password && strlen(Reinit_Password) > 0) {
|
||||
if (characterstring_length(&rd_data->password) > 20) {
|
||||
rd_data->error_class = ERROR_CLASS_SERVICES;
|
||||
rd_data->error_code = ERROR_CODE_PARAMETER_OUT_OF_RANGE;
|
||||
} else if (characterstring_ansi_same(&rd_data->password, Reinit_Password)) {
|
||||
/* Note: you could use a mix of state and password to
|
||||
accomplish multiple things before restarting */
|
||||
} else if (characterstring_ansi_same(
|
||||
&rd_data->password, Reinit_Password)) {
|
||||
password_success = true;
|
||||
} else {
|
||||
rd_data->error_class = ERROR_CLASS_SECURITY;
|
||||
rd_data->error_code = ERROR_CODE_PASSWORD_FAILURE;
|
||||
}
|
||||
} else {
|
||||
password_success = true;
|
||||
}
|
||||
if (password_success) {
|
||||
switch (rd_data->state) {
|
||||
case BACNET_REINIT_COLDSTART:
|
||||
case BACNET_REINIT_WARMSTART:
|
||||
@@ -387,9 +415,6 @@ bool Device_Reinitialize(BACNET_REINITIALIZE_DEVICE_DATA *rd_data)
|
||||
rd_data->error_code = ERROR_CODE_PARAMETER_OUT_OF_RANGE;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
rd_data->error_class = ERROR_CLASS_SECURITY;
|
||||
rd_data->error_code = ERROR_CODE_PASSWORD_FAILURE;
|
||||
}
|
||||
|
||||
return status;
|
||||
@@ -1103,9 +1128,8 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
|
||||
case PROP_OBJECT_LIST:
|
||||
count = Device_Object_List_Count();
|
||||
apdu_len = bacnet_array_encode(rpdata->object_instance,
|
||||
rpdata->array_index,
|
||||
Device_Object_List_Element_Encode,
|
||||
count, apdu, apdu_max);
|
||||
rpdata->array_index, Device_Object_List_Element_Encode, count,
|
||||
apdu, apdu_max);
|
||||
if (apdu_len == BACNET_STATUS_ABORT) {
|
||||
rpdata->error_code =
|
||||
ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED;
|
||||
@@ -1635,8 +1659,8 @@ bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
||||
}
|
||||
#endif
|
||||
if (wp_data->object_property == PROP_OBJECT_NAME) {
|
||||
status = Device_Write_Property_Object_Name(wp_data,
|
||||
pObject->Object_Write_Property);
|
||||
status = Device_Write_Property_Object_Name(
|
||||
wp_data, pObject->Object_Write_Property);
|
||||
} else {
|
||||
status = pObject->Object_Write_Property(wp_data);
|
||||
}
|
||||
@@ -1663,8 +1687,7 @@ bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
||||
* @return The length of the apdu encoded or #BACNET_STATUS_ERROR or
|
||||
* #BACNET_STATUS_ABORT or #BACNET_STATUS_REJECT.
|
||||
*/
|
||||
int Device_Add_List_Element(
|
||||
BACNET_LIST_ELEMENT_DATA * list_element)
|
||||
int Device_Add_List_Element(BACNET_LIST_ELEMENT_DATA *list_element)
|
||||
{
|
||||
int status = BACNET_STATUS_ERROR;
|
||||
struct object_functions *pObject = NULL;
|
||||
@@ -1698,8 +1721,7 @@ int Device_Add_List_Element(
|
||||
* @return The length of the apdu encoded or #BACNET_STATUS_ERROR or
|
||||
* #BACNET_STATUS_ABORT or #BACNET_STATUS_REJECT.
|
||||
*/
|
||||
int Device_Remove_List_Element(
|
||||
BACNET_LIST_ELEMENT_DATA * list_element)
|
||||
int Device_Remove_List_Element(BACNET_LIST_ELEMENT_DATA *list_element)
|
||||
{
|
||||
int status = BACNET_STATUS_ERROR;
|
||||
struct object_functions *pObject = NULL;
|
||||
@@ -1805,8 +1827,7 @@ void Device_COV_Clear(BACNET_OBJECT_TYPE object_type, uint32_t object_instance)
|
||||
* @param data - CreateObject data, including error codes if failures
|
||||
* @return true if object has been created
|
||||
*/
|
||||
bool Device_Create_Object(
|
||||
BACNET_CREATE_OBJECT_DATA *data)
|
||||
bool Device_Create_Object(BACNET_CREATE_OBJECT_DATA *data)
|
||||
{
|
||||
bool status = false;
|
||||
struct object_functions *pObject = NULL;
|
||||
@@ -1865,8 +1886,7 @@ bool Device_Create_Object(
|
||||
* @param data - DeleteObject data, including error codes if failures
|
||||
* @return true if object has been deleted
|
||||
*/
|
||||
bool Device_Delete_Object(
|
||||
BACNET_DELETE_OBJECT_DATA *data)
|
||||
bool Device_Delete_Object(BACNET_DELETE_OBJECT_DATA *data)
|
||||
{
|
||||
bool status = false;
|
||||
struct object_functions *pObject = NULL;
|
||||
@@ -1997,8 +2017,7 @@ bool DeviceGetRRInfo(BACNET_READ_RANGE_DATA *pRequest, /* Info on the request */
|
||||
* @brief Updates all the object timers with elapsed milliseconds
|
||||
* @param milliseconds - number of milliseconds elapsed
|
||||
*/
|
||||
void Device_Timer(
|
||||
uint16_t milliseconds)
|
||||
void Device_Timer(uint16_t milliseconds)
|
||||
{
|
||||
struct object_functions *pObject;
|
||||
unsigned count = 0;
|
||||
|
||||
+43
-20
@@ -67,8 +67,8 @@ static object_functions_t My_Object_Table[] = {
|
||||
Device_Property_Lists, DeviceGetRRInfo, NULL /* Iterator */,
|
||||
NULL /* Value_Lists */, NULL /* COV */, NULL /* COV Clear */,
|
||||
NULL /* Intrinsic Reporting */, NULL /* Add_List_Element */,
|
||||
NULL /* Remove_List_Element */,
|
||||
NULL /* Create */, NULL /* Delete */, NULL /* Timer */ },
|
||||
NULL /* Remove_List_Element */, NULL /* Create */, NULL /* Delete */,
|
||||
NULL /* Timer */ },
|
||||
#if (BACNET_PROTOCOL_REVISION >= 17)
|
||||
{ OBJECT_NETWORK_PORT, Network_Port_Init, Network_Port_Count,
|
||||
Network_Port_Index_To_Instance, Network_Port_Valid_Instance,
|
||||
@@ -95,7 +95,7 @@ static object_functions_t My_Object_Table[] = {
|
||||
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
|
||||
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
|
||||
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
|
||||
Binary_Output_Create, Binary_Output_Delete, NULL /* Timer */},
|
||||
Binary_Output_Create, Binary_Output_Delete, NULL /* Timer */ },
|
||||
{ MAX_BACNET_OBJECT_TYPE, NULL /* Init */, NULL /* Count */,
|
||||
NULL /* Index_To_Instance */, NULL /* Valid_Instance */,
|
||||
NULL /* Object_Name */, NULL /* Read_Property */,
|
||||
@@ -103,7 +103,7 @@ static object_functions_t My_Object_Table[] = {
|
||||
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
|
||||
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
|
||||
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
|
||||
NULL /* Create */, NULL /* Delete */ , NULL /* Timer */}
|
||||
NULL /* Create */, NULL /* Delete */, NULL /* Timer */ }
|
||||
};
|
||||
|
||||
/** Glue function to let the Device object, when called by a handler,
|
||||
@@ -296,6 +296,24 @@ static uint32_t Database_Revision = 0;
|
||||
static BACNET_REINITIALIZED_STATE Reinitialize_State = BACNET_REINIT_IDLE;
|
||||
static const char *Reinit_Password = "raspberry";
|
||||
|
||||
/**
|
||||
* @brief Sets the ReinitializeDevice password
|
||||
*
|
||||
* The password shall be a null terminated C string of up to
|
||||
* 20 ASCII characters for those devices that require the password.
|
||||
*
|
||||
* For those devices that do not require a password, set to NULL or
|
||||
* point to a zero length C string (null terminated).
|
||||
*
|
||||
* @param the ReinitializeDevice password; can be NULL or empty string
|
||||
*/
|
||||
bool Device_Reinitialize_Password_Set(const char *password)
|
||||
{
|
||||
Reinit_Password = password;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Commands a Device re-initialization, to a given state.
|
||||
* The request's password must match for the operation to succeed.
|
||||
* This implementation provides a framework, but doesn't
|
||||
@@ -312,6 +330,7 @@ static const char *Reinit_Password = "raspberry";
|
||||
bool Device_Reinitialize(BACNET_REINITIALIZE_DEVICE_DATA *rd_data)
|
||||
{
|
||||
bool status = false;
|
||||
bool password_success = false;
|
||||
|
||||
/* From 16.4.1.1.2 Password
|
||||
This optional parameter shall be a CharacterString of up to
|
||||
@@ -319,12 +338,21 @@ bool Device_Reinitialize(BACNET_REINITIALIZE_DEVICE_DATA *rd_data)
|
||||
protection, the service request shall be denied if the parameter
|
||||
is absent or if the password is incorrect. For those devices that
|
||||
do not require a password, this parameter shall be ignored.*/
|
||||
if (Reinit_Password && strlen(Reinit_Password) > 0) {
|
||||
if (characterstring_length(&rd_data->password) > 20) {
|
||||
rd_data->error_class = ERROR_CLASS_SERVICES;
|
||||
rd_data->error_code = ERROR_CODE_PARAMETER_OUT_OF_RANGE;
|
||||
} else if (characterstring_ansi_same(&rd_data->password, Reinit_Password)) {
|
||||
/* Note: you could use a mix of state and password to
|
||||
accomplish multiple things before restarting */
|
||||
} else if (characterstring_ansi_same(
|
||||
&rd_data->password, Reinit_Password)) {
|
||||
password_success = true;
|
||||
} else {
|
||||
rd_data->error_class = ERROR_CLASS_SECURITY;
|
||||
rd_data->error_code = ERROR_CODE_PASSWORD_FAILURE;
|
||||
}
|
||||
} else {
|
||||
password_success = true;
|
||||
}
|
||||
if (password_success) {
|
||||
switch (rd_data->state) {
|
||||
case BACNET_REINIT_COLDSTART:
|
||||
case BACNET_REINIT_WARMSTART:
|
||||
@@ -1070,9 +1098,8 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
|
||||
case PROP_OBJECT_LIST:
|
||||
count = Device_Object_List_Count();
|
||||
apdu_len = bacnet_array_encode(rpdata->object_instance,
|
||||
rpdata->array_index,
|
||||
Device_Object_List_Element_Encode,
|
||||
count, apdu, apdu_max);
|
||||
rpdata->array_index, Device_Object_List_Element_Encode, count,
|
||||
apdu, apdu_max);
|
||||
if (apdu_len == BACNET_STATUS_ABORT) {
|
||||
rpdata->error_code =
|
||||
ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED;
|
||||
@@ -1602,8 +1629,8 @@ bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
||||
}
|
||||
#endif
|
||||
if (wp_data->object_property == PROP_OBJECT_NAME) {
|
||||
status = Device_Write_Property_Object_Name(wp_data,
|
||||
pObject->Object_Write_Property);
|
||||
status = Device_Write_Property_Object_Name(
|
||||
wp_data, pObject->Object_Write_Property);
|
||||
} else {
|
||||
status = pObject->Object_Write_Property(wp_data);
|
||||
}
|
||||
@@ -1630,8 +1657,7 @@ bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
||||
* @return The length of the apdu encoded or #BACNET_STATUS_ERROR or
|
||||
* #BACNET_STATUS_ABORT or #BACNET_STATUS_REJECT.
|
||||
*/
|
||||
int Device_Add_List_Element(
|
||||
BACNET_LIST_ELEMENT_DATA * list_element)
|
||||
int Device_Add_List_Element(BACNET_LIST_ELEMENT_DATA *list_element)
|
||||
{
|
||||
int status = BACNET_STATUS_ERROR;
|
||||
struct object_functions *pObject = NULL;
|
||||
@@ -1665,8 +1691,7 @@ int Device_Add_List_Element(
|
||||
* @return The length of the apdu encoded or #BACNET_STATUS_ERROR or
|
||||
* #BACNET_STATUS_ABORT or #BACNET_STATUS_REJECT.
|
||||
*/
|
||||
int Device_Remove_List_Element(
|
||||
BACNET_LIST_ELEMENT_DATA * list_element)
|
||||
int Device_Remove_List_Element(BACNET_LIST_ELEMENT_DATA *list_element)
|
||||
{
|
||||
int status = BACNET_STATUS_ERROR;
|
||||
struct object_functions *pObject = NULL;
|
||||
@@ -1772,8 +1797,7 @@ void Device_COV_Clear(BACNET_OBJECT_TYPE object_type, uint32_t object_instance)
|
||||
* @param data - CreateObject data, including error codes if failures
|
||||
* @return true if object has been created
|
||||
*/
|
||||
bool Device_Create_Object(
|
||||
BACNET_CREATE_OBJECT_DATA *data)
|
||||
bool Device_Create_Object(BACNET_CREATE_OBJECT_DATA *data)
|
||||
{
|
||||
bool status = false;
|
||||
struct object_functions *pObject = NULL;
|
||||
@@ -1832,8 +1856,7 @@ bool Device_Create_Object(
|
||||
* @param data - DeleteObject data, including error codes if failures
|
||||
* @return true if object has been deleted
|
||||
*/
|
||||
bool Device_Delete_Object(
|
||||
BACNET_DELETE_OBJECT_DATA *data)
|
||||
bool Device_Delete_Object(BACNET_DELETE_OBJECT_DATA *data)
|
||||
{
|
||||
bool status = false;
|
||||
struct object_functions *pObject = NULL;
|
||||
|
||||
+61
-17
@@ -67,8 +67,7 @@ static struct my_object_functions {
|
||||
read_property_function Object_Read_Property;
|
||||
write_property_function Object_Write_Property;
|
||||
rpm_property_lists_function Object_RPM_List;
|
||||
} Object_Table[] = {
|
||||
{ OBJECT_DEVICE, NULL, /* don't init - recursive! */
|
||||
} Object_Table[] = { { OBJECT_DEVICE, NULL, /* don't init - recursive! */
|
||||
Device_Count, Device_Index_To_Instance,
|
||||
Device_Valid_Object_Instance_Number,
|
||||
Device_Object_Name, Device_Read_Property_Local,
|
||||
@@ -159,8 +158,7 @@ static int Read_Property_Common(
|
||||
}
|
||||
apdu = rpdata->application_data;
|
||||
if (property_list_common(rpdata->object_property)) {
|
||||
apdu_len = property_list_common_encode(rpdata,
|
||||
Object_Instance_Number);
|
||||
apdu_len = property_list_common_encode(rpdata, Object_Instance_Number);
|
||||
} else if (rpdata->object_property == PROP_OBJECT_NAME) {
|
||||
/* only array properties can have array options */
|
||||
if (rpdata->array_index != BACNET_ARRAY_ALL) {
|
||||
@@ -180,9 +178,8 @@ static int Read_Property_Common(
|
||||
} else if (rpdata->object_property == PROP_PROPERTY_LIST) {
|
||||
Device_Objects_Property_List(
|
||||
rpdata->object_type, rpdata->object_instance, &property_list);
|
||||
apdu_len = property_list_encode(rpdata,
|
||||
property_list.Required.pList, property_list.Optional.pList,
|
||||
property_list.Proprietary.pList);
|
||||
apdu_len = property_list_encode(rpdata, property_list.Required.pList,
|
||||
property_list.Optional.pList, property_list.Proprietary.pList);
|
||||
#endif
|
||||
} else if (pObject->Object_Read_Property) {
|
||||
apdu_len = pObject->Object_Read_Property(rpdata);
|
||||
@@ -332,12 +329,64 @@ bool Device_Set_Object_Name(BACNET_CHARACTER_STRING *object_name)
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the ReinitializeDevice password
|
||||
*
|
||||
* The password shall be a null terminated C string of up to
|
||||
* 20 ASCII characters for those devices that require the password.
|
||||
*
|
||||
* For those devices that do not require a password, set to NULL or
|
||||
* point to a zero length C string (null terminated).
|
||||
*
|
||||
* @param the ReinitializeDevice password; can be NULL or empty string
|
||||
*/
|
||||
bool Device_Reinitialize_Password_Set(const char *password)
|
||||
{
|
||||
Reinit_Password = password;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Commands a Device re-initialization, to a given state.
|
||||
* The request's password must match for the operation to succeed.
|
||||
* This implementation provides a framework, but doesn't
|
||||
* actually *DO* anything.
|
||||
* @note You could use a mix of states and passwords to multiple outcomes.
|
||||
* @note You probably want to restart *after* the simple ack has been sent
|
||||
* from the return handler, so just set a local flag here.
|
||||
* @ingroup ObjIntf
|
||||
*
|
||||
* @param rd_data [in,out] The information from the RD request.
|
||||
* On failure, the error class and code will be set.
|
||||
* @return True if succeeds (password is correct), else False.
|
||||
*/
|
||||
bool Device_Reinitialize(BACNET_REINITIALIZE_DEVICE_DATA *rd_data)
|
||||
{
|
||||
bool status = false;
|
||||
bool password_success = false;
|
||||
|
||||
/* Note: you could use a mix of state and password to multiple things */
|
||||
if (characterstring_ansi_same(&rd_data->password, Reinit_Password)) {
|
||||
/* From 16.4.1.1.2 Password
|
||||
This optional parameter shall be a CharacterString of up to
|
||||
20 characters. For those devices that require the password as a
|
||||
protection, the service request shall be denied if the parameter
|
||||
is absent or if the password is incorrect. For those devices that
|
||||
do not require a password, this parameter shall be ignored.*/
|
||||
if (Reinit_Password && strlen(Reinit_Password) > 0) {
|
||||
if (characterstring_length(&rd_data->password) > 20) {
|
||||
rd_data->error_class = ERROR_CLASS_SERVICES;
|
||||
rd_data->error_code = ERROR_CODE_PARAMETER_OUT_OF_RANGE;
|
||||
} else if (characterstring_ansi_same(
|
||||
&rd_data->password, Reinit_Password)) {
|
||||
password_success = true;
|
||||
} else {
|
||||
rd_data->error_class = ERROR_CLASS_SECURITY;
|
||||
rd_data->error_code = ERROR_CODE_PASSWORD_FAILURE;
|
||||
}
|
||||
} else {
|
||||
password_success = true;
|
||||
}
|
||||
if (password_success) {
|
||||
switch (rd_data->state) {
|
||||
case BACNET_REINIT_COLDSTART:
|
||||
case BACNET_REINIT_WARMSTART:
|
||||
@@ -367,9 +416,6 @@ bool Device_Reinitialize(BACNET_REINITIALIZE_DEVICE_DATA *rd_data)
|
||||
rd_data->error_code = ERROR_CODE_PARAMETER_OUT_OF_RANGE;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
rd_data->error_class = ERROR_CLASS_SECURITY;
|
||||
rd_data->error_code = ERROR_CODE_PASSWORD_FAILURE;
|
||||
}
|
||||
|
||||
return status;
|
||||
@@ -705,9 +751,8 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
|
||||
case PROP_OBJECT_LIST:
|
||||
count = Device_Object_List_Count();
|
||||
apdu_len = bacnet_array_encode(rpdata->object_instance,
|
||||
rpdata->array_index,
|
||||
Device_Object_List_Element_Encode,
|
||||
count, apdu, apdu_max);
|
||||
rpdata->array_index, Device_Object_List_Element_Encode, count,
|
||||
apdu, apdu_max);
|
||||
if (apdu_len == BACNET_STATUS_ABORT) {
|
||||
rpdata->error_code =
|
||||
ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED;
|
||||
@@ -745,8 +790,7 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
|
||||
encode_application_unsigned(&apdu[0], dlmstp_max_master());
|
||||
break;
|
||||
case 9600:
|
||||
apdu_len =
|
||||
encode_application_unsigned(&apdu[0], rs485_baud_rate());
|
||||
apdu_len = encode_application_unsigned(&apdu[0], rs485_baud_rate());
|
||||
break;
|
||||
default:
|
||||
rpdata->error_class = ERROR_CLASS_PROPERTY;
|
||||
|
||||
@@ -67,8 +67,7 @@ static struct my_object_functions {
|
||||
read_property_function Object_Read_Property;
|
||||
write_property_function Object_Write_Property;
|
||||
rpm_property_lists_function Object_RPM_List;
|
||||
} Object_Table[] = {
|
||||
{ OBJECT_DEVICE, NULL, /* don't init - recursive! */
|
||||
} Object_Table[] = { { OBJECT_DEVICE, NULL, /* don't init - recursive! */
|
||||
Device_Count, Device_Index_To_Instance,
|
||||
Device_Valid_Object_Instance_Number,
|
||||
Device_Object_Name, Device_Read_Property_Local,
|
||||
@@ -161,8 +160,7 @@ int Device_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
|
||||
#if (BACNET_PROTOCOL_REVISION >= 14)
|
||||
if ((int)rpdata->object_property == PROP_PROPERTY_LIST) {
|
||||
Device_Objects_Property_List(rpdata->object_type,
|
||||
rpdata->object_instance,
|
||||
&property_list);
|
||||
rpdata->object_instance, &property_list);
|
||||
apdu_len = property_list_encode(rpdata,
|
||||
property_list.Required.pList,
|
||||
property_list.Optional.pList,
|
||||
@@ -306,12 +304,64 @@ bool Device_Object_Name(
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the ReinitializeDevice password
|
||||
*
|
||||
* The password shall be a null terminated C string of up to
|
||||
* 20 ASCII characters for those devices that require the password.
|
||||
*
|
||||
* For those devices that do not require a password, set to NULL or
|
||||
* point to a zero length C string (null terminated).
|
||||
*
|
||||
* @param the ReinitializeDevice password; can be NULL or empty string
|
||||
*/
|
||||
bool Device_Reinitialize_Password_Set(const char *password)
|
||||
{
|
||||
Reinit_Password = password;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Commands a Device re-initialization, to a given state.
|
||||
* The request's password must match for the operation to succeed.
|
||||
* This implementation provides a framework, but doesn't
|
||||
* actually *DO* anything.
|
||||
* @note You could use a mix of states and passwords to multiple outcomes.
|
||||
* @note You probably want to restart *after* the simple ack has been sent
|
||||
* from the return handler, so just set a local flag here.
|
||||
* @ingroup ObjIntf
|
||||
*
|
||||
* @param rd_data [in,out] The information from the RD request.
|
||||
* On failure, the error class and code will be set.
|
||||
* @return True if succeeds (password is correct), else False.
|
||||
*/
|
||||
bool Device_Reinitialize(BACNET_REINITIALIZE_DEVICE_DATA *rd_data)
|
||||
{
|
||||
bool status = false;
|
||||
bool password_success = false;
|
||||
|
||||
/* Note: you could use a mix of state and password to multiple things */
|
||||
if (characterstring_ansi_same(&rd_data->password, Reinit_Password)) {
|
||||
/* From 16.4.1.1.2 Password
|
||||
This optional parameter shall be a CharacterString of up to
|
||||
20 characters. For those devices that require the password as a
|
||||
protection, the service request shall be denied if the parameter
|
||||
is absent or if the password is incorrect. For those devices that
|
||||
do not require a password, this parameter shall be ignored.*/
|
||||
if (Reinit_Password && strlen(Reinit_Password) > 0) {
|
||||
if (characterstring_length(&rd_data->password) > 20) {
|
||||
rd_data->error_class = ERROR_CLASS_SERVICES;
|
||||
rd_data->error_code = ERROR_CODE_PARAMETER_OUT_OF_RANGE;
|
||||
} else if (characterstring_ansi_same(
|
||||
&rd_data->password, Reinit_Password)) {
|
||||
password_success = true;
|
||||
} else {
|
||||
rd_data->error_class = ERROR_CLASS_SECURITY;
|
||||
rd_data->error_code = ERROR_CODE_PASSWORD_FAILURE;
|
||||
}
|
||||
} else {
|
||||
password_success = true;
|
||||
}
|
||||
if (password_success) {
|
||||
switch (rd_data->state) {
|
||||
case BACNET_REINIT_COLDSTART:
|
||||
case BACNET_REINIT_WARMSTART:
|
||||
@@ -341,9 +391,6 @@ bool Device_Reinitialize(BACNET_REINITIALIZE_DEVICE_DATA *rd_data)
|
||||
rd_data->error_code = ERROR_CODE_PARAMETER_OUT_OF_RANGE;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
rd_data->error_class = ERROR_CLASS_SECURITY;
|
||||
rd_data->error_code = ERROR_CODE_PASSWORD_FAILURE;
|
||||
}
|
||||
|
||||
return status;
|
||||
@@ -695,9 +742,8 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
|
||||
case PROP_OBJECT_LIST:
|
||||
count = Device_Object_List_Count();
|
||||
apdu_len = bacnet_array_encode(rpdata->object_instance,
|
||||
rpdata->array_index,
|
||||
Device_Object_List_Element_Encode,
|
||||
count, apdu, apdu_max);
|
||||
rpdata->array_index, Device_Object_List_Element_Encode, count,
|
||||
apdu, apdu_max);
|
||||
if (apdu_len == BACNET_STATUS_ABORT) {
|
||||
rpdata->error_code =
|
||||
ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED;
|
||||
|
||||
@@ -52,14 +52,65 @@ static uint32_t Object_Instance_Number = 12345;
|
||||
static BACNET_DEVICE_STATUS System_Status = STATUS_OPERATIONAL;
|
||||
static uint8_t Database_Revision;
|
||||
BACNET_REINITIALIZED_STATE Reinitialize_State = BACNET_REINIT_IDLE;
|
||||
static char Reinit_Password[16] = "filister";
|
||||
static const char *Reinit_Password = "filister";
|
||||
|
||||
/**
|
||||
* @brief Sets the ReinitializeDevice password
|
||||
*
|
||||
* The password shall be a null terminated C string of up to
|
||||
* 20 ASCII characters for those devices that require the password.
|
||||
*
|
||||
* For those devices that do not require a password, set to NULL or
|
||||
* point to a zero length C string (null terminated).
|
||||
*
|
||||
* @param the ReinitializeDevice password; can be NULL or empty string
|
||||
*/
|
||||
bool Device_Reinitialize_Password_Set(const char *password)
|
||||
{
|
||||
Reinit_Password = password;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Commands a Device re-initialization, to a given state.
|
||||
* The request's password must match for the operation to succeed.
|
||||
* This implementation provides a framework, but doesn't
|
||||
* actually *DO* anything.
|
||||
* @note You could use a mix of states and passwords to multiple outcomes.
|
||||
* @note You probably want to restart *after* the simple ack has been sent
|
||||
* from the return handler, so just set a local flag here.
|
||||
* @ingroup ObjIntf
|
||||
*
|
||||
* @param rd_data [in,out] The information from the RD request.
|
||||
* On failure, the error class and code will be set.
|
||||
* @return True if succeeds (password is correct), else False.
|
||||
*/
|
||||
bool Device_Reinitialize(BACNET_REINITIALIZE_DEVICE_DATA *rd_data)
|
||||
{
|
||||
bool status = false;
|
||||
bool password_success = false;
|
||||
|
||||
/* Note: you could use a mix of state and password to multiple things */
|
||||
if (characterstring_ansi_same(&rd_data->password, Reinit_Password)) {
|
||||
/* From 16.4.1.1.2 Password
|
||||
This optional parameter shall be a CharacterString of up to
|
||||
20 characters. For those devices that require the password as a
|
||||
protection, the service request shall be denied if the parameter
|
||||
is absent or if the password is incorrect. For those devices that
|
||||
do not require a password, this parameter shall be ignored.*/
|
||||
if (Reinit_Password && strlen(Reinit_Password) > 0) {
|
||||
if (characterstring_length(&rd_data->password) > 20) {
|
||||
rd_data->error_class = ERROR_CLASS_SERVICES;
|
||||
rd_data->error_code = ERROR_CODE_PARAMETER_OUT_OF_RANGE;
|
||||
} else if (characterstring_ansi_same(
|
||||
&rd_data->password, Reinit_Password)) {
|
||||
password_success = true;
|
||||
} else {
|
||||
rd_data->error_class = ERROR_CLASS_SECURITY;
|
||||
rd_data->error_code = ERROR_CODE_PASSWORD_FAILURE;
|
||||
}
|
||||
} else {
|
||||
password_success = true;
|
||||
}
|
||||
if (password_success) {
|
||||
switch (rd_data->state) {
|
||||
case BACNET_REINIT_COLDSTART:
|
||||
case BACNET_REINIT_WARMSTART:
|
||||
@@ -89,9 +140,6 @@ bool Device_Reinitialize(BACNET_REINITIALIZE_DEVICE_DATA *rd_data)
|
||||
rd_data->error_code = ERROR_CODE_PARAMETER_OUT_OF_RANGE;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
rd_data->error_class = ERROR_CLASS_SECURITY;
|
||||
rd_data->error_code = ERROR_CODE_PASSWORD_FAILURE;
|
||||
}
|
||||
|
||||
return status;
|
||||
|
||||
+54
-5
@@ -271,12 +271,64 @@ uint32_t Device_Index_To_Instance(unsigned index)
|
||||
return Object_Instance_Number;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the ReinitializeDevice password
|
||||
*
|
||||
* The password shall be a null terminated C string of up to
|
||||
* 20 ASCII characters for those devices that require the password.
|
||||
*
|
||||
* For those devices that do not require a password, set to NULL or
|
||||
* point to a zero length C string (null terminated).
|
||||
*
|
||||
* @param the ReinitializeDevice password; can be NULL or empty string
|
||||
*/
|
||||
bool Device_Reinitialize_Password_Set(const char *password)
|
||||
{
|
||||
Reinit_Password = password;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Commands a Device re-initialization, to a given state.
|
||||
* The request's password must match for the operation to succeed.
|
||||
* This implementation provides a framework, but doesn't
|
||||
* actually *DO* anything.
|
||||
* @note You could use a mix of states and passwords to multiple outcomes.
|
||||
* @note You probably want to restart *after* the simple ack has been sent
|
||||
* from the return handler, so just set a local flag here.
|
||||
* @ingroup ObjIntf
|
||||
*
|
||||
* @param rd_data [in,out] The information from the RD request.
|
||||
* On failure, the error class and code will be set.
|
||||
* @return True if succeeds (password is correct), else False.
|
||||
*/
|
||||
bool Device_Reinitialize(BACNET_REINITIALIZE_DEVICE_DATA *rd_data)
|
||||
{
|
||||
bool status = false;
|
||||
bool password_success = false;
|
||||
|
||||
/* Note: you could use a mix of state and password to multiple things */
|
||||
if (characterstring_ansi_same(&rd_data->password, Reinit_Password)) {
|
||||
/* From 16.4.1.1.2 Password
|
||||
This optional parameter shall be a CharacterString of up to
|
||||
20 characters. For those devices that require the password as a
|
||||
protection, the service request shall be denied if the parameter
|
||||
is absent or if the password is incorrect. For those devices that
|
||||
do not require a password, this parameter shall be ignored.*/
|
||||
if (Reinit_Password && strlen(Reinit_Password) > 0) {
|
||||
if (characterstring_length(&rd_data->password) > 20) {
|
||||
rd_data->error_class = ERROR_CLASS_SERVICES;
|
||||
rd_data->error_code = ERROR_CODE_PARAMETER_OUT_OF_RANGE;
|
||||
} else if (characterstring_ansi_same(
|
||||
&rd_data->password, Reinit_Password)) {
|
||||
password_success = true;
|
||||
} else {
|
||||
rd_data->error_class = ERROR_CLASS_SECURITY;
|
||||
rd_data->error_code = ERROR_CODE_PASSWORD_FAILURE;
|
||||
}
|
||||
} else {
|
||||
password_success = true;
|
||||
}
|
||||
if (password_success) {
|
||||
switch (rd_data->state) {
|
||||
case BACNET_REINIT_COLDSTART:
|
||||
case BACNET_REINIT_WARMSTART:
|
||||
@@ -306,9 +358,6 @@ bool Device_Reinitialize(BACNET_REINITIALIZE_DEVICE_DATA *rd_data)
|
||||
rd_data->error_code = ERROR_CODE_PARAMETER_OUT_OF_RANGE;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
rd_data->error_class = ERROR_CLASS_SECURITY;
|
||||
rd_data->error_code = ERROR_CODE_PASSWORD_FAILURE;
|
||||
}
|
||||
|
||||
return status;
|
||||
|
||||
@@ -342,12 +342,64 @@ bool Device_Set_Object_Name(BACNET_CHARACTER_STRING *object_name)
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the ReinitializeDevice password
|
||||
*
|
||||
* The password shall be a null terminated C string of up to
|
||||
* 20 ASCII characters for those devices that require the password.
|
||||
*
|
||||
* For those devices that do not require a password, set to NULL or
|
||||
* point to a zero length C string (null terminated).
|
||||
*
|
||||
* @param the ReinitializeDevice password; can be NULL or empty string
|
||||
*/
|
||||
bool Device_Reinitialize_Password_Set(const char *password)
|
||||
{
|
||||
Reinit_Password = password;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Commands a Device re-initialization, to a given state.
|
||||
* The request's password must match for the operation to succeed.
|
||||
* This implementation provides a framework, but doesn't
|
||||
* actually *DO* anything.
|
||||
* @note You could use a mix of states and passwords to multiple outcomes.
|
||||
* @note You probably want to restart *after* the simple ack has been sent
|
||||
* from the return handler, so just set a local flag here.
|
||||
* @ingroup ObjIntf
|
||||
*
|
||||
* @param rd_data [in,out] The information from the RD request.
|
||||
* On failure, the error class and code will be set.
|
||||
* @return True if succeeds (password is correct), else False.
|
||||
*/
|
||||
bool Device_Reinitialize(BACNET_REINITIALIZE_DEVICE_DATA *rd_data)
|
||||
{
|
||||
bool status = false;
|
||||
bool password_success = false;
|
||||
|
||||
/* Note: you could use a mix of state and password to multiple things */
|
||||
if (characterstring_ansi_same(&rd_data->password, Reinit_Password)) {
|
||||
/* From 16.4.1.1.2 Password
|
||||
This optional parameter shall be a CharacterString of up to
|
||||
20 characters. For those devices that require the password as a
|
||||
protection, the service request shall be denied if the parameter
|
||||
is absent or if the password is incorrect. For those devices that
|
||||
do not require a password, this parameter shall be ignored.*/
|
||||
if (Reinit_Password && strlen(Reinit_Password) > 0) {
|
||||
if (characterstring_length(&rd_data->password) > 20) {
|
||||
rd_data->error_class = ERROR_CLASS_SERVICES;
|
||||
rd_data->error_code = ERROR_CODE_PARAMETER_OUT_OF_RANGE;
|
||||
} else if (characterstring_ansi_same(
|
||||
&rd_data->password, Reinit_Password)) {
|
||||
password_success = true;
|
||||
} else {
|
||||
rd_data->error_class = ERROR_CLASS_SECURITY;
|
||||
rd_data->error_code = ERROR_CODE_PASSWORD_FAILURE;
|
||||
}
|
||||
} else {
|
||||
password_success = true;
|
||||
}
|
||||
if (password_success) {
|
||||
switch (rd_data->state) {
|
||||
case BACNET_REINIT_COLDSTART:
|
||||
case BACNET_REINIT_WARMSTART:
|
||||
@@ -379,9 +431,6 @@ bool Device_Reinitialize(BACNET_REINITIALIZE_DEVICE_DATA *rd_data)
|
||||
rd_data->error_code = ERROR_CODE_PARAMETER_OUT_OF_RANGE;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
rd_data->error_class = ERROR_CLASS_SECURITY;
|
||||
rd_data->error_code = ERROR_CODE_PASSWORD_FAILURE;
|
||||
}
|
||||
|
||||
return status;
|
||||
|
||||
@@ -336,12 +336,64 @@ bool Device_Set_Object_Name(BACNET_CHARACTER_STRING *object_name)
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the ReinitializeDevice password
|
||||
*
|
||||
* The password shall be a null terminated C string of up to
|
||||
* 20 ASCII characters for those devices that require the password.
|
||||
*
|
||||
* For those devices that do not require a password, set to NULL or
|
||||
* point to a zero length C string (null terminated).
|
||||
*
|
||||
* @param the ReinitializeDevice password; can be NULL or empty string
|
||||
*/
|
||||
bool Device_Reinitialize_Password_Set(const char *password)
|
||||
{
|
||||
Reinit_Password = password;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Commands a Device re-initialization, to a given state.
|
||||
* The request's password must match for the operation to succeed.
|
||||
* This implementation provides a framework, but doesn't
|
||||
* actually *DO* anything.
|
||||
* @note You could use a mix of states and passwords to multiple outcomes.
|
||||
* @note You probably want to restart *after* the simple ack has been sent
|
||||
* from the return handler, so just set a local flag here.
|
||||
* @ingroup ObjIntf
|
||||
*
|
||||
* @param rd_data [in,out] The information from the RD request.
|
||||
* On failure, the error class and code will be set.
|
||||
* @return True if succeeds (password is correct), else False.
|
||||
*/
|
||||
bool Device_Reinitialize(BACNET_REINITIALIZE_DEVICE_DATA *rd_data)
|
||||
{
|
||||
bool status = false;
|
||||
bool password_success = false;
|
||||
|
||||
/* Note: you could use a mix of state and password to multiple things */
|
||||
if (characterstring_ansi_same(&rd_data->password, Reinit_Password)) {
|
||||
/* From 16.4.1.1.2 Password
|
||||
This optional parameter shall be a CharacterString of up to
|
||||
20 characters. For those devices that require the password as a
|
||||
protection, the service request shall be denied if the parameter
|
||||
is absent or if the password is incorrect. For those devices that
|
||||
do not require a password, this parameter shall be ignored.*/
|
||||
if (Reinit_Password && strlen(Reinit_Password) > 0) {
|
||||
if (characterstring_length(&rd_data->password) > 20) {
|
||||
rd_data->error_class = ERROR_CLASS_SERVICES;
|
||||
rd_data->error_code = ERROR_CODE_PARAMETER_OUT_OF_RANGE;
|
||||
} else if (characterstring_ansi_same(
|
||||
&rd_data->password, Reinit_Password)) {
|
||||
password_success = true;
|
||||
} else {
|
||||
rd_data->error_class = ERROR_CLASS_SECURITY;
|
||||
rd_data->error_code = ERROR_CODE_PASSWORD_FAILURE;
|
||||
}
|
||||
} else {
|
||||
password_success = true;
|
||||
}
|
||||
if (password_success) {
|
||||
switch (rd_data->state) {
|
||||
case BACNET_REINIT_COLDSTART:
|
||||
case BACNET_REINIT_WARMSTART:
|
||||
@@ -373,9 +425,6 @@ bool Device_Reinitialize(BACNET_REINITIALIZE_DEVICE_DATA *rd_data)
|
||||
rd_data->error_code = ERROR_CODE_PARAMETER_OUT_OF_RANGE;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
rd_data->error_class = ERROR_CLASS_SECURITY;
|
||||
rd_data->error_code = ERROR_CODE_PASSWORD_FAILURE;
|
||||
}
|
||||
|
||||
return status;
|
||||
|
||||
@@ -98,8 +98,8 @@ static object_functions_t My_Object_Table[] = {
|
||||
Device_Property_Lists, DeviceGetRRInfo, NULL /* Iterator */,
|
||||
NULL /* Value_Lists */, NULL /* COV */, NULL /* COV Clear */,
|
||||
NULL /* Intrinsic Reporting */, NULL /* Add_List_Element */,
|
||||
NULL /* Remove_List_Element */,
|
||||
NULL /* Create */, NULL /* Delete */, NULL /* Timer */ },
|
||||
NULL /* Remove_List_Element */, NULL /* Create */, NULL /* Delete */,
|
||||
NULL /* Timer */ },
|
||||
#if (BACNET_PROTOCOL_REVISION >= 17)
|
||||
{ OBJECT_NETWORK_PORT, Network_Port_Init, Network_Port_Count,
|
||||
Network_Port_Index_To_Instance, Network_Port_Valid_Instance,
|
||||
@@ -108,7 +108,7 @@ static object_functions_t My_Object_Table[] = {
|
||||
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
|
||||
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
|
||||
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
|
||||
NULL /* Create */, NULL /* Delete */ , NULL /* Timer */},
|
||||
NULL /* Create */, NULL /* Delete */, NULL /* Timer */ },
|
||||
#endif
|
||||
{ OBJECT_ANALOG_INPUT, Analog_Input_Init, Analog_Input_Count,
|
||||
Analog_Input_Index_To_Instance, Analog_Input_Valid_Instance,
|
||||
@@ -118,7 +118,7 @@ static object_functions_t My_Object_Table[] = {
|
||||
Analog_Input_Encode_Value_List, Analog_Input_Change_Of_Value,
|
||||
Analog_Input_Change_Of_Value_Clear, Analog_Input_Intrinsic_Reporting,
|
||||
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
|
||||
NULL /* Create */, NULL /* Delete */ , NULL /* Timer */},
|
||||
NULL /* Create */, NULL /* Delete */, NULL /* Timer */ },
|
||||
{ OBJECT_ANALOG_OUTPUT, Analog_Output_Init, Analog_Output_Count,
|
||||
Analog_Output_Index_To_Instance, Analog_Output_Valid_Instance,
|
||||
Analog_Output_Object_Name, Analog_Output_Read_Property,
|
||||
@@ -126,7 +126,7 @@ static object_functions_t My_Object_Table[] = {
|
||||
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
|
||||
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
|
||||
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
|
||||
Analog_Output_Create, Analog_Output_Delete, NULL /* Timer */},
|
||||
Analog_Output_Create, Analog_Output_Delete, NULL /* Timer */ },
|
||||
{ OBJECT_ANALOG_VALUE, Analog_Value_Init, Analog_Value_Count,
|
||||
Analog_Value_Index_To_Instance, Analog_Value_Valid_Instance,
|
||||
Analog_Value_Object_Name, Analog_Value_Read_Property,
|
||||
@@ -152,7 +152,7 @@ static object_functions_t My_Object_Table[] = {
|
||||
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
|
||||
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
|
||||
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
|
||||
Binary_Output_Create, Binary_Output_Delete, NULL /* Timer */},
|
||||
Binary_Output_Create, Binary_Output_Delete, NULL /* Timer */ },
|
||||
{ OBJECT_BINARY_VALUE, Binary_Value_Init, Binary_Value_Count,
|
||||
Binary_Value_Index_To_Instance, Binary_Value_Valid_Instance,
|
||||
Binary_Value_Object_Name, Binary_Value_Read_Property,
|
||||
@@ -171,8 +171,8 @@ static object_functions_t My_Object_Table[] = {
|
||||
CharacterString_Value_Change_Of_Value,
|
||||
CharacterString_Value_Change_Of_Value_Clear,
|
||||
NULL /* Intrinsic Reporting */, NULL /* Add_List_Element */,
|
||||
NULL /* Remove_List_Element */,
|
||||
NULL /* Create */, NULL /* Delete */, NULL /* Timer */ },
|
||||
NULL /* Remove_List_Element */, NULL /* Create */, NULL /* Delete */,
|
||||
NULL /* Timer */ },
|
||||
{ OBJECT_COMMAND, Command_Init, Command_Count, Command_Index_To_Instance,
|
||||
Command_Valid_Instance, Command_Object_Name, Command_Read_Property,
|
||||
Command_Write_Property, Command_Property_Lists,
|
||||
@@ -197,8 +197,8 @@ static object_functions_t My_Object_Table[] = {
|
||||
NULL /* Iterator */, NULL /* Value_Lists */, NULL /* COV */,
|
||||
NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
|
||||
Notification_Class_Add_List_Element,
|
||||
Notification_Class_Remove_List_Element,
|
||||
NULL /* Create */, NULL /* Delete */, NULL /* Timer */ },
|
||||
Notification_Class_Remove_List_Element, NULL /* Create */,
|
||||
NULL /* Delete */, NULL /* Timer */ },
|
||||
#endif
|
||||
{ OBJECT_LIFE_SAFETY_POINT, Life_Safety_Point_Init, Life_Safety_Point_Count,
|
||||
Life_Safety_Point_Index_To_Instance, Life_Safety_Point_Valid_Instance,
|
||||
@@ -207,7 +207,7 @@ static object_functions_t My_Object_Table[] = {
|
||||
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
|
||||
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
|
||||
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
|
||||
NULL /* Create */, NULL /* Delete */ , NULL /* Timer */},
|
||||
NULL /* Create */, NULL /* Delete */, NULL /* Timer */ },
|
||||
{ OBJECT_LOAD_CONTROL, Load_Control_Init, Load_Control_Count,
|
||||
Load_Control_Index_To_Instance, Load_Control_Valid_Instance,
|
||||
Load_Control_Object_Name, Load_Control_Read_Property,
|
||||
@@ -215,7 +215,7 @@ static object_functions_t My_Object_Table[] = {
|
||||
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
|
||||
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
|
||||
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
|
||||
NULL /* Create */, NULL /* Delete */ , NULL /* Timer */},
|
||||
NULL /* Create */, NULL /* Delete */, NULL /* Timer */ },
|
||||
{ OBJECT_MULTI_STATE_INPUT, Multistate_Input_Init, Multistate_Input_Count,
|
||||
Multistate_Input_Index_To_Instance, Multistate_Input_Valid_Instance,
|
||||
Multistate_Input_Object_Name, Multistate_Input_Read_Property,
|
||||
@@ -223,7 +223,7 @@ static object_functions_t My_Object_Table[] = {
|
||||
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
|
||||
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
|
||||
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
|
||||
NULL /* Create */, NULL /* Delete */ , NULL /* Timer */},
|
||||
NULL /* Create */, NULL /* Delete */, NULL /* Timer */ },
|
||||
{ OBJECT_MULTI_STATE_OUTPUT, Multistate_Output_Init,
|
||||
Multistate_Output_Count, Multistate_Output_Index_To_Instance,
|
||||
Multistate_Output_Valid_Instance, Multistate_Output_Object_Name,
|
||||
@@ -232,7 +232,7 @@ static object_functions_t My_Object_Table[] = {
|
||||
NULL /* Iterator */, NULL /* Value_Lists */, NULL /* COV */,
|
||||
NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
|
||||
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
|
||||
Multistate_Output_Create, Multistate_Output_Delete, NULL /* Timer */},
|
||||
Multistate_Output_Create, Multistate_Output_Delete, NULL /* Timer */ },
|
||||
{ OBJECT_MULTI_STATE_VALUE, Multistate_Value_Init, Multistate_Value_Count,
|
||||
Multistate_Value_Index_To_Instance, Multistate_Value_Valid_Instance,
|
||||
Multistate_Value_Object_Name, Multistate_Value_Read_Property,
|
||||
@@ -241,7 +241,7 @@ static object_functions_t My_Object_Table[] = {
|
||||
Multistate_Value_Encode_Value_List, Multistate_Value_Change_Of_Value,
|
||||
Multistate_Value_Change_Of_Value_Clear, NULL /* Intrinsic Reporting */,
|
||||
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
|
||||
NULL /* Create */, NULL /* Delete */ , NULL /* Timer */},
|
||||
NULL /* Create */, NULL /* Delete */, NULL /* Timer */ },
|
||||
{ OBJECT_TRENDLOG, Trend_Log_Init, Trend_Log_Count,
|
||||
Trend_Log_Index_To_Instance, Trend_Log_Valid_Instance,
|
||||
Trend_Log_Object_Name, Trend_Log_Read_Property,
|
||||
@@ -249,7 +249,7 @@ static object_functions_t My_Object_Table[] = {
|
||||
NULL /* Iterator */, NULL /* Value_Lists */, NULL /* COV */,
|
||||
NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
|
||||
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
|
||||
NULL /* Create */, NULL /* Delete */ , NULL /* Timer */},
|
||||
NULL /* Create */, NULL /* Delete */, NULL /* Timer */ },
|
||||
#if (BACNET_PROTOCOL_REVISION >= 14)
|
||||
{ OBJECT_LIGHTING_OUTPUT, Lighting_Output_Init, Lighting_Output_Count,
|
||||
Lighting_Output_Index_To_Instance, Lighting_Output_Valid_Instance,
|
||||
@@ -258,7 +258,7 @@ static object_functions_t My_Object_Table[] = {
|
||||
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
|
||||
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
|
||||
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
|
||||
Lighting_Output_Create, Lighting_Output_Delete, Lighting_Output_Timer},
|
||||
Lighting_Output_Create, Lighting_Output_Delete, Lighting_Output_Timer },
|
||||
{ OBJECT_CHANNEL, Channel_Init, Channel_Count, Channel_Index_To_Instance,
|
||||
Channel_Valid_Instance, Channel_Object_Name, Channel_Read_Property,
|
||||
Channel_Write_Property, Channel_Property_Lists,
|
||||
@@ -274,7 +274,7 @@ static object_functions_t My_Object_Table[] = {
|
||||
NULL /* Iterator */, NULL /* Value_Lists */, NULL /* COV */,
|
||||
NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
|
||||
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
|
||||
Color_Create, Color_Delete, Color_Timer},
|
||||
Color_Create, Color_Delete, Color_Timer },
|
||||
{ OBJECT_COLOR_TEMPERATURE, Color_Temperature_Init, Color_Temperature_Count,
|
||||
Color_Temperature_Index_To_Instance, Color_Temperature_Valid_Instance,
|
||||
Color_Temperature_Object_Name, Color_Temperature_Read_Property,
|
||||
@@ -283,7 +283,7 @@ static object_functions_t My_Object_Table[] = {
|
||||
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
|
||||
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
|
||||
Color_Temperature_Create, Color_Temperature_Delete,
|
||||
Color_Temperature_Timer},
|
||||
Color_Temperature_Timer },
|
||||
#endif
|
||||
#if defined(BACFILE)
|
||||
{ OBJECT_FILE, bacfile_init, bacfile_count, bacfile_index_to_instance,
|
||||
@@ -292,7 +292,7 @@ static object_functions_t My_Object_Table[] = {
|
||||
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
|
||||
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
|
||||
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
|
||||
bacfile_create, bacfile_delete, NULL /* Timer */},
|
||||
bacfile_create, bacfile_delete, NULL /* Timer */ },
|
||||
#endif
|
||||
{ OBJECT_OCTETSTRING_VALUE, OctetString_Value_Init, OctetString_Value_Count,
|
||||
OctetString_Value_Index_To_Instance, OctetString_Value_Valid_Instance,
|
||||
@@ -318,8 +318,8 @@ static object_functions_t My_Object_Table[] = {
|
||||
Schedule_Property_Lists, NULL /* ReadRangeInfo */, NULL /* Iterator */,
|
||||
NULL /* Value_Lists */, NULL /* COV */, NULL /* COV Clear */,
|
||||
NULL /* Intrinsic Reporting */, NULL /* Add_List_Element */,
|
||||
NULL /* Remove_List_Element */,
|
||||
NULL /* Create */, NULL /* Delete */, NULL /* Timer */ },
|
||||
NULL /* Remove_List_Element */, NULL /* Create */, NULL /* Delete */,
|
||||
NULL /* Timer */ },
|
||||
{ OBJECT_ACCUMULATOR, Accumulator_Init, Accumulator_Count,
|
||||
Accumulator_Index_To_Instance, Accumulator_Valid_Instance,
|
||||
Accumulator_Object_Name, Accumulator_Read_Property,
|
||||
@@ -327,7 +327,7 @@ static object_functions_t My_Object_Table[] = {
|
||||
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
|
||||
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
|
||||
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
|
||||
NULL /* Create */, NULL /* Delete */ , NULL /* Timer */},
|
||||
NULL /* Create */, NULL /* Delete */, NULL /* Timer */ },
|
||||
{ MAX_BACNET_OBJECT_TYPE, NULL /* Init */, NULL /* Count */,
|
||||
NULL /* Index_To_Instance */, NULL /* Valid_Instance */,
|
||||
NULL /* Object_Name */, NULL /* Read_Property */,
|
||||
@@ -528,6 +528,24 @@ static uint32_t Database_Revision = 0;
|
||||
static BACNET_REINITIALIZED_STATE Reinitialize_State = BACNET_REINIT_IDLE;
|
||||
static const char *Reinit_Password = "filister";
|
||||
|
||||
/**
|
||||
* @brief Sets the ReinitializeDevice password
|
||||
*
|
||||
* The password shall be a null terminated C string of up to
|
||||
* 20 ASCII characters for those devices that require the password.
|
||||
*
|
||||
* For those devices that do not require a password, set to NULL or
|
||||
* point to a zero length C string (null terminated).
|
||||
*
|
||||
* @param the ReinitializeDevice password; can be NULL or empty string
|
||||
*/
|
||||
bool Device_Reinitialize_Password_Set(const char *password)
|
||||
{
|
||||
Reinit_Password = password;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Commands a Device re-initialization, to a given state.
|
||||
* The request's password must match for the operation to succeed.
|
||||
* This implementation provides a framework, but doesn't
|
||||
@@ -544,6 +562,7 @@ static const char *Reinit_Password = "filister";
|
||||
bool Device_Reinitialize(BACNET_REINITIALIZE_DEVICE_DATA *rd_data)
|
||||
{
|
||||
bool status = false;
|
||||
bool password_success = false;
|
||||
|
||||
/* From 16.4.1.1.2 Password
|
||||
This optional parameter shall be a CharacterString of up to
|
||||
@@ -551,12 +570,21 @@ bool Device_Reinitialize(BACNET_REINITIALIZE_DEVICE_DATA *rd_data)
|
||||
protection, the service request shall be denied if the parameter
|
||||
is absent or if the password is incorrect. For those devices that
|
||||
do not require a password, this parameter shall be ignored.*/
|
||||
if (Reinit_Password && strlen(Reinit_Password) > 0) {
|
||||
if (characterstring_length(&rd_data->password) > 20) {
|
||||
rd_data->error_class = ERROR_CLASS_SERVICES;
|
||||
rd_data->error_code = ERROR_CODE_PARAMETER_OUT_OF_RANGE;
|
||||
} else if (characterstring_ansi_same(&rd_data->password, Reinit_Password)) {
|
||||
/* Note: you could use a mix of state and password to
|
||||
accomplish multiple things before restarting */
|
||||
} else if (characterstring_ansi_same(
|
||||
&rd_data->password, Reinit_Password)) {
|
||||
password_success = true;
|
||||
} else {
|
||||
rd_data->error_class = ERROR_CLASS_SECURITY;
|
||||
rd_data->error_code = ERROR_CODE_PASSWORD_FAILURE;
|
||||
}
|
||||
} else {
|
||||
password_success = true;
|
||||
}
|
||||
if (password_success) {
|
||||
switch (rd_data->state) {
|
||||
case BACNET_REINIT_COLDSTART:
|
||||
case BACNET_REINIT_WARMSTART:
|
||||
@@ -586,9 +614,6 @@ bool Device_Reinitialize(BACNET_REINITIALIZE_DEVICE_DATA *rd_data)
|
||||
rd_data->error_code = ERROR_CODE_PARAMETER_OUT_OF_RANGE;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
rd_data->error_class = ERROR_CLASS_SECURITY;
|
||||
rd_data->error_code = ERROR_CODE_PASSWORD_FAILURE;
|
||||
}
|
||||
|
||||
return status;
|
||||
@@ -1306,9 +1331,8 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
|
||||
case PROP_OBJECT_LIST:
|
||||
count = Device_Object_List_Count();
|
||||
apdu_len = bacnet_array_encode(rpdata->object_instance,
|
||||
rpdata->array_index,
|
||||
Device_Object_List_Element_Encode,
|
||||
count, apdu, apdu_max);
|
||||
rpdata->array_index, Device_Object_List_Element_Encode, count,
|
||||
apdu, apdu_max);
|
||||
if (apdu_len == BACNET_STATUS_ABORT) {
|
||||
rpdata->error_code =
|
||||
ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED;
|
||||
@@ -1838,8 +1862,8 @@ bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
||||
}
|
||||
#endif
|
||||
if (wp_data->object_property == PROP_OBJECT_NAME) {
|
||||
status = Device_Write_Property_Object_Name(wp_data,
|
||||
pObject->Object_Write_Property);
|
||||
status = Device_Write_Property_Object_Name(
|
||||
wp_data, pObject->Object_Write_Property);
|
||||
} else {
|
||||
status = pObject->Object_Write_Property(wp_data);
|
||||
}
|
||||
@@ -1866,8 +1890,7 @@ bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
||||
* @return The length of the apdu encoded or #BACNET_STATUS_ERROR or
|
||||
* #BACNET_STATUS_ABORT or #BACNET_STATUS_REJECT.
|
||||
*/
|
||||
int Device_Add_List_Element(
|
||||
BACNET_LIST_ELEMENT_DATA * list_element)
|
||||
int Device_Add_List_Element(BACNET_LIST_ELEMENT_DATA *list_element)
|
||||
{
|
||||
int status = BACNET_STATUS_ERROR;
|
||||
struct object_functions *pObject = NULL;
|
||||
@@ -1901,8 +1924,7 @@ int Device_Add_List_Element(
|
||||
* @return The length of the apdu encoded or #BACNET_STATUS_ERROR or
|
||||
* #BACNET_STATUS_ABORT or #BACNET_STATUS_REJECT.
|
||||
*/
|
||||
int Device_Remove_List_Element(
|
||||
BACNET_LIST_ELEMENT_DATA * list_element)
|
||||
int Device_Remove_List_Element(BACNET_LIST_ELEMENT_DATA *list_element)
|
||||
{
|
||||
int status = BACNET_STATUS_ERROR;
|
||||
struct object_functions *pObject = NULL;
|
||||
@@ -2008,8 +2030,7 @@ void Device_COV_Clear(BACNET_OBJECT_TYPE object_type, uint32_t object_instance)
|
||||
* @param data - CreateObject data, including error codes if failures
|
||||
* @return true if object has been created
|
||||
*/
|
||||
bool Device_Create_Object(
|
||||
BACNET_CREATE_OBJECT_DATA *data)
|
||||
bool Device_Create_Object(BACNET_CREATE_OBJECT_DATA *data)
|
||||
{
|
||||
bool status = false;
|
||||
struct object_functions *pObject = NULL;
|
||||
@@ -2068,8 +2089,7 @@ bool Device_Create_Object(
|
||||
* @param data - DeleteObject data, including error codes if failures
|
||||
* @return true if object has been deleted
|
||||
*/
|
||||
bool Device_Delete_Object(
|
||||
BACNET_DELETE_OBJECT_DATA *data)
|
||||
bool Device_Delete_Object(BACNET_DELETE_OBJECT_DATA *data)
|
||||
{
|
||||
bool status = false;
|
||||
struct object_functions *pObject = NULL;
|
||||
@@ -2236,8 +2256,7 @@ bool DeviceGetRRInfo(BACNET_READ_RANGE_DATA *pRequest, /* Info on the request */
|
||||
* @brief Updates all the object timers with elapsed milliseconds
|
||||
* @param milliseconds - number of milliseconds elapsed
|
||||
*/
|
||||
void Device_Timer(
|
||||
uint16_t milliseconds)
|
||||
void Device_Timer(uint16_t milliseconds)
|
||||
{
|
||||
struct object_functions *pObject;
|
||||
unsigned count = 0;
|
||||
|
||||
@@ -254,6 +254,9 @@ extern "C" {
|
||||
BACNET_STACK_EXPORT
|
||||
BACNET_REINITIALIZED_STATE Device_Reinitialized_State(
|
||||
void);
|
||||
BACNET_STACK_EXPORT
|
||||
bool Device_Reinitialize_Password_Set(
|
||||
const char *password);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
rr_info_function Device_Objects_RR_Info(
|
||||
|
||||
@@ -173,8 +173,8 @@ void handler_device_communication_control(uint8_t *service_request,
|
||||
if (len > 0)
|
||||
goto DCC_ABORT;
|
||||
#endif
|
||||
|
||||
if (characterstring_ansi_same(&password, My_Password)) {
|
||||
if ((My_Password[0] == '\0') ||
|
||||
characterstring_ansi_same(&password, My_Password)) {
|
||||
len = encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id,
|
||||
SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL);
|
||||
|
||||
@@ -41,7 +41,8 @@ static void test_Device_Data_Sharing(void)
|
||||
rpdata.application_data = &apdu[0];
|
||||
rpdata.application_data_len = sizeof(apdu);
|
||||
rpdata.object_type = OBJECT_DEVICE;
|
||||
rpdata.object_instance = Device_Index_To_Instance(0);;
|
||||
rpdata.object_instance = Device_Index_To_Instance(0);
|
||||
;
|
||||
Device_Property_Lists(&pRequired, &pOptional, &pProprietary);
|
||||
while ((*pRequired) != -1) {
|
||||
rpdata.object_property = *pRequired;
|
||||
@@ -127,6 +128,7 @@ static void testDevice(void)
|
||||
{
|
||||
bool status = false;
|
||||
const char *name = "Patricia";
|
||||
BACNET_REINITIALIZE_DEVICE_DATA rd_data;
|
||||
|
||||
status = Device_Set_Object_Instance_Number(0);
|
||||
zassert_equal(Device_Object_Instance_Number(), 0, NULL);
|
||||
@@ -151,22 +153,74 @@ static void testDevice(void)
|
||||
Device_Set_Model_Name(name, strlen(name));
|
||||
zassert_equal(strcmp(Device_Model_Name(), name), 0, NULL);
|
||||
|
||||
/* Reinitialize with no device password */
|
||||
rd_data.error_class = ERROR_CLASS_DEVICE;
|
||||
rd_data.error_code = ERROR_CODE_SUCCESS;
|
||||
rd_data.state = BACNET_REINIT_COLDSTART;
|
||||
characterstring_init_ansi(&rd_data.password, NULL);
|
||||
status = Device_Reinitialize_Password_Set(NULL);
|
||||
status = Device_Reinitialize(&rd_data);
|
||||
zassert_true(status, NULL);
|
||||
zassert_equal(rd_data.error_class, ERROR_CLASS_DEVICE, "error-class=%s",
|
||||
bactext_error_class_name(rd_data.error_class));
|
||||
zassert_equal(rd_data.error_code, ERROR_CODE_SUCCESS, "error-code=%s",
|
||||
bactext_error_code_name(rd_data.error_code));
|
||||
/* Reinitialize with device valid password, service no password */
|
||||
status = Device_Reinitialize_Password_Set("valid");
|
||||
zassert_true(status, NULL);
|
||||
status = characterstring_init_ansi(&rd_data.password, NULL);
|
||||
zassert_true(status, NULL);
|
||||
status = Device_Reinitialize(&rd_data);
|
||||
zassert_false(status, NULL);
|
||||
zassert_equal(rd_data.error_class, ERROR_CLASS_SECURITY, "error-class=%s",
|
||||
bactext_error_class_name(rd_data.error_class));
|
||||
zassert_equal(rd_data.error_code, ERROR_CODE_PASSWORD_FAILURE,
|
||||
"error-code=%s", bactext_error_code_name(rd_data.error_code));
|
||||
/* Reinitialize with device valid password, service invalid password */
|
||||
status = characterstring_init_ansi(&rd_data.password, "invalid");
|
||||
zassert_true(status, NULL);
|
||||
status = Device_Reinitialize(&rd_data);
|
||||
zassert_false(status, NULL);
|
||||
zassert_equal(rd_data.error_class, ERROR_CLASS_SECURITY, "error-class=%s",
|
||||
bactext_error_class_name(rd_data.error_class));
|
||||
zassert_equal(rd_data.error_code, ERROR_CODE_PASSWORD_FAILURE,
|
||||
"error-code=%s", bactext_error_code_name(rd_data.error_code));
|
||||
/* Reinitialize with device valid password, service valid password */
|
||||
characterstring_init_ansi(&rd_data.password, "valid");
|
||||
status = Device_Reinitialize(&rd_data);
|
||||
zassert_true(status, NULL);
|
||||
/* Reinitialize with device valid password, service too long password */
|
||||
characterstring_init_ansi(&rd_data.password, "abcdefghijklmnopqrstuvwxyz");
|
||||
status = Device_Reinitialize(&rd_data);
|
||||
zassert_false(status, NULL);
|
||||
zassert_equal(rd_data.error_class, ERROR_CLASS_SERVICES, "error-class=%s",
|
||||
bactext_error_class_name(rd_data.error_class));
|
||||
zassert_equal(rd_data.error_code, ERROR_CODE_PARAMETER_OUT_OF_RANGE,
|
||||
"error-code=%s", bactext_error_code_name(rd_data.error_code));
|
||||
/* Reinitialize with device no password, unsupported state */
|
||||
status = Device_Reinitialize_Password_Set(NULL);
|
||||
zassert_true(status, NULL);
|
||||
rd_data.state = BACNET_REINIT_MAX;
|
||||
status = Device_Reinitialize(&rd_data);
|
||||
zassert_false(status, NULL);
|
||||
zassert_equal(rd_data.error_class, ERROR_CLASS_SERVICES, "error-class=%s",
|
||||
bactext_error_class_name(rd_data.error_class));
|
||||
zassert_equal(rd_data.error_code, ERROR_CODE_PARAMETER_OUT_OF_RANGE,
|
||||
"error-code=%s", bactext_error_code_name(rd_data.error_code));
|
||||
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
#if defined(CONFIG_ZTEST_NEW_API)
|
||||
ZTEST_SUITE(device_tests, NULL, NULL, NULL, NULL, NULL);
|
||||
#else
|
||||
void test_main(void)
|
||||
{
|
||||
ztest_test_suite(device_tests,
|
||||
ztest_unit_test(testDevice),
|
||||
ztest_unit_test(test_Device_Data_Sharing)
|
||||
);
|
||||
ztest_test_suite(device_tests, ztest_unit_test(testDevice),
|
||||
ztest_unit_test(test_Device_Data_Sharing));
|
||||
|
||||
ztest_run_test_suite(device_tests);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user