Changed WhoHas and I-Have to use CharacterString instead of forcing ANSI X34 and C Strings. Affected all demos and ports object name, so I changed the object name function name to make sure it was noticed.

This commit is contained in:
skarg
2011-03-24 16:53:02 +00:00
parent 75d88abf77
commit deab12a5e1
74 changed files with 1566 additions and 850 deletions
+106
View File
@@ -484,12 +484,118 @@ bool characterstring_printable(
break;
}
}
} else {
status = true;
}
}
return status;
}
/* Basic UTF-8 manipulation routines
by Jeff Bezanson
placed in the public domain Fall 2005 */
static const char trailingBytesForUTF8[256] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
};
/* based on the valid_utf8 routine from the PCRE library by Philip Hazel
length is in bytes, since without knowing whether the string is valid
it's hard to know how many characters there are! */
static int utf8_isvalid(const char *str, int length)
{
const unsigned char *p, *pend = (unsigned char*)str + length;
unsigned char c;
int ab;
for (p = (unsigned char*)str; p < pend; p++) {
c = *p;
/* null in middle of string */
if (c == 0) {
return 0;
}
/* ASCII character */
if (c < 128) {
continue;
}
if ((c & 0xc0) != 0xc0) {
return 0;
}
ab = trailingBytesForUTF8[c];
if (length < ab) {
return 0;
}
length -= ab;
p++;
/* Check top bits in the second byte */
if ((*p & 0xc0) != 0x80) {
return 0;
}
/* Check for overlong sequences for each different length */
switch (ab) {
/* Check for xx00 000x */
case 1:
if ((c & 0x3e) == 0) return 0;
continue; /* We know there aren't any more bytes to check */
/* Check for 1110 0000, xx0x xxxx */
case 2:
if (c == 0xe0 && (*p & 0x20) == 0) return 0;
break;
/* Check for 1111 0000, xx00 xxxx */
case 3:
if (c == 0xf0 && (*p & 0x30) == 0) return 0;
break;
/* Check for 1111 1000, xx00 0xxx */
case 4:
if (c == 0xf8 && (*p & 0x38) == 0) return 0;
break;
/* Check for leading 0xfe or 0xff,
and then for 1111 1100, xx00 00xx */
case 5:
if (c == 0xfe || c == 0xff ||
(c == 0xfc && (*p & 0x3c) == 0)) return 0;
break;
}
/* Check for valid bytes after the 2nd, if any; all must start 10 */
while (--ab > 0) {
if ((*(++p) & 0xc0) != 0x80) return 0;
}
}
return 1;
}
bool characterstring_valid(
BACNET_CHARACTER_STRING * char_string)
{
bool valid = false; /* return value */
if (char_string->encoding < MAX_CHARACTER_STRING_ENCODING) {
if (char_string->encoding == CHARACTER_UTF8) {
if (utf8_isvalid(char_string->value, char_string->length)) {
valid = true;
}
} else {
valid = true;
}
}
return valid;
}
/* returns false if the string exceeds capacity
initialize by using value=NULL */
bool octetstring_init(
+8 -8
View File
@@ -63,7 +63,7 @@ int whohas_encode_apdu(
encode_context_unsigned(&apdu[apdu_len], 1, data->high_limit);
apdu_len += len;
}
if (data->object_name) {
if (data->is_object_name) {
len =
encode_context_character_string(&apdu[apdu_len], 3,
&data->object.name);
@@ -115,7 +115,7 @@ int whohas_decode_service_request(
}
/* object id */
if (decode_is_context_tag(&apdu[len], 2)) {
data->object_name = false;
data->is_object_name = false;
len +=
decode_tag_number_and_value(&apdu[len], &tag_number,
&len_value);
@@ -126,7 +126,7 @@ int whohas_decode_service_request(
}
/* object name */
else if (decode_is_context_tag(&apdu[len], 3)) {
data->object_name = true;
data->is_object_name = true;
len +=
decode_tag_number_and_value(&apdu[len], &tag_number,
&len_value);
@@ -186,9 +186,9 @@ void testWhoHasData(
ct_test(pTest, len != -1);
ct_test(pTest, test_data.low_limit == data->low_limit);
ct_test(pTest, test_data.high_limit == data->high_limit);
ct_test(pTest, test_data.object_name == data->object_name);
ct_test(pTest, test_data.is_object_name == data->is_object_name);
/* Object ID */
if (data->object_name == false) {
if (data->is_object_name == false) {
ct_test(pTest,
test_data.object.identifier.type == data->object.identifier.type);
ct_test(pTest,
@@ -209,7 +209,7 @@ void testWhoHas(
data.low_limit = -1;
data.high_limit = -1;
data.object_name = false;
data.is_object_name = false;
data.object.identifier.type = OBJECT_ANALOG_INPUT;
data.object.identifier.instance = 1;
testWhoHasData(pTest, &data);
@@ -218,7 +218,7 @@ void testWhoHas(
data.low_limit += (BACNET_MAX_INSTANCE / 4)) {
for (data.high_limit = 0; data.high_limit <= BACNET_MAX_INSTANCE;
data.high_limit += (BACNET_MAX_INSTANCE / 4)) {
data.object_name = false;
data.is_object_name = false;
for (data.object.identifier.type = OBJECT_ANALOG_INPUT;
data.object.identifier.type < MAX_BACNET_OBJECT_TYPE;
data.object.identifier.type++) {
@@ -228,7 +228,7 @@ void testWhoHas(
testWhoHasData(pTest, &data);
}
}
data.object_name = true;
data.is_object_name = true;
characterstring_init_ansi(&data.object.name, "patricia");
testWhoHasData(pTest, &data);
}