Modified the character strings encoding to intialize character strings with NULLs at the end. Changed device object demo to use ANSI X34 only. Fixed bug in WriteProperty for Device Object Name.

This commit is contained in:
skarg
2006-01-05 18:40:11 +00:00
parent 105528e7b1
commit 137f36a977
5 changed files with 64 additions and 53 deletions
-18
View File
@@ -843,24 +843,6 @@ int decode_octet_string(uint8_t * apdu, uint32_t len_value,
return len;
}
// from clause 20.2.9 Encoding of a Character String Value
// returns the number of apdu bytes consumed
int encode_bacnet_string(uint8_t * apdu, const char *char_string, int len)
{
int i;
// limit - 6 octets is the most our tag and type could be
if (len > (MAX_APDU - 6))
len = MAX_APDU - 6;
for (i = 0; i < len; i++) {
apdu[1 + i] = char_string[i];
}
apdu[0] = CHARACTER_ANSI;
len++;
return len;
}
// from clause 20.2.9 Encoding of a Character String Value
// returns the number of apdu bytes consumed
int encode_bacnet_character_string(uint8_t * apdu,
+1 -1
View File
@@ -729,7 +729,7 @@ typedef enum
typedef enum
{
CHARACTER_ANSI = 0,
CHARACTER_ANSI_X34 = 0,
CHARACTER_MS_DBCS = 1,
CHARACTER_JISC_6226 = 2,
CHARACTER_UCS4 = 3,
+20 -12
View File
@@ -168,6 +168,7 @@ uint8_t bitstring_bits_capacity(BACNET_BIT_STRING *bit_string)
return 0;
}
#define CHARACTER_STRING_CAPACITY (MAX_CHARACTER_STRING_BYTES - 1)
/* returns false if the string exceeds capacity
initialize by using length=0 */
bool characterstring_init(
@@ -183,19 +184,26 @@ bool characterstring_init(
{
char_string->length = 0;
char_string->encoding = encoding;
if (length <= sizeof(char_string->value))
/* save a byte at the end for NULL -
note: assumes printable characters */
if (length <= CHARACTER_STRING_CAPACITY)
{
if (value)
{
for (i = 0; i < length; i++)
for (i = 0; i < MAX_CHARACTER_STRING_BYTES; i++)
{
char_string->value[char_string->length] = value[i];
char_string->length++;
if (i < length)
{
char_string->value[char_string->length] = value[i];
char_string->length++;
}
else
char_string->value[i] = 0;
}
}
else
{
for (i = 0; i < sizeof(char_string->value); i++)
for (i = 0; i < MAX_CHARACTER_STRING_BYTES; i++)
{
char_string->value[i] = 0;
}
@@ -208,12 +216,12 @@ bool characterstring_init(
}
bool characterstring_init_ansi(
BACNET_CHARACTER_STRING *char_string,
char *value)
BACNET_CHARACTER_STRING *char_string,
char *value)
{
return characterstring_init(
char_string,
CHARACTER_ANSI,
CHARACTER_ANSI_X34,
value, value?strlen(value):0);
}
@@ -228,7 +236,7 @@ bool characterstring_append(
if (char_string)
{
if ((length + char_string->length) <= sizeof(char_string->value))
if ((length + char_string->length) <= CHARACTER_STRING_CAPACITY)
{
for (i = 0; i < length; i++)
{
@@ -253,7 +261,7 @@ bool characterstring_truncate(
if (char_string)
{
if (length <= sizeof(char_string->value))
if (length <= CHARACTER_STRING_CAPACITY)
{
char_string->length = length;
status = true;
@@ -296,7 +304,7 @@ size_t characterstring_capacity(BACNET_CHARACTER_STRING *char_string)
if (char_string)
{
length = sizeof(char_string->value);
length = CHARACTER_STRING_CAPACITY;
}
return length;
@@ -318,7 +326,7 @@ uint8_t characterstring_encoding(BACNET_CHARACTER_STRING *char_string)
/* returns false if the string exceeds capacity
initialize by using length=0 */
bool octetstring_init(
BACNET_OCTET_STRING *octet_string,
BACNET_OCTET_STRING *octet_string,
uint8_t *value,
size_t length)
{
+2 -1
View File
@@ -48,12 +48,13 @@ typedef struct BACnet_Bit_String
uint8_t value[MAX_BITSTRING_BYTES];
} BACNET_BIT_STRING;
#define MAX_CHARACTER_STRING_BYTES (MAX_APDU-6)
typedef struct BACnet_Character_String
{
size_t length;
uint8_t encoding;
/* limit - 6 octets is the most our tag and type could be */
char value[MAX_APDU-6];
char value[MAX_CHARACTER_STRING_BYTES];
} BACNET_CHARACTER_STRING;
/* FIXME: convert the bacdcode library to use BACNET_OCTET_STRING
+41 -21
View File
@@ -38,8 +38,6 @@
#endif
static uint32_t Object_Instance_Number = 0;
// FIXME: it is likely that this name is configurable,
// so consider a fixed sized string
static char Object_Name[16] = "SimpleServer";
static BACNET_DEVICE_STATUS System_Status = STATUS_OPERATIONAL;
static char Vendor_Name[16] = "ASHRAE";
@@ -108,6 +106,25 @@ bool Device_Valid_Object_Instance_Number(uint32_t object_id)
(object_id == BACNET_MAX_INSTANCE));
}
const char *Device_Object_Name(void)
{
return Object_Name;
}
bool Device_Set_Object_Name(const char *name, size_t length)
{
bool status = false; /*return value*/
if (length < sizeof(Object_Name))
{
memmove(Object_Name,name,length);
Object_Name[length] = 0;
status = true;
}
return status;
}
BACNET_DEVICE_STATUS Device_System_Status(void)
{
return System_Status;
@@ -385,43 +402,36 @@ int Device_Encode_Property_APDU(
Object_Instance_Number);
break;
case PROP_OBJECT_NAME:
characterstring_init(&char_string,CHARACTER_ANSI,
Object_Name,strlen(Object_Name));
characterstring_init_ansi(&char_string, Object_Name);
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
break;
case PROP_OBJECT_TYPE:
apdu_len = encode_tagged_enumerated(&apdu[0], OBJECT_DEVICE);
break;
case PROP_DESCRIPTION:
characterstring_init(&char_string,CHARACTER_ANSI,
Description,strlen(Description));
characterstring_init_ansi(&char_string, Description);
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
break;
case PROP_SYSTEM_STATUS:
apdu_len = encode_tagged_enumerated(&apdu[0], System_Status);
break;
case PROP_VENDOR_NAME:
characterstring_init(&char_string,CHARACTER_ANSI,
Vendor_Name,strlen(Vendor_Name));
characterstring_init_ansi(&char_string, Vendor_Name);
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
break;
case PROP_VENDOR_IDENTIFIER:
apdu_len = encode_tagged_unsigned(&apdu[0], Vendor_Identifier);
break;
case PROP_MODEL_NAME:
characterstring_init(&char_string,CHARACTER_ANSI,
Model_Name,strlen(Model_Name));
characterstring_init_ansi(&char_string, Model_Name);
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
break;
case PROP_FIRMWARE_REVISION:
characterstring_init(&char_string,CHARACTER_ANSI,
Firmware_Revision,strlen(Firmware_Revision));
characterstring_init_ansi(&char_string, Firmware_Revision);
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
break;
case PROP_APPLICATION_SOFTWARE_VERSION:
characterstring_init(&char_string,CHARACTER_ANSI,
Application_Software_Version,
strlen(Application_Software_Version));
characterstring_init_ansi(&char_string, Application_Software_Version);
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
break;
// if you support time
@@ -460,7 +470,7 @@ int Device_Encode_Property_APDU(
// initialize all the services to not-supported
bitstring_set_bit(&bit_string, (uint8_t)i, false);
}
/* FIXME: set the services that YOUR device executes */
/* FIXME: set only the services that YOUR device executes */
bitstring_set_bit(&bit_string, SERVICE_SUPPORTED_WHO_IS, true);
bitstring_set_bit(&bit_string, SERVICE_SUPPORTED_I_AM, true);
bitstring_set_bit(&bit_string, SERVICE_SUPPORTED_READ_PROPERTY, true);
@@ -650,13 +660,23 @@ bool Device_Write_Property(
case PROP_OBJECT_NAME:
if (wp_data->value.tag == BACNET_APPLICATION_TAG_CHARACTER_STRING)
{
status = Device_Set_Vendor_Name(
characterstring_value(&wp_data->value.type.Character_String),
characterstring_length(&wp_data->value.type.Character_String));
if (!status)
uint8_t encoding;
encoding = characterstring_encoding(&wp_data->value.type.Character_String);
if (encoding == CHARACTER_ANSI_X34)
{
status = Device_Set_Object_Name(
characterstring_value(&wp_data->value.type.Character_String),
characterstring_length(&wp_data->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_NO_SPACE_TO_WRITE_PROPERTY;
*error_code = ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED;
}
}
else