Skip to content

Commit 54dc647

Browse files
committed
Fixed basic device object to support fixes from upstream for BACnetARRAY and DCC and RD names.
1 parent 6aec7a0 commit 54dc647

File tree

1 file changed

+71
-76
lines changed

1 file changed

+71
-76
lines changed

zephyr/subsys/bacnet_basic/device.c

Lines changed: 71 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -810,6 +810,11 @@ bool Device_Reinitialize(BACNET_REINITIALIZE_DEVICE_DATA *rd_data)
810810
{
811811
bool status = false;
812812
bool password_success = false;
813+
#if defined(CONFIG_BACNET_BASIC_OBJECT_NETWORK_PORT)
814+
#if (BACNET_PROTOCOL_REVISION >= 17)
815+
unsigned i;
816+
#endif
817+
#endif
813818

814819
/* From 16.4.1.1.2 Password
815820
This optional parameter shall be a CharacterString of up to
@@ -818,7 +823,11 @@ bool Device_Reinitialize(BACNET_REINITIALIZE_DEVICE_DATA *rd_data)
818823
is absent or if the password is incorrect. For those devices that
819824
do not require a password, this parameter shall be ignored.*/
820825
if (characterstring_length(&Reinit_Password) > 0) {
821-
if (characterstring_length(&rd_data->password) > 20) {
826+
if ((characterstring_encoding(&rd_data->password) == CHARACTER_UTF8) &&
827+
(characterstring_utf8_length(&rd_data->password) > 20)) {
828+
rd_data->error_class = ERROR_CLASS_SERVICES;
829+
rd_data->error_code = ERROR_CODE_PARAMETER_OUT_OF_RANGE;
830+
} else if (characterstring_length(&rd_data->password) > 20) {
822831
rd_data->error_class = ERROR_CLASS_SERVICES;
823832
rd_data->error_code = ERROR_CODE_PARAMETER_OUT_OF_RANGE;
824833
} else if (characterstring_same(&rd_data->password, &Reinit_Password)) {
@@ -833,13 +842,26 @@ bool Device_Reinitialize(BACNET_REINITIALIZE_DEVICE_DATA *rd_data)
833842
if (password_success) {
834843
switch (rd_data->state) {
835844
case BACNET_REINIT_COLDSTART:
845+
dcc_set_status_duration(COMMUNICATION_ENABLE, 0);
846+
/* note: you probably want to restart *after* the
847+
simple ack has been sent from the return handler
848+
so just set a flag from here */
849+
Reinitialize_State = rd_data->state;
850+
status = true;
851+
break;
836852
case BACNET_REINIT_WARMSTART:
837853
dcc_set_status_duration(COMMUNICATION_ENABLE, 0);
838-
/* Note: you could use a mix of state
839-
and password to multiple things */
854+
#if defined(CONFIG_BACNET_BASIC_OBJECT_NETWORK_PORT)
855+
#if (BACNET_PROTOCOL_REVISION >= 17)
856+
for (i = 0; i < Network_Port_Count(); i++) {
857+
Network_Port_Changes_Pending_Activate(
858+
Network_Port_Index_To_Instance(i));
859+
}
860+
#endif
861+
#endif
840862
/* note: you probably want to restart *after* the
841-
simple ack has been sent from the return handler
842-
so just set a flag from here */
863+
simple ack has been sent from the return handler
864+
so just set a flag from here */
843865
Reinitialize_State = rd_data->state;
844866
status = true;
845867
break;
@@ -857,6 +879,19 @@ bool Device_Reinitialize(BACNET_REINITIALIZE_DEVICE_DATA *rd_data)
857879
ERROR_CODE_OPTIONAL_FUNCTIONALITY_NOT_SUPPORTED;
858880
}
859881
break;
882+
case BACNET_REINIT_ACTIVATE_CHANGES:
883+
/* note: activate changes *after* the simple ack is sent */
884+
#if defined(CONFIG_BACNET_BASIC_OBJECT_NETWORK_PORT)
885+
#if (BACNET_PROTOCOL_REVISION >= 17)
886+
for (i = 0; i < Network_Port_Count(); i++) {
887+
Network_Port_Changes_Pending_Activate(
888+
Network_Port_Index_To_Instance(i));
889+
}
890+
#endif
891+
#endif
892+
Reinitialize_State = rd_data->state;
893+
status = true;
894+
break;
860895
default:
861896
rd_data->error_class = ERROR_CLASS_SERVICES;
862897
rd_data->error_code = ERROR_CODE_PARAMETER_OUT_OF_RANGE;
@@ -1303,7 +1338,7 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
13031338
apdu_len = encode_application_unsigned(&apdu[0], apdu_retries());
13041339
break;
13051340
case PROP_DEVICE_ADDRESS_BINDING:
1306-
/* FIXME: encode the list here, if it exists */
1341+
apdu_len = address_list_encode(&apdu[0], apdu_max);
13071342
break;
13081343
case PROP_DATABASE_REVISION:
13091344
apdu_len = encode_application_unsigned(&apdu[0], Device_Database_Revision());
@@ -1356,7 +1391,8 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
13561391
* on entry, and APDU message on return.
13571392
* @return The length of the APDU on success, else BACNET_STATUS_ERROR
13581393
*/
1359-
static int Read_Property_Common(struct object_functions *pObject, BACNET_READ_PROPERTY_DATA *rpdata)
1394+
static int Read_Property_Common(const struct object_functions *pObject,
1395+
BACNET_READ_PROPERTY_DATA *rpdata)
13601396
{
13611397
int apdu_len = BACNET_STATUS_ERROR;
13621398
BACNET_CHARACTER_STRING char_string;
@@ -1369,61 +1405,24 @@ static int Read_Property_Common(struct object_functions *pObject, BACNET_READ_PR
13691405
return 0;
13701406
}
13711407
apdu = rpdata->application_data;
1372-
switch (rpdata->object_property) {
1373-
case PROP_OBJECT_IDENTIFIER:
1374-
/* only array properties can have array options */
1375-
if (rpdata->array_index != BACNET_ARRAY_ALL) {
1376-
rpdata->error_class = ERROR_CLASS_PROPERTY;
1377-
rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
1378-
apdu_len = BACNET_STATUS_ERROR;
1379-
} else {
1380-
/* Device Object exception: requested instance
1381-
may not match our instance if a wildcard */
1382-
if (rpdata->object_type == OBJECT_DEVICE) {
1383-
rpdata->object_instance = Object_Instance_Number;
1384-
}
1385-
apdu_len = encode_application_object_id(&apdu[0], rpdata->object_type,
1386-
rpdata->object_instance);
1408+
if (property_list_common(rpdata->object_property)) {
1409+
apdu_len = property_list_common_encode(rpdata, Object_Instance_Number);
1410+
} else if (rpdata->object_property == PROP_OBJECT_NAME) {
1411+
characterstring_init_ansi(&char_string, "");
1412+
if (pObject->Object_Name) {
1413+
(void)pObject->Object_Name(rpdata->object_instance, &char_string);
13871414
}
1388-
break;
1389-
case PROP_OBJECT_NAME:
1390-
/* only array properties can have array options */
1391-
if (rpdata->array_index != BACNET_ARRAY_ALL) {
1392-
rpdata->error_class = ERROR_CLASS_PROPERTY;
1393-
rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
1394-
apdu_len = BACNET_STATUS_ERROR;
1395-
} else {
1396-
characterstring_init_ansi(&char_string, "");
1397-
if (pObject->Object_Name) {
1398-
(void)pObject->Object_Name(rpdata->object_instance, &char_string);
1399-
}
1400-
apdu_len = encode_application_character_string(&apdu[0], &char_string);
1401-
}
1402-
break;
1403-
case PROP_OBJECT_TYPE:
1404-
/* only array properties can have array options */
1405-
if (rpdata->array_index != BACNET_ARRAY_ALL) {
1406-
rpdata->error_class = ERROR_CLASS_PROPERTY;
1407-
rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
1408-
apdu_len = BACNET_STATUS_ERROR;
1409-
} else {
1410-
apdu_len = encode_application_enumerated(&apdu[0], rpdata->object_type);
1411-
}
1412-
break;
1415+
apdu_len = encode_application_character_string(&apdu[0], &char_string);
14131416
#if (BACNET_PROTOCOL_REVISION >= 14)
1414-
case PROP_PROPERTY_LIST:
1417+
} else if (rpdata->object_property == PROP_PROPERTY_LIST) {
14151418
Device_Objects_Property_List(rpdata->object_type, rpdata->object_instance,
14161419
&property_list);
14171420
apdu_len = property_list_encode(rpdata, property_list.Required.pList,
14181421
property_list.Optional.pList,
14191422
property_list.Proprietary.pList);
1420-
break;
14211423
#endif
1422-
default:
1423-
if (pObject->Object_Read_Property) {
1424-
apdu_len = pObject->Object_Read_Property(rpdata);
1425-
}
1426-
break;
1424+
} else if (pObject->Object_Read_Property) {
1425+
apdu_len = pObject->Object_Read_Property(rpdata);
14271426
}
14281427

14291428
return apdu_len;
@@ -1473,25 +1472,20 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data)
14731472
BACNET_APPLICATION_DATA_VALUE value;
14741473

14751474
/* decode the some of the request */
1476-
len = bacapp_decode_application_data(wp_data->application_data,
1477-
wp_data->application_data_len, &value);
1475+
len = bacapp_decode_known_property(wp_data->application_data, wp_data->application_data_len,
1476+
&value, wp_data->object_type, wp_data->object_property);
14781477
/* FIXME: len < application_data_len: more data? */
14791478
if (len < 0) {
14801479
/* error while decoding - a value larger than we can handle */
14811480
wp_data->error_class = ERROR_CLASS_PROPERTY;
14821481
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
14831482
return false;
14841483
}
1485-
if ((wp_data->object_property != PROP_OBJECT_LIST) &&
1486-
(wp_data->array_index != BACNET_ARRAY_ALL)) {
1487-
/* only array properties can have array options */
1488-
wp_data->error_class = ERROR_CLASS_PROPERTY;
1489-
wp_data->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
1490-
return false;
1491-
}
14921484
switch ((int)wp_data->object_property) {
14931485
case PROP_OBJECT_IDENTIFIER:
1494-
if (value.tag == BACNET_APPLICATION_TAG_OBJECT_ID) {
1486+
status = write_property_type_valid(wp_data, &value,
1487+
BACNET_APPLICATION_TAG_OBJECT_ID);
1488+
if (status) {
14951489
if ((value.type.Object_Id.type == OBJECT_DEVICE) &&
14961490
(Device_Set_Object_Instance_Number(value.type.Object_Id.instance))) {
14971491
/* we could send an I-Am broadcast to let the world know */
@@ -1500,9 +1494,6 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data)
15001494
wp_data->error_class = ERROR_CLASS_PROPERTY;
15011495
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
15021496
}
1503-
} else {
1504-
wp_data->error_class = ERROR_CLASS_PROPERTY;
1505-
wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
15061497
}
15071498
break;
15081499
#if defined(BACDL_MSTP)
@@ -1544,7 +1535,8 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data)
15441535
} else if (length < characterstring_capacity(&My_Object_Name)) {
15451536
encoding = characterstring_encoding(&value.type.Character_String);
15461537
if (encoding < MAX_CHARACTER_STRING_ENCODING) {
1547-
/* All the object names in a device must be unique. */
1538+
/* All the object names in a device must be unique.
1539+
*/
15481540
if (Device_Valid_Object_Name(&value.type.Character_String,
15491541
NULL, NULL)) {
15501542
wp_data->error_class = ERROR_CLASS_PROPERTY;
@@ -1606,12 +1598,6 @@ static bool Device_Write_Property_Object_Name(BACNET_WRITE_PROPERTY_DATA *wp_dat
16061598
if (!wp_data) {
16071599
return false;
16081600
}
1609-
if (wp_data->array_index != BACNET_ARRAY_ALL) {
1610-
/* only array properties can have array options */
1611-
wp_data->error_class = ERROR_CLASS_PROPERTY;
1612-
wp_data->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
1613-
return false;
1614-
}
16151601
apdu = wp_data->application_data;
16161602
apdu_size = wp_data->application_data_len;
16171603
len = bacnet_character_string_application_decode(apdu, apdu_size, &value);
@@ -1709,8 +1695,17 @@ bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
17091695
Device_Write_Property_Store(wp_data);
17101696
}
17111697
} else {
1712-
wp_data->error_class = ERROR_CLASS_PROPERTY;
1713-
wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
1698+
if (Device_Objects_Property_List_Member(wp_data->object_type,
1699+
wp_data->object_instance,
1700+
wp_data->object_property)) {
1701+
/* this property is not writable */
1702+
wp_data->error_class = ERROR_CLASS_PROPERTY;
1703+
wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
1704+
} else {
1705+
/* this property is not supported */
1706+
wp_data->error_class = ERROR_CLASS_PROPERTY;
1707+
wp_data->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
1708+
}
17141709
}
17151710
} else {
17161711
wp_data->error_class = ERROR_CLASS_OBJECT;

0 commit comments

Comments
 (0)