/* no required minumum length or duplicate checking */ bool bacnet_name_write(uint16_t offset, BACNET_CHARACTER_STRING * char_string, BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code) { bool status = false; size_t length = 0; uint8_t encoding = 0; length = characterstring_length(char_string); if (length <= NVM_NAME_SIZE) { encoding = characterstring_encoding(char_string); if (encoding < MAX_CHARACTER_STRING_ENCODING) { status = bacnet_name_set(offset, char_string); if (!status) { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; } } else { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED; } } else { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY; } return status; }
bool Routed_Device_Write_Property_Local( BACNET_WRITE_PROPERTY_DATA * wp_data) { bool status = false; /* return value */ int len = 0; BACNET_APPLICATION_DATA_VALUE value; /* decode the some of the request */ len = bacapp_decode_application_data(wp_data->application_data, wp_data->application_data_len, &value); if (len < 0) { /* error while decoding - a value larger than we can handle */ wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; return false; } /* only array properties can have array options */ if ((wp_data->object_property != PROP_OBJECT_LIST) && (wp_data->array_index != BACNET_ARRAY_ALL)) { wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; return false; } /* FIXME: len < application_data_len: more data? */ switch (wp_data->object_property) { case PROP_OBJECT_IDENTIFIER: status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_OBJECT_ID, &wp_data->error_class, &wp_data->error_code); if (status) { if ((value.type.Object_Id.type == OBJECT_DEVICE) && (Routed_Device_Set_Object_Instance_Number(value.type. Object_Id.instance))) { /* FIXME: we could send an I-Am broadcast to let the world know */ } else { status = false; wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; } } break; case PROP_OBJECT_NAME: status = WPValidateString(&value, MAX_DEV_NAME_LEN, false, &wp_data->error_class, &wp_data->error_code); if (status) { Routed_Device_Set_Object_Name(characterstring_encoding(&value. type.Character_String), characterstring_value(&value.type.Character_String), characterstring_length(&value.type.Character_String)); } break; default: status = Device_Write_Property_Local(wp_data); break; } return status; }
bool bacnet_name_set(uint16_t offset, BACNET_CHARACTER_STRING * char_string) { uint8_t encoding = 0; uint8_t length = 0; char *str = NULL; length = characterstring_length(char_string); encoding = characterstring_encoding(char_string); str = characterstring_value(char_string); return bacnet_name_save(offset, encoding, str, length); }
bool WPValidateString( BACNET_APPLICATION_DATA_VALUE * pValue, int iMaxLen, bool bEmptyAllowed, BACNET_ERROR_CLASS * pErrorClass, BACNET_ERROR_CODE * pErrorCode) { bool bResult; /* Save on a bit of code duplication by pre selecting the most * common outcomes from the tests (not necessarily the most likely * outcome of the tests). */ bResult = false; *pErrorClass = ERROR_CLASS_PROPERTY; if (pValue->tag == BACNET_APPLICATION_TAG_CHARACTER_STRING) { if (characterstring_encoding(&pValue->type.Character_String) == CHARACTER_ANSI_X34) { if ((bEmptyAllowed == false) && (characterstring_length(&pValue->type.Character_String) == 0)) { *pErrorCode = ERROR_CODE_VALUE_OUT_OF_RANGE; } else if ((bEmptyAllowed == false) && (!characterstring_printable(&pValue->type.Character_String))) { /* assumption: non-empty also means must be "printable" */ *pErrorCode = ERROR_CODE_VALUE_OUT_OF_RANGE; } else if (characterstring_length(&pValue->type.Character_String) > (uint16_t) iMaxLen) { *pErrorClass = ERROR_CLASS_RESOURCES; *pErrorCode = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY; } else bResult = true; /* It's all good! */ } else *pErrorCode = ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED; } else *pErrorCode = ERROR_CODE_INVALID_DATA_TYPE; return (bResult); }
bool bacnet_name_write_unique(uint16_t offset, int object_type, uint32_t object_instance, BACNET_CHARACTER_STRING * char_string, BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code) { bool status = false; size_t length = 0; uint8_t encoding = 0; int duplicate_type = 0; uint32_t duplicate_instance = 0; length = characterstring_length(char_string); if (length < 1) { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; } else if (length <= NVM_NAME_SIZE) { encoding = characterstring_encoding(char_string); if (encoding < MAX_CHARACTER_STRING_ENCODING) { if (Device_Valid_Object_Name(char_string, &duplicate_type, &duplicate_instance)) { if ((duplicate_type == object_type) && (duplicate_instance == object_instance)) { /* writing same name to same object */ status = true; } else { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_DUPLICATE_NAME; } } else { status = bacnet_name_set(offset, char_string); if (status) { Device_Inc_Database_Revision(); } else { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; } } } else { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED; } } else { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY; } return status; }
static bool Multistate_Input_State_Text_Write( uint32_t object_instance, uint32_t state_index, BACNET_CHARACTER_STRING * char_string, BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code) { unsigned index = 0; /* offset from instance lookup */ size_t length = 0; uint8_t encoding = 0; bool status = false; /* return value */ index = Multistate_Input_Instance_To_Index(object_instance); if ((index < MAX_MULTISTATE_INPUTS) && (state_index > 0) && (state_index <= Multistate_Input_Max_States(object_instance))) { state_index--; length = characterstring_length(char_string); if (length <= sizeof(State_Text[index][state_index])) { encoding = characterstring_encoding(char_string); if (encoding == CHARACTER_UTF8) { status = characterstring_ansi_copy(State_Text[index][state_index], sizeof(State_Text[index][state_index]), char_string); if (!status) { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; } } else { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED; } } else { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY; } } else { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; } return status; }
bool Device_Write_Property_Local( BACNET_WRITE_PROPERTY_DATA * wp_data) { bool status = false; /* return value - false=error */ int len = 0; uint8_t encoding = 0; size_t length = 0; BACNET_APPLICATION_DATA_VALUE value; /* decode the some of the request */ len = bacapp_decode_application_data(wp_data->application_data, wp_data->application_data_len, &value); /* FIXME: len < application_data_len: more data? */ if (len < 0) { /* error while decoding - a value larger than we can handle */ wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; return false; } if ((wp_data->object_property != PROP_OBJECT_LIST) && (wp_data->array_index != BACNET_ARRAY_ALL)) { /* only array properties can have array options */ wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; return false; } switch ((int) wp_data->object_property) { case PROP_OBJECT_IDENTIFIER: if (value.tag == BACNET_APPLICATION_TAG_OBJECT_ID) { if ((value.type.Object_Id.type == OBJECT_DEVICE) && (Device_Set_Object_Instance_Number(value.type. Object_Id.instance))) { /* we could send an I-Am broadcast to let the world know */ status = true; } else { wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; } } else { wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE; } break; case PROP_MAX_INFO_FRAMES: if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) { if (value.type.Unsigned_Int <= 255) { dlmstp_set_max_info_frames(value.type.Unsigned_Int); status = true; } else { wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; } } else { wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE; } break; case PROP_MAX_MASTER: if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) { if ((value.type.Unsigned_Int > 0) && (value.type.Unsigned_Int <= 127)) { dlmstp_set_max_master(value.type.Unsigned_Int); status = true; } else { wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; } } else { wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE; } break; case PROP_OBJECT_NAME: if (value.tag == BACNET_APPLICATION_TAG_CHARACTER_STRING) { length = characterstring_length(&value.type.Character_String); if (length < 1) { wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; } else if (length < characterstring_capacity(&My_Object_Name)) { encoding = characterstring_encoding(&value.type.Character_String); if (encoding < MAX_CHARACTER_STRING_ENCODING) { /* All the object names in a device must be unique. */ if (Device_Valid_Object_Name(&value.type. Character_String, NULL, NULL)) { wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_code = ERROR_CODE_DUPLICATE_NAME; } else { Device_Set_Object_Name(&value.type. Character_String); status = true; } } else { wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_code = ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED; } } else { wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY; } } else { wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE; } break; case 9600: if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) { if (value.type.Unsigned_Int <= 115200) { RS485_Set_Baud_Rate(value.type.Unsigned_Int); status = true; } else { wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; } } else { wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE; } break; case PROP_NUMBER_OF_APDU_RETRIES: case PROP_APDU_TIMEOUT: case PROP_VENDOR_IDENTIFIER: case PROP_SYSTEM_STATUS: case PROP_LOCATION: case PROP_DESCRIPTION: case PROP_MODEL_NAME: case PROP_VENDOR_NAME: case PROP_FIRMWARE_REVISION: case PROP_APPLICATION_SOFTWARE_VERSION: case PROP_LOCAL_TIME: case PROP_UTC_OFFSET: case PROP_LOCAL_DATE: case PROP_DAYLIGHT_SAVINGS_STATUS: case PROP_PROTOCOL_VERSION: case PROP_PROTOCOL_REVISION: case PROP_PROTOCOL_SERVICES_SUPPORTED: case PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED: case PROP_OBJECT_LIST: case PROP_MAX_APDU_LENGTH_ACCEPTED: case PROP_SEGMENTATION_SUPPORTED: case PROP_DEVICE_ADDRESS_BINDING: case PROP_DATABASE_REVISION: case PROP_ACTIVE_COV_SUBSCRIPTIONS: wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED; break; default: wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_code = ERROR_CODE_UNKNOWN_PROPERTY; break; } /* not using len at this time */ len = len; return status; }
bool Device_Write_Property( BACNET_WRITE_PROPERTY_DATA * wp_data, BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code) { bool status = false; /* return value */ int len = 0; BACNET_APPLICATION_DATA_VALUE value; if (!Device_Valid_Object_Instance_Number(wp_data->object_instance)) { *error_class = ERROR_CLASS_OBJECT; *error_code = ERROR_CODE_UNKNOWN_OBJECT; return false; } /* decode the some of the request */ len = bacapp_decode_application_data(wp_data->application_data, wp_data->application_data_len, &value); /* FIXME: len < application_data_len: more data? */ /* FIXME: len == 0: unable to decode? */ switch (wp_data->object_property) { case PROP_OBJECT_IDENTIFIER: if (value.tag == BACNET_APPLICATION_TAG_OBJECT_ID) { if ((value.type.Object_Id.type == OBJECT_DEVICE) && (Device_Set_Object_Instance_Number(value.type. Object_Id.instance))) { /* we could send an I-Am broadcast to let the world know */ status = true; } else { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; } } else { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_INVALID_DATA_TYPE; } break; case PROP_MAX_INFO_FRAMES: if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) { if (value.type.Unsigned_Int <= 255) { dlmstp_set_max_info_frames(value.type.Unsigned_Int); status = true; } else { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; } } else { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_INVALID_DATA_TYPE; } break; case PROP_MAX_MASTER: if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) { if ((value.type.Unsigned_Int > 0) && (value.type.Unsigned_Int <= 127)) { dlmstp_set_max_master(value.type.Unsigned_Int); status = true; } else { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; } } else { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_INVALID_DATA_TYPE; } break; case PROP_OBJECT_NAME: if (value.tag == BACNET_APPLICATION_TAG_CHARACTER_STRING) { uint8_t encoding; size_t len; encoding = characterstring_encoding(&value.type.Character_String); len = characterstring_length(&value.type.Character_String); if (encoding == CHARACTER_ANSI_X34) { if (len <= 20) { /* FIXME: set the name */ /* Display_Set_Name( characterstring_value(&value.type.Character_String)); */ /* FIXME: All the object names in a device must be unique. Disallow setting the Device Object Name to any objects in the device. */ } else { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY; } } else { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED; } } else { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_INVALID_DATA_TYPE; } break; case 9600: if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) { if (value.type.Unsigned_Int > 115200) { RS485_Set_Baud_Rate(value.type.Unsigned_Int); status = true; } else { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; } } else { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_INVALID_DATA_TYPE; } break; default: *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_WRITE_ACCESS_DENIED; break; } return status; }
/* returns true if successful */ bool Device_Write_Property( BACNET_WRITE_PROPERTY_DATA * wp_data, BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code) { bool status = false; /* return value */ int len = 0; BACNET_APPLICATION_DATA_VALUE value; if (!Device_Valid_Object_Instance_Number(wp_data->object_instance)) { *error_class = ERROR_CLASS_OBJECT; *error_code = ERROR_CODE_UNKNOWN_OBJECT; return false; } /* decode the some of the request */ len = bacapp_decode_application_data(wp_data->application_data, wp_data->application_data_len, &value); /* FIXME: len < application_data_len: more data? */ /* FIXME: len == 0: unable to decode? */ switch (wp_data->object_property) { case PROP_OBJECT_IDENTIFIER: if (value.tag == BACNET_APPLICATION_TAG_OBJECT_ID) { if ((value.type.Object_Id.type == OBJECT_DEVICE) && (Device_Set_Object_Instance_Number(value.type. Object_Id.instance))) { /* FIXME: we could send an I-Am broadcast to let the world know */ status = true; } else { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; } } else { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_INVALID_DATA_TYPE; } break; case PROP_NUMBER_OF_APDU_RETRIES: if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) { /* FIXME: bounds check? */ apdu_retries_set((uint8_t) value.type.Unsigned_Int); status = true; } else { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_INVALID_DATA_TYPE; } break; case PROP_APDU_TIMEOUT: if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) { /* FIXME: bounds check? */ apdu_timeout_set((uint16_t) value.type.Unsigned_Int); status = true; } else { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_INVALID_DATA_TYPE; } break; case PROP_VENDOR_IDENTIFIER: if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) { /* FIXME: bounds check? */ Device_Set_Vendor_Identifier((uint16_t) value. type.Unsigned_Int); status = true; } else { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_INVALID_DATA_TYPE; } break; case PROP_SYSTEM_STATUS: if (value.tag == BACNET_APPLICATION_TAG_ENUMERATED) { /* FIXME: bounds check? */ Device_Set_System_Status((BACNET_DEVICE_STATUS) value. type.Enumerated); status = true; } else { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_INVALID_DATA_TYPE; } break; case PROP_OBJECT_NAME: if (value.tag == BACNET_APPLICATION_TAG_CHARACTER_STRING) { uint8_t encoding; encoding = characterstring_encoding(&value.type.Character_String); if (encoding == CHARACTER_ANSI_X34) { status = Device_Set_Object_Name(characterstring_value (&value.type.Character_String), characterstring_length(&value.type.Character_String)); if (!status) { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY; } } else { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED; } } else { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_INVALID_DATA_TYPE; } break; #if defined(BACDL_MSTP) case PROP_MAX_INFO_FRAMES: if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) { if (value.type.Unsigned_Int <= 255) { dlmstp_set_max_info_frames((uint8_t) value. type.Unsigned_Int); status = true; } else { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; } } else { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_INVALID_DATA_TYPE; } break; case PROP_MAX_MASTER: if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) { if ((value.type.Unsigned_Int > 0) && (value.type.Unsigned_Int <= 127)) { dlmstp_set_max_master((uint8_t) value.type.Unsigned_Int); status = true; } else { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; } } else { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_INVALID_DATA_TYPE; } break; #endif default: *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_WRITE_ACCESS_DENIED; break; } return status; }