changed the modules to use the new BACNet string types.

Modified the device object to handle having the string properties changed via WriteProperty service.
Updated the unit tests.
Updated the demo objects.
This commit is contained in:
skarg
2005-12-23 17:39:36 +00:00
parent 89859a867c
commit 1cc71f8d14
35 changed files with 580 additions and 389 deletions
+1
View File
@@ -7,6 +7,7 @@ BASEDIR = .
CFLAGS = -Wall -I. -Itest -DTEST -DTEST_ABORT -g CFLAGS = -Wall -I. -Itest -DTEST -DTEST_ABORT -g
SRCS = bacdcode.c \ SRCS = bacdcode.c \
bacstr.c \
bigend.c \ bigend.c \
abort.c \ abort.c \
test/ctest.c test/ctest.c
+4 -1
View File
@@ -71,6 +71,7 @@ int Analog_Input_Encode_Property_APDU(
{ {
int apdu_len = 0; // return value int apdu_len = 0; // return value
BACNET_BIT_STRING bit_string; BACNET_BIT_STRING bit_string;
BACNET_CHARACTER_STRING char_string;
char text_string[32] = {""}; char text_string[32] = {""};
float value = 3.14; float value = 3.14;
@@ -84,7 +85,9 @@ int Analog_Input_Encode_Property_APDU(
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
case PROP_DESCRIPTION: case PROP_DESCRIPTION:
sprintf(text_string,"ANALOG INPUT %u",object_instance); sprintf(text_string,"ANALOG INPUT %u",object_instance);
apdu_len = encode_tagged_character_string(&apdu[0], text_string); characterstring_init_ansi(&char_string, text_string);
apdu_len = encode_tagged_character_string(&apdu[0],
&char_string);
break; break;
case PROP_OBJECT_TYPE: case PROP_OBJECT_TYPE:
apdu_len = encode_tagged_enumerated(&apdu[0], OBJECT_ANALOG_INPUT); apdu_len = encode_tagged_enumerated(&apdu[0], OBJECT_ANALOG_INPUT);
+1
View File
@@ -7,6 +7,7 @@ BASEDIR = .
CFLAGS = -Wall -I. -Itest -DTEST -DTEST_ANALOG_INPUT -g CFLAGS = -Wall -I. -Itest -DTEST -DTEST_ANALOG_INPUT -g
SRCS = bacdcode.c \ SRCS = bacdcode.c \
bacstr.c \
bigend.c \ bigend.c \
ai.c \ ai.c \
test/ctest.c test/ctest.c
+4 -1
View File
@@ -152,6 +152,7 @@ int Analog_Output_Encode_Property_APDU(
int len = 0; int len = 0;
int apdu_len = 0; // return value int apdu_len = 0; // return value
BACNET_BIT_STRING bit_string; BACNET_BIT_STRING bit_string;
BACNET_CHARACTER_STRING char_string;
char text_string[32] = {""}; char text_string[32] = {""};
float real_value = 1.414; float real_value = 1.414;
unsigned object_index = 0; unsigned object_index = 0;
@@ -168,7 +169,9 @@ int Analog_Output_Encode_Property_APDU(
case PROP_DESCRIPTION: case PROP_DESCRIPTION:
// note: the object name must be unique within this device // note: the object name must be unique within this device
sprintf(text_string,"ANALOG OUTPUT %u",object_instance); sprintf(text_string,"ANALOG OUTPUT %u",object_instance);
apdu_len = encode_tagged_character_string(&apdu[0], text_string); characterstring_init_ansi(&char_string, text_string);
apdu_len = encode_tagged_character_string(&apdu[0],
&char_string);
break; break;
case PROP_OBJECT_TYPE: case PROP_OBJECT_TYPE:
apdu_len = encode_tagged_enumerated(&apdu[0], OBJECT_ANALOG_OUTPUT); apdu_len = encode_tagged_enumerated(&apdu[0], OBJECT_ANALOG_OUTPUT);
+1
View File
@@ -7,6 +7,7 @@ BASEDIR = .
CFLAGS = -Wall -I. -Itest -DTEST -DTEST_ANALOG_OUTPUT -g CFLAGS = -Wall -I. -Itest -DTEST -DTEST_ANALOG_OUTPUT -g
SRCS = bacdcode.c \ SRCS = bacdcode.c \
bacstr.c \
bigend.c \ bigend.c \
ao.c \ ao.c \
test/ctest.c test/ctest.c
+16 -21
View File
@@ -220,7 +220,7 @@ int arf_ack_encode_apdu(
apdu_len += encode_tagged_signed(&apdu[apdu_len], apdu_len += encode_tagged_signed(&apdu[apdu_len],
data->type.stream.fileStartPosition); data->type.stream.fileStartPosition);
apdu_len += encode_tagged_octet_string(&apdu[apdu_len], apdu_len += encode_tagged_octet_string(&apdu[apdu_len],
data->fileData, data->fileDataLength); &data->fileData);
apdu_len += encode_closing_tag(&apdu[apdu_len], 0); apdu_len += encode_closing_tag(&apdu[apdu_len], 0);
break; break;
case FILE_RECORD_ACCESS: case FILE_RECORD_ACCESS:
@@ -230,7 +230,7 @@ int arf_ack_encode_apdu(
apdu_len += encode_tagged_unsigned(&apdu[apdu_len], apdu_len += encode_tagged_unsigned(&apdu[apdu_len],
data->type.record.RecordCount); data->type.record.RecordCount);
apdu_len += encode_tagged_octet_string(&apdu[apdu_len], apdu_len += encode_tagged_octet_string(&apdu[apdu_len],
data->fileData, data->fileDataLength); &data->fileData);
apdu_len += encode_closing_tag(&apdu[apdu_len], 1); apdu_len += encode_closing_tag(&apdu[apdu_len], 1);
break; break;
default: default:
@@ -281,9 +281,7 @@ int arf_ack_decode_service_request(
return -1; return -1;
len += decode_octet_string(&apdu[len], len += decode_octet_string(&apdu[len],
len_value_type, len_value_type,
data->fileData, &data->fileData);
data->fileDataLength);
data->fileDataLength = len_value_type;
if (!decode_is_closing_tag_number(&apdu[len], 0)) if (!decode_is_closing_tag_number(&apdu[len], 0))
return -1; return -1;
// a tag number is not extended so only one octet // a tag number is not extended so only one octet
@@ -320,9 +318,7 @@ int arf_ack_decode_service_request(
return -1; return -1;
len += decode_octet_string(&apdu[len], len += decode_octet_string(&apdu[len],
len_value_type, len_value_type,
data->fileData, &data->fileData);
data->fileDataLength);
data->fileDataLength = len_value_type;
if (!decode_is_closing_tag_number(&apdu[len], 1)) if (!decode_is_closing_tag_number(&apdu[len], 1))
return -1; return -1;
// a tag number is not extended so only one octet // a tag number is not extended so only one octet
@@ -380,7 +376,6 @@ void testAtomicReadFileAckAccess(Test * pTest,
int apdu_len = 0; int apdu_len = 0;
uint8_t invoke_id = 128; uint8_t invoke_id = 128;
uint8_t test_invoke_id = 0; uint8_t test_invoke_id = 0;
uint8_t test_octet_string[128] = "bingo!";
len = arf_ack_encode_apdu( len = arf_ack_encode_apdu(
&apdu[0], &apdu[0],
@@ -389,8 +384,6 @@ void testAtomicReadFileAckAccess(Test * pTest,
ct_test(pTest, len != 0); ct_test(pTest, len != 0);
apdu_len = len; apdu_len = len;
test_data.fileData = test_octet_string;
test_data.fileDataLength = sizeof(test_octet_string);
len = arf_ack_decode_apdu( len = arf_ack_decode_apdu(
&apdu[0], &apdu[0],
apdu_len, apdu_len,
@@ -411,33 +404,35 @@ void testAtomicReadFileAckAccess(Test * pTest,
ct_test(pTest, test_data.type.record.RecordCount == ct_test(pTest, test_data.type.record.RecordCount ==
data->type.record.RecordCount); data->type.record.RecordCount);
} }
ct_test(pTest, test_data.fileDataLength == ct_test(pTest, octetstring_length(&test_data.fileData) ==
data->fileDataLength); octetstring_length(&data->fileData));
ct_test(pTest, memcmp( ct_test(pTest, memcmp(
&test_data.fileData[0], octetstring_value(&test_data.fileData),
&data->fileData[0], octetstring_value(&data->fileData),
test_data.fileDataLength) == 0); octetstring_length(&test_data.fileData)) == 0);
} }
void testAtomicReadFileAck(Test * pTest) void testAtomicReadFileAck(Test * pTest)
{ {
BACNET_ATOMIC_READ_FILE_DATA data = {0}; BACNET_ATOMIC_READ_FILE_DATA data = {0};
uint8_t *test_octet_string = "Joshua-Mary-Anna-Christopher"; uint8_t test_octet_string[32] = "Joshua-Mary-Anna-Christopher";
data.endOfFile = true; data.endOfFile = true;
data.access = FILE_STREAM_ACCESS; data.access = FILE_STREAM_ACCESS;
data.type.stream.fileStartPosition = 0; data.type.stream.fileStartPosition = 0;
data.fileData = test_octet_string; octetstring_init(&data.fileData,
data.fileDataLength = strlen(test_octet_string); test_octet_string,
sizeof(test_octet_string));
testAtomicReadFileAckAccess(pTest, &data); testAtomicReadFileAckAccess(pTest, &data);
data.endOfFile = false; data.endOfFile = false;
data.access = FILE_RECORD_ACCESS; data.access = FILE_RECORD_ACCESS;
data.type.record.fileStartRecord = 1; data.type.record.fileStartRecord = 1;
data.type.record.RecordCount = 2; data.type.record.RecordCount = 2;
data.fileData = test_octet_string; octetstring_init(&data.fileData,
data.fileDataLength = strlen(test_octet_string); test_octet_string,
sizeof(test_octet_string));
testAtomicReadFileAckAccess(pTest, &data); testAtomicReadFileAckAccess(pTest, &data);
return; return;
+2 -4
View File
@@ -37,6 +37,7 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include "bacdcode.h" #include "bacdcode.h"
#include "bacstr.h"
typedef struct BACnet_Atomic_Read_File_Data typedef struct BACnet_Atomic_Read_File_Data
{ {
@@ -57,10 +58,7 @@ typedef struct BACnet_Atomic_Read_File_Data
unsigned RecordCount; unsigned RecordCount;
} record; } record;
} type; } type;
// These are used for the ACK portion BACNET_OCTET_STRING fileData;
// Set them to an unused buffer for the decode to fill
uint8_t *fileData;
unsigned fileDataLength;
bool endOfFile; bool endOfFile;
} BACNET_ATOMIC_READ_FILE_DATA; } BACNET_ATOMIC_READ_FILE_DATA;
+1
View File
@@ -7,6 +7,7 @@ BASEDIR = .
CFLAGS = -Wall -I. -Itest -DTEST -DTEST_ATOMIC_READ_FILE -DBACDL_BIP=1 -g CFLAGS = -Wall -I. -Itest -DTEST -DTEST_ATOMIC_READ_FILE -DBACDL_BIP=1 -g
SRCS = bacdcode.c \ SRCS = bacdcode.c \
bacstr.c \
bigend.c \ bigend.c \
arf.c \ arf.c \
test/ctest.c test/ctest.c
+17 -22
View File
@@ -64,7 +64,7 @@ int awf_encode_apdu(
apdu_len += encode_tagged_signed(&apdu[apdu_len], apdu_len += encode_tagged_signed(&apdu[apdu_len],
data->type.stream.fileStartPosition); data->type.stream.fileStartPosition);
apdu_len += encode_tagged_octet_string(&apdu[apdu_len], apdu_len += encode_tagged_octet_string(&apdu[apdu_len],
data->fileData, data->fileDataLength); &data->fileData);
apdu_len += encode_closing_tag(&apdu[apdu_len], 0); apdu_len += encode_closing_tag(&apdu[apdu_len], 0);
break; break;
case FILE_RECORD_ACCESS: case FILE_RECORD_ACCESS:
@@ -74,7 +74,7 @@ int awf_encode_apdu(
apdu_len += encode_tagged_unsigned(&apdu[apdu_len], apdu_len += encode_tagged_unsigned(&apdu[apdu_len],
data->type.record.returnedRecordCount); data->type.record.returnedRecordCount);
apdu_len += encode_tagged_octet_string(&apdu[apdu_len], apdu_len += encode_tagged_octet_string(&apdu[apdu_len],
data->fileData, data->fileDataLength); &data->fileData);
apdu_len += encode_closing_tag(&apdu[apdu_len], 1); apdu_len += encode_closing_tag(&apdu[apdu_len], 1);
break; break;
default: default:
@@ -127,9 +127,7 @@ int awf_decode_service_request(
return -1; return -1;
len += decode_octet_string(&apdu[len], len += decode_octet_string(&apdu[len],
len_value_type, len_value_type,
data->fileData, &data->fileData);
data->fileDataLength);
data->fileDataLength = len_value_type;
if (!decode_is_closing_tag_number(&apdu[len], 0)) if (!decode_is_closing_tag_number(&apdu[len], 0))
return -1; return -1;
// a tag number is not extended so only one octet // a tag number is not extended so only one octet
@@ -166,9 +164,7 @@ int awf_decode_service_request(
return -1; return -1;
len += decode_octet_string(&apdu[len], len += decode_octet_string(&apdu[len],
len_value_type, len_value_type,
data->fileData, &data->fileData);
data->fileDataLength);
data->fileDataLength = len_value_type;
if (!decode_is_closing_tag_number(&apdu[len], 1)) if (!decode_is_closing_tag_number(&apdu[len], 1))
return -1; return -1;
// a tag number is not extended so only one octet // a tag number is not extended so only one octet
@@ -322,7 +318,6 @@ void testAtomicWriteFileAccess(Test * pTest,
int apdu_len = 0; int apdu_len = 0;
uint8_t invoke_id = 128; uint8_t invoke_id = 128;
uint8_t test_invoke_id = 0; uint8_t test_invoke_id = 0;
uint8_t test_octet_string[128] = "bingo!";
len = awf_encode_apdu( len = awf_encode_apdu(
&apdu[0], &apdu[0],
@@ -331,8 +326,6 @@ void testAtomicWriteFileAccess(Test * pTest,
ct_test(pTest, len != 0); ct_test(pTest, len != 0);
apdu_len = len; apdu_len = len;
test_data.fileData = test_octet_string;
test_data.fileDataLength = sizeof(test_octet_string);
len = awf_decode_apdu( len = awf_decode_apdu(
&apdu[0], &apdu[0],
apdu_len, apdu_len,
@@ -354,25 +347,26 @@ void testAtomicWriteFileAccess(Test * pTest,
ct_test(pTest, test_data.type.record.returnedRecordCount == ct_test(pTest, test_data.type.record.returnedRecordCount ==
data->type.record.returnedRecordCount); data->type.record.returnedRecordCount);
} }
ct_test(pTest, test_data.fileDataLength == ct_test(pTest, octetstring_length(&test_data.fileData) ==
data->fileDataLength); octetstring_length(&data->fileData));
ct_test(pTest, memcmp( ct_test(pTest, memcmp(
&test_data.fileData[0], octetstring_value(&test_data.fileData),
&data->fileData[0], octetstring_value(&data->fileData),
test_data.fileDataLength) == 0); octetstring_length(&test_data.fileData)) == 0);
} }
void testAtomicWriteFile(Test * pTest) void testAtomicWriteFile(Test * pTest)
{ {
BACNET_ATOMIC_WRITE_FILE_DATA data = {0}; BACNET_ATOMIC_WRITE_FILE_DATA data = {0};
uint8_t *test_octet_string = "Joshua-Mary-Anna-Christopher"; uint8_t test_octet_string[32] = "Joshua-Mary-Anna-Christopher";
data.object_type = OBJECT_FILE; data.object_type = OBJECT_FILE;
data.object_instance = 1; data.object_instance = 1;
data.access = FILE_STREAM_ACCESS; data.access = FILE_STREAM_ACCESS;
data.type.stream.fileStartPosition = 0; data.type.stream.fileStartPosition = 0;
data.fileData = test_octet_string; octetstring_init(&data.fileData,
data.fileDataLength = strlen(test_octet_string); test_octet_string,
sizeof(test_octet_string));
testAtomicWriteFileAccess(pTest, &data); testAtomicWriteFileAccess(pTest, &data);
data.object_type = OBJECT_FILE; data.object_type = OBJECT_FILE;
@@ -380,8 +374,9 @@ void testAtomicWriteFile(Test * pTest)
data.access = FILE_RECORD_ACCESS; data.access = FILE_RECORD_ACCESS;
data.type.record.fileStartRecord = 1; data.type.record.fileStartRecord = 1;
data.type.record.returnedRecordCount = 2; data.type.record.returnedRecordCount = 2;
data.fileData = test_octet_string; octetstring_init(&data.fileData,
data.fileDataLength = strlen(test_octet_string); test_octet_string,
sizeof(test_octet_string));
testAtomicWriteFileAccess(pTest, &data); testAtomicWriteFileAccess(pTest, &data);
return; return;
+1 -5
View File
@@ -55,11 +55,7 @@ typedef struct BACnet_Atomic_Write_File_Data
unsigned returnedRecordCount; unsigned returnedRecordCount;
} record; } record;
} type; } type;
// note: set the file data to an empty buffer BACNET_OCTET_STRING fileData;
// and set the DataLength to the size of the empty buffer
// before decoding the data.
uint8_t *fileData;
unsigned fileDataLength;
} BACNET_ATOMIC_WRITE_FILE_DATA; } BACNET_ATOMIC_WRITE_FILE_DATA;
#ifdef __cplusplus #ifdef __cplusplus
+1
View File
@@ -7,6 +7,7 @@ BASEDIR = .
CFLAGS = -Wall -I. -Itest -DTEST -DTEST_ATOMIC_WRITE_FILE -DBACDL_BIP=1 -g CFLAGS = -Wall -I. -Itest -DTEST -DTEST_ATOMIC_WRITE_FILE -DBACDL_BIP=1 -g
SRCS = bacdcode.c \ SRCS = bacdcode.c \
bacstr.c \
bigend.c \ bigend.c \
awf.c \ awf.c \
test/ctest.c test/ctest.c
+1
View File
@@ -7,6 +7,7 @@ BASEDIR = .
CFLAGS = -Wall -I. -Itest -DTEST -DTEST_BACNET_APPLICATION_DATA -g CFLAGS = -Wall -I. -Itest -DTEST -DTEST_BACNET_APPLICATION_DATA -g
SRCS = bacdcode.c \ SRCS = bacdcode.c \
bacstr.c \
bacapp.c \ bacapp.c \
bigend.c \ bigend.c \
test/ctest.c test/ctest.c
+102 -88
View File
@@ -807,16 +807,16 @@ int encode_tagged_object_id(
// from clause 20.2.8 Encoding of an Octet String Value // from clause 20.2.8 Encoding of an Octet String Value
// returns the number of apdu bytes consumed // returns the number of apdu bytes consumed
int encode_octet_string(uint8_t * apdu, const uint8_t *octet_string, int encode_octet_string(uint8_t * apdu, BACNET_OCTET_STRING *octet_string)
unsigned len)
{ {
unsigned i; int len = 0; /* return value */
// limit - 6 octets is the most our tag and type could be if (octet_string)
if (len > (MAX_APDU - 6)) {
len = MAX_APDU - 6; /* FIXME: might need to pass in the length of the APDU
for (i = 0; i < len; i++) { to bounds check since it might not be the only data chunk */
apdu[i] = octet_string[i]; len = octetstring_length(octet_string);
memmove(&apdu[0], octetstring_value(octet_string), len);
} }
return len; return len;
@@ -825,17 +825,22 @@ int encode_octet_string(uint8_t * apdu, const uint8_t *octet_string,
// from clause 20.2.8 Encoding of an Octet String Value // from clause 20.2.8 Encoding of an Octet String Value
// and 20.2.1 General Rules for Encoding BACnet Tags // and 20.2.1 General Rules for Encoding BACnet Tags
// returns the number of apdu bytes consumed // returns the number of apdu bytes consumed
int encode_tagged_octet_string(uint8_t * apdu, const uint8_t *octet_string, int encode_tagged_octet_string(uint8_t * apdu,
unsigned len) BACNET_OCTET_STRING *octet_string)
{ {
int apdu_len; int apdu_len = 0;
apdu_len = encode_tag(&apdu[0], BACNET_APPLICATION_TAG_OCTET_STRING, if (octet_string)
false, len); {
if ((apdu_len + len) < MAX_APDU) apdu_len = encode_tag(&apdu[0], BACNET_APPLICATION_TAG_OCTET_STRING,
apdu_len += encode_octet_string(&apdu[apdu_len], octet_string, len); false, octetstring_length(octet_string));
else /* FIXME: probably need to pass in the length of the APDU
apdu_len = 0; to bounds check since it might not be the only data chunk */
if ((apdu_len + octetstring_length(octet_string)) < MAX_APDU)
apdu_len += encode_octet_string(&apdu[apdu_len], octet_string);
else
apdu_len = 0;
}
return apdu_len; return apdu_len;
} }
@@ -844,21 +849,14 @@ int encode_tagged_octet_string(uint8_t * apdu, const uint8_t *octet_string,
// and 20.2.1 General Rules for Encoding BACnet Tags // and 20.2.1 General Rules for Encoding BACnet Tags
// returns the number of apdu bytes consumed // returns the number of apdu bytes consumed
int decode_octet_string(uint8_t * apdu, uint32_t len_value, int decode_octet_string(uint8_t * apdu, uint32_t len_value,
uint8_t *buffer, size_t buffer_len) BACNET_OCTET_STRING *octet_string)
{ {
int len = 0; // return value int len = 0; // return value
uint32_t i = 0; // counter bool status = false;
// FIXME: issue warning? status = octetstring_init(octet_string,&apdu[0],len_value);
if (len_value > buffer_len) if (status)
len_value = buffer_len; len = len_value;
if (len_value) {
for (i = 0; i < len_value; i++) {
buffer[i] = apdu[i];
}
len += len_value;
}
return len; return len;
} }
@@ -883,27 +881,28 @@ int encode_bacnet_string(uint8_t * apdu, const char *char_string, int len)
// from clause 20.2.9 Encoding of a Character String Value // from clause 20.2.9 Encoding of a Character String Value
// returns the number of apdu bytes consumed // returns the number of apdu bytes consumed
int encode_bacnet_character_string(uint8_t * apdu, const char *char_string) int encode_bacnet_character_string(uint8_t * apdu,
BACNET_CHARACTER_STRING *char_string)
{ {
int len; int len;
len = strlen(char_string); len = characterstring_length(char_string);
len = encode_bacnet_string(&apdu[0], char_string, len); apdu[0] = characterstring_encoding(char_string);
memmove(apdu, characterstring_value(char_string), len);
return len; return len + 1 /* for encoding */;
} }
// from clause 20.2.9 Encoding of a Character String Value // from clause 20.2.9 Encoding of a Character String Value
// and 20.2.1 General Rules for Encoding BACnet Tags // and 20.2.1 General Rules for Encoding BACnet Tags
// returns the number of apdu bytes consumed // returns the number of apdu bytes consumed
int encode_tagged_character_string(uint8_t * apdu, const char *char_string) int encode_tagged_character_string(uint8_t * apdu,
BACNET_CHARACTER_STRING *char_string)
{ {
int len = 0; int len = 0;
int string_len = 0; int string_len = 0;
// find the size of the apdu first - not necessarily effecient string_len = characterstring_length(char_string) + 1 /* for encoding */;
// but reuses existing functions
string_len = encode_bacnet_character_string(&apdu[1], char_string);
len = encode_tag(&apdu[0], BACNET_APPLICATION_TAG_CHARACTER_STRING, len = encode_tag(&apdu[0], BACNET_APPLICATION_TAG_CHARACTER_STRING,
false, string_len); false, string_len);
if ((len + string_len) < MAX_APDU) if ((len + string_len) < MAX_APDU)
@@ -918,28 +917,15 @@ int encode_tagged_character_string(uint8_t * apdu, const char *char_string)
// and 20.2.1 General Rules for Encoding BACnet Tags // and 20.2.1 General Rules for Encoding BACnet Tags
// returns the number of apdu bytes consumed // returns the number of apdu bytes consumed
int decode_character_string(uint8_t * apdu, uint32_t len_value, int decode_character_string(uint8_t * apdu, uint32_t len_value,
char *char_string, size_t string_len) BACNET_CHARACTER_STRING *char_string)
{ {
int len = 0; // return value int len = 0; // return value
uint32_t i = 0; // counter bool status = false;
// FIXME: issue warning? status = characterstring_init(char_string, apdu[0], (char *)&apdu[1],
if (len_value > string_len) len_value-1);
len_value = string_len; if (status)
len = len_value;
if (len_value) {
// decode ANSI X3.4
if (apdu[len] == 0) {
len++;
len_value--;
for (i = 0; i < len_value; i++) {
char_string[i] = apdu[len + i];
}
// terminate the c string
char_string[i] = 0;
len += len_value;
}
}
return len; return len;
} }
@@ -1509,40 +1495,54 @@ void testBACDCodeOctetString(Test * pTest)
{ {
uint8_t array[MAX_APDU] = { 0 }; uint8_t array[MAX_APDU] = { 0 };
uint8_t encoded_array[MAX_APDU] = { 0 }; uint8_t encoded_array[MAX_APDU] = { 0 };
char test_string[MAX_APDU] = { "" }; BACNET_OCTET_STRING octet_string;
char decoded_string[MAX_APDU] = { "" }; BACNET_OCTET_STRING test_octet_string;
uint8_t test_value[MAX_APDU] = { "" };
int i; // for loop counter int i; // for loop counter
int apdu_len; int apdu_len;
int len; int len;
char *test_string0 = "";
uint8_t tag_number = 0; uint8_t tag_number = 0;
uint32_t len_value = 0; uint32_t len_value = 0;
bool status = false;
int diff = 0; /* for memcmp */
apdu_len = encode_tagged_octet_string(&array[0], (uint8_t *)&test_string0[0], 0); status = octetstring_init(
&octet_string,
NULL,
0);
ct_test(pTest,status == true);
apdu_len = encode_tagged_octet_string(&array[0], &octet_string);
len = decode_tag_number_and_value(&array[0], &tag_number, &len_value); len = decode_tag_number_and_value(&array[0], &tag_number, &len_value);
len += decode_octet_string(&array[len], len_value, ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OCTET_STRING);
(uint8_t *)&decoded_string[0], sizeof(decoded_string)); len += decode_octet_string(&array[len], len_value, &test_octet_string);
ct_test(pTest, apdu_len == len); ct_test(pTest, apdu_len == len);
ct_test(pTest, memcmp(&test_string0[0], &decoded_string[0], diff = memcmp(octetstring_value(&octet_string), &test_value[0],
len_value) == 0); octetstring_length(&octet_string));
ct_test(pTest,diff == 0);
for (i = 0; i < (MAX_APDU - 6); i++) { for (i = 0; i < (MAX_APDU - 6); i++) {
test_string[i] = '0' + (i % 10); test_value[i] = '0' + (i % 10);
apdu_len = status = octetstring_init(
encode_tagged_octet_string(&encoded_array[0], &octet_string,
(uint8_t *)&test_string[0], i); test_value,
i);
ct_test(pTest,status == true);
apdu_len = encode_tagged_octet_string(&encoded_array[0],&octet_string);
len = decode_tag_number_and_value(&encoded_array[0], len = decode_tag_number_and_value(&encoded_array[0],
&tag_number, &len_value); &tag_number, &len_value);
ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OCTET_STRING);
len += decode_octet_string(&encoded_array[len], len_value, len += decode_octet_string(&encoded_array[len], len_value,
(uint8_t *)&decoded_string[0], sizeof(decoded_string)); &test_octet_string);
if (apdu_len != len) { if (apdu_len != len) {
printf("test octet string=#%d\n", i); printf("test octet string=#%d\n", i);
} }
ct_test(pTest, apdu_len == len); ct_test(pTest, apdu_len == len);
if (memcmp(&test_string[0], &decoded_string[0], len_value) != 0) { diff = memcmp(octetstring_value(&octet_string), &test_value[0],
octetstring_length(&octet_string));
if (diff) {
printf("test octet string=#%d\n", i); printf("test octet string=#%d\n", i);
} }
ct_test(pTest, memcmp(&test_string[0], &decoded_string[0], ct_test(pTest,diff == 0);
len_value) == 0);
} }
return; return;
@@ -1552,39 +1552,53 @@ void testBACDCodeCharacterString(Test * pTest)
{ {
uint8_t array[MAX_APDU] = { 0 }; uint8_t array[MAX_APDU] = { 0 };
uint8_t encoded_array[MAX_APDU] = { 0 }; uint8_t encoded_array[MAX_APDU] = { 0 };
char test_string[MAX_APDU] = { "" }; BACNET_CHARACTER_STRING char_string;
char decoded_string[MAX_APDU] = { "" }; BACNET_CHARACTER_STRING test_char_string;
char test_value[MAX_APDU] = { "" };
int i; // for loop counter int i; // for loop counter
int apdu_len; int apdu_len;
int len; int len;
char *test_string0 = "";
uint8_t tag_number = 0; uint8_t tag_number = 0;
uint32_t len_value = 0; uint32_t len_value = 0;
int diff = 0; /* for comparison */
bool status = false;
apdu_len = encode_tagged_character_string(&array[0], &test_string0[0]); status = characterstring_init(
&char_string,
CHARACTER_ANSI,
NULL,
0);
ct_test(pTest,status == true);
apdu_len = encode_tagged_character_string(&array[0], &char_string);
len = decode_tag_number_and_value(&array[0], &tag_number, &len_value); len = decode_tag_number_and_value(&array[0], &tag_number, &len_value);
len += decode_character_string(&array[len], len_value, ct_test(pTest,tag_number == BACNET_APPLICATION_TAG_CHARACTER_STRING);
&decoded_string[0], sizeof(decoded_string)); len += decode_character_string(&array[len], len_value, &test_char_string);
ct_test(pTest, apdu_len == len); ct_test(pTest, apdu_len == len);
ct_test(pTest, strcmp(&test_string0[0], &decoded_string[0]) == 0); diff = memcmp(characterstring_value(&char_string), &test_value[0],
characterstring_length(&char_string));
ct_test(pTest, diff == 0);
for (i = 0; i < (MAX_APDU - 6); i++) { for (i = 0; i < (MAX_APDU - 6); i++) {
test_string[i] = 'S'; test_value[i] = 'S';
test_string[i + 1] = '\0'; test_value[i + 1] = '\0';
status = characterstring_init_ansi(&char_string, test_value);
ct_test(pTest,status == true);
apdu_len = apdu_len =
encode_tagged_character_string(&encoded_array[0], encode_tagged_character_string(&encoded_array[0], &char_string);
&test_string[0]);
len = decode_tag_number_and_value(&encoded_array[0], len = decode_tag_number_and_value(&encoded_array[0],
&tag_number, &len_value); &tag_number, &len_value);
ct_test(pTest,tag_number == BACNET_APPLICATION_TAG_CHARACTER_STRING);
len += decode_character_string(&encoded_array[len], len_value, len += decode_character_string(&encoded_array[len], len_value,
&decoded_string[0], sizeof(decoded_string)); &test_char_string);
if (apdu_len != len) { if (apdu_len != len) {
printf("test string=#%d\n", i); printf("test string=#%d apdu_len=%d len=%d\n", i,apdu_len,len);
} }
ct_test(pTest, apdu_len == len); ct_test(pTest, apdu_len == len);
if (strcmp(&test_string[0], &decoded_string[0]) != 0) { diff = memcmp(characterstring_value(&char_string), &test_value[0],
characterstring_length(&char_string));
if (diff) {
printf("test string=#%d\n", i); printf("test string=#%d\n", i);
} }
ct_test(pTest, strcmp(&test_string[0], &decoded_string[0]) == 0); ct_test(pTest, diff == 0);
} }
return; return;
+8 -10
View File
@@ -100,25 +100,23 @@ int encode_tagged_object_id(uint8_t * apdu, int object_type, uint32_t instance);
// from clause 20.2.8 Encoding of an Octet String Value // from clause 20.2.8 Encoding of an Octet String Value
// and 20.2.1 General Rules for Encoding BACnet Tags // and 20.2.1 General Rules for Encoding BACnet Tags
// returns the number of apdu bytes consumed // returns the number of apdu bytes consumed
int encode_octet_string(uint8_t * apdu, const uint8_t *octet_string, int encode_octet_string(uint8_t * apdu,
unsigned len); BACNET_OCTET_STRING *octet_string);
int encode_tagged_octet_string(uint8_t * apdu, const uint8_t *octet_string, int encode_tagged_octet_string(uint8_t * apdu,
unsigned len); BACNET_OCTET_STRING *octet_string);
int decode_octet_string(uint8_t * apdu, uint32_t len_value, int decode_octet_string(uint8_t * apdu, uint32_t len_value,
uint8_t *buffer, size_t buffer_len); BACNET_OCTET_STRING *octet_string);
// from clause 20.2.9 Encoding of a Character String Value // from clause 20.2.9 Encoding of a Character String Value
// and 20.2.1 General Rules for Encoding BACnet Tags // and 20.2.1 General Rules for Encoding BACnet Tags
// returns the number of apdu bytes consumed // returns the number of apdu bytes consumed
int encode_bacnet_string(uint8_t * apdu,
const char *char_string, int string_len);
int encode_bacnet_character_string(uint8_t * apdu, int encode_bacnet_character_string(uint8_t * apdu,
const char *char_string); BACNET_CHARACTER_STRING *char_string);
int encode_tagged_character_string(uint8_t * apdu, int encode_tagged_character_string(uint8_t * apdu,
const char *char_string); BACNET_CHARACTER_STRING *char_string);
int decode_character_string(uint8_t * apdu, uint32_t len_value, int decode_character_string(uint8_t * apdu, uint32_t len_value,
char *char_string, size_t string_len); BACNET_CHARACTER_STRING *char_string);
// from clause 20.2.4 Encoding of an Unsigned Integer Value // from clause 20.2.4 Encoding of an Unsigned Integer Value
// and 20.2.1 General Rules for Encoding BACnet Tags // and 20.2.1 General Rules for Encoding BACnet Tags
+1
View File
@@ -6,6 +6,7 @@ CFLAGS = -Wall -I. -Itest -g -DTEST -DTEST_DECODE
TARGET = bacdcode TARGET = bacdcode
SRCS = bacdcode.c \ SRCS = bacdcode.c \
bacstr.c \
bigend.c \ bigend.c \
test/ctest.c test/ctest.c
+1
View File
@@ -7,6 +7,7 @@ BASEDIR = .
CFLAGS = -Wall -I. -Itest -DTEST -DTEST_BACERROR -g CFLAGS = -Wall -I. -Itest -DTEST -DTEST_BACERROR -g
SRCS = bacdcode.c \ SRCS = bacdcode.c \
bacstr.c \
bigend.c \ bigend.c \
bacerror.c \ bacerror.c \
test/ctest.c test/ctest.c
+15 -7
View File
@@ -153,6 +153,7 @@ int bacfile_encode_property_apdu(
{ {
int apdu_len = 0; // return value int apdu_len = 0; // return value
char text_string[32] = {""}; char text_string[32] = {""};
BACNET_CHARACTER_STRING char_string;
(void)array_index; (void)array_index;
switch (property) switch (property)
@@ -164,17 +165,22 @@ int bacfile_encode_property_apdu(
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
sprintf(text_string,"FILE %d",object_instance); sprintf(text_string,"FILE %d",object_instance);
apdu_len = encode_tagged_character_string(&apdu[0], text_string); characterstring_init_ansi(&char_string, text_string);
apdu_len = encode_tagged_character_string(&apdu[0],
&char_string);
break; break;
case PROP_OBJECT_TYPE: case PROP_OBJECT_TYPE:
apdu_len = encode_tagged_enumerated(&apdu[0], OBJECT_FILE); apdu_len = encode_tagged_enumerated(&apdu[0], OBJECT_FILE);
break; break;
case PROP_DESCRIPTION: case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string, bacfile_name(object_instance));
apdu_len = encode_tagged_character_string(&apdu[0], apdu_len = encode_tagged_character_string(&apdu[0],
bacfile_name(object_instance)); &char_string);
break; break;
case PROP_FILE_TYPE: case PROP_FILE_TYPE:
apdu_len = encode_tagged_character_string(&apdu[0],"TEXT"); characterstring_init_ansi(&char_string, "TEXT");
apdu_len = encode_tagged_character_string(&apdu[0],
&char_string);
break; break;
case PROP_FILE_SIZE: case PROP_FILE_SIZE:
apdu_len = encode_tagged_unsigned(&apdu[0], apdu_len = encode_tagged_unsigned(&apdu[0],
@@ -300,6 +306,7 @@ bool bacfile_read_data(BACNET_ATOMIC_READ_FILE_DATA *data)
char *pFilename = NULL; char *pFilename = NULL;
bool found = false; bool found = false;
FILE *pFile = NULL; FILE *pFile = NULL;
size_t len = 0;
pFilename = bacfile_name(data->object_instance); pFilename = bacfile_name(data->object_instance);
if (pFilename) if (pFilename)
@@ -311,23 +318,24 @@ bool bacfile_read_data(BACNET_ATOMIC_READ_FILE_DATA *data)
(void)fseek(pFile, (void)fseek(pFile,
data->type.stream.fileStartPosition, data->type.stream.fileStartPosition,
SEEK_SET); SEEK_SET);
data->fileDataLength = fread(data->fileData, 1, len = fread(octetstring_value(&data->fileData), 1,
data->type.stream.requestedOctetCount, pFile); data->type.stream.requestedOctetCount, pFile);
if (data->fileDataLength < data->type.stream.requestedOctetCount) if (len < data->type.stream.requestedOctetCount)
data->endOfFile = true; data->endOfFile = true;
else else
data->endOfFile = false; data->endOfFile = false;
octetstring_truncate(&data->fileData,len);
fclose(pFile); fclose(pFile);
} }
else else
{ {
data->fileDataLength = 0; octetstring_truncate(&data->fileData,0);
data->endOfFile = true; data->endOfFile = true;
} }
} }
else else
{ {
data->fileDataLength = 0; octetstring_truncate(&data->fileData,0);
data->endOfFile = true; data->endOfFile = true;
} }
+98 -50
View File
@@ -34,6 +34,7 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <string.h> /* for strlen */
#include "bacstr.h" #include "bacstr.h"
#include "bits.h" #include "bits.h"
@@ -87,10 +88,19 @@ uint8_t bitstring_bits_used(BACNET_BIT_STRING *bit_string)
return bit_string->bits_used; return bit_string->bits_used;
} }
uint8_t bitstring_bits_capacity(BACNET_BIT_STRING *bit_string)
{
if (bit_string)
return (sizeof(bit_string->value) * 8);
else
return 0;
}
/* returns false if the string exceeds capacity /* returns false if the string exceeds capacity
initialize by using length=0 */ initialize by using length=0 */
bool characterstring_init( bool characterstring_init(
BACNET_CHARACTER_STRING *char_string, BACNET_CHARACTER_STRING *char_string,
uint8_t encoding,
char *value, char *value,
size_t length) size_t length)
{ {
@@ -100,6 +110,7 @@ bool characterstring_init(
if (char_string) if (char_string)
{ {
char_string->length = 0; char_string->length = 0;
char_string->encoding = encoding;
if (length <= sizeof(char_string->value)) if (length <= sizeof(char_string->value))
{ {
if (value) if (value)
@@ -124,6 +135,16 @@ bool characterstring_init(
return status; return status;
} }
bool characterstring_init_ansi(
BACNET_CHARACTER_STRING *char_string,
char *value)
{
return characterstring_init(
char_string,
CHARACTER_ANSI,
value, value?strlen(value):0);
}
/* returns false if the string exceeds capacity */ /* returns false if the string exceeds capacity */
bool characterstring_append( bool characterstring_append(
BACNET_CHARACTER_STRING *char_string, BACNET_CHARACTER_STRING *char_string,
@@ -171,25 +192,16 @@ bool characterstring_truncate(
} }
/* returns the length. Returns the value in parameter. */ /* returns the length. Returns the value in parameter. */
size_t characterstring_value(BACNET_CHARACTER_STRING *char_string, char *value) char *characterstring_value(BACNET_CHARACTER_STRING *char_string)
{ {
size_t i; /* counter */ char *value = NULL;
size_t length = 0; /* return value */
if (char_string) if (char_string)
{ {
/* FIXME: validate length is within bounds? */ value = char_string->value;
length = char_string->length;
if (value)
{
for (i = 0; i < sizeof(char_string->value); i++)
{
value[i] = char_string->value[i];
}
}
} }
return length; return value;
} }
/* returns the length. */ /* returns the length. */
@@ -206,6 +218,31 @@ size_t characterstring_length(BACNET_CHARACTER_STRING *char_string)
return length; return length;
} }
size_t characterstring_capacity(BACNET_CHARACTER_STRING *char_string)
{
size_t length = 0;
if (char_string)
{
length = sizeof(char_string->value);
}
return length;
}
/* returns the encoding. */
uint8_t characterstring_encoding(BACNET_CHARACTER_STRING *char_string)
{
uint8_t encoding = 0;
if (char_string)
{
encoding = char_string->encoding;
}
return encoding;
}
/* returns false if the string exceeds capacity /* returns false if the string exceeds capacity
initialize by using length=0 */ initialize by using length=0 */
bool octetstring_init( bool octetstring_init(
@@ -290,25 +327,16 @@ bool octetstring_truncate(
} }
/* returns the length. Returns the value in parameter. */ /* returns the length. Returns the value in parameter. */
size_t octetstring_value(BACNET_OCTET_STRING *octet_string, uint8_t *value) uint8_t *octetstring_value(BACNET_OCTET_STRING *octet_string)
{ {
size_t i; /* counter */ uint8_t *value = NULL;
size_t length = 0; /* return value */
if (octet_string) if (octet_string)
{ {
/* FIXME: validate length is within bounds? */ value = octet_string->value;
length = octet_string->length;
if (value)
{
for (i = 0; i < sizeof(octet_string->value); i++)
{
value[i] = octet_string->value[i];
}
}
} }
return length; return value;
} }
/* returns the length. */ /* returns the length. */
@@ -325,6 +353,20 @@ size_t octetstring_length(BACNET_OCTET_STRING *octet_string)
return length; return length;
} }
/* returns the length. */
size_t octetstring_capacity(BACNET_OCTET_STRING *octet_string)
{
size_t length = 0;
if (octet_string)
{
/* FIXME: validate length is within bounds? */
length = sizeof(octet_string->value);
}
return length;
}
#ifdef TEST #ifdef TEST
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
@@ -363,7 +405,7 @@ void testBitString(Test * pTest)
void testCharacterString(Test * pTest) void testCharacterString(Test * pTest)
{ {
BACNET_CHARACTER_STRING bacnet_string; BACNET_CHARACTER_STRING bacnet_string;
char value[MAX_APDU] = "Joshua,Mary,Anna,Christopher"; char *value = "Joshua,Mary,Anna,Christopher";
char test_value[MAX_APDU] = "Patricia"; char test_value[MAX_APDU] = "Patricia";
char test_append_value[MAX_APDU] = " and the Kids"; char test_append_value[MAX_APDU] = " and the Kids";
char test_append_string[MAX_APDU] = ""; char test_append_string[MAX_APDU] = "";
@@ -373,37 +415,38 @@ void testCharacterString(Test * pTest)
size_t i = 0; size_t i = 0;
// verify initialization // verify initialization
status = characterstring_init(&bacnet_string,NULL,0); status = characterstring_init(&bacnet_string,CHARACTER_ANSI,NULL,0);
ct_test(pTest, status == true); ct_test(pTest, status == true);
ct_test(pTest,characterstring_length(&bacnet_string) == 0); ct_test(pTest,characterstring_length(&bacnet_string) == 0);
ct_test(pTest, characterstring_value(&bacnet_string,&value[0]) == 0); ct_test(pTest,characterstring_encoding(&bacnet_string) == CHARACTER_ANSI);
for (i = 0; i < sizeof(value); i++)
{
ct_test(pTest, value[i] == 0);
}
/* bounds check */ /* bounds check */
status = characterstring_init(&bacnet_string,NULL,sizeof(value)+1); status = characterstring_init(
&bacnet_string,
CHARACTER_ANSI,
NULL,
characterstring_capacity(&bacnet_string)+1);
ct_test(pTest, status == false); ct_test(pTest, status == false);
status = characterstring_init(&bacnet_string,NULL,sizeof(value)); status = characterstring_truncate(
ct_test(pTest, status == true); &bacnet_string,characterstring_capacity(&bacnet_string)+1);
status = characterstring_truncate(&bacnet_string,sizeof(value)+1);
ct_test(pTest, status == false); ct_test(pTest, status == false);
status = characterstring_truncate(&bacnet_string,sizeof(value)); status = characterstring_truncate(
&bacnet_string,characterstring_capacity(&bacnet_string));
ct_test(pTest, status == true); ct_test(pTest, status == true);
test_length = strlen(test_value); test_length = strlen(test_value);
status = characterstring_init( status = characterstring_init(
&bacnet_string, &bacnet_string,
CHARACTER_ANSI,
&test_value[0], &test_value[0],
test_length); test_length);
ct_test(pTest, status == true); ct_test(pTest, status == true);
length = characterstring_value(&bacnet_string,&value[0]); value = characterstring_value(&bacnet_string);
length = characterstring_length(&bacnet_string);
ct_test(pTest, length == test_length); ct_test(pTest, length == test_length);
for (i = 0; i < test_length; i++) for (i = 0; i < test_length; i++)
{ {
ct_test(pTest, value[i] == test_value[i]); ct_test(pTest, value[i] == test_value[i]);
} }
test_length = strlen(test_append_value); test_length = strlen(test_append_value);
status = characterstring_append( status = characterstring_append(
&bacnet_string, &bacnet_string,
@@ -413,7 +456,8 @@ void testCharacterString(Test * pTest)
strcat(test_append_string,test_append_value); strcat(test_append_string,test_append_value);
test_length = strlen(test_append_string); test_length = strlen(test_append_string);
ct_test(pTest, status == true); ct_test(pTest, status == true);
length = characterstring_value(&bacnet_string,&value[0]); length = characterstring_length(&bacnet_string);
value = characterstring_value(&bacnet_string);
ct_test(pTest, length == test_length); ct_test(pTest, length == test_length);
for (i = 0; i < test_length; i++) for (i = 0; i < test_length; i++)
{ {
@@ -424,7 +468,7 @@ void testCharacterString(Test * pTest)
void testOctetString(Test * pTest) void testOctetString(Test * pTest)
{ {
BACNET_OCTET_STRING bacnet_string; BACNET_OCTET_STRING bacnet_string;
uint8_t value[MAX_APDU] = "Joshua,Mary,Anna,Christopher"; uint8_t *value = NULL;
uint8_t test_value[MAX_APDU] = "Patricia"; uint8_t test_value[MAX_APDU] = "Patricia";
uint8_t test_append_value[MAX_APDU] = " and the Kids"; uint8_t test_append_value[MAX_APDU] = " and the Kids";
uint8_t test_append_string[MAX_APDU] = ""; uint8_t test_append_string[MAX_APDU] = "";
@@ -437,19 +481,21 @@ void testOctetString(Test * pTest)
status = octetstring_init(&bacnet_string,NULL,0); status = octetstring_init(&bacnet_string,NULL,0);
ct_test(pTest, status == true); ct_test(pTest, status == true);
ct_test(pTest,octetstring_length(&bacnet_string) == 0); ct_test(pTest,octetstring_length(&bacnet_string) == 0);
ct_test(pTest, octetstring_value(&bacnet_string,&value[0]) == 0); value = octetstring_value(&bacnet_string);
for (i = 0; i < sizeof(value); i++) for (i = 0; i < octetstring_capacity(&bacnet_string); i++)
{ {
ct_test(pTest, value[i] == 0); ct_test(pTest, value[i] == 0);
} }
/* bounds check */ /* bounds check */
status = octetstring_init(&bacnet_string,NULL,sizeof(value)+1); status = octetstring_init(&bacnet_string,NULL,
octetstring_capacity(&bacnet_string)+1);
ct_test(pTest, status == false); ct_test(pTest, status == false);
status = octetstring_init(&bacnet_string,NULL,sizeof(value)); status = octetstring_init(&bacnet_string,NULL,
octetstring_capacity(&bacnet_string));
ct_test(pTest, status == true); ct_test(pTest, status == true);
status = octetstring_truncate(&bacnet_string,sizeof(value)+1); status = octetstring_truncate(&bacnet_string,octetstring_capacity(&bacnet_string)+1);
ct_test(pTest, status == false); ct_test(pTest, status == false);
status = octetstring_truncate(&bacnet_string,sizeof(value)); status = octetstring_truncate(&bacnet_string,octetstring_capacity(&bacnet_string));
ct_test(pTest, status == true); ct_test(pTest, status == true);
test_length = strlen((char *)test_value); test_length = strlen((char *)test_value);
@@ -458,7 +504,8 @@ void testOctetString(Test * pTest)
&test_value[0], &test_value[0],
test_length); test_length);
ct_test(pTest, status == true); ct_test(pTest, status == true);
length = octetstring_value(&bacnet_string,&value[0]); length = octetstring_length(&bacnet_string);
value = octetstring_value(&bacnet_string);
ct_test(pTest, length == test_length); ct_test(pTest, length == test_length);
for (i = 0; i < test_length; i++) for (i = 0; i < test_length; i++)
{ {
@@ -474,7 +521,8 @@ void testOctetString(Test * pTest)
strcat((char *)test_append_string,(char *)test_append_value); strcat((char *)test_append_string,(char *)test_append_value);
test_length = strlen((char *)test_append_string); test_length = strlen((char *)test_append_string);
ct_test(pTest, status == true); ct_test(pTest, status == true);
length = octetstring_value(&bacnet_string,&value[0]); length = octetstring_length(&bacnet_string);
value = octetstring_value(&bacnet_string);
ct_test(pTest, length == test_length); ct_test(pTest, length == test_length);
for (i = 0; i < test_length; i++) for (i = 0; i < test_length; i++)
{ {
+23 -6
View File
@@ -51,7 +51,9 @@ typedef struct BACnet_Bit_String
typedef struct BACnet_Character_String typedef struct BACnet_Character_String
{ {
size_t length; size_t length;
char value[MAX_APDU]; uint8_t encoding;
/* limit - 6 octets is the most our tag and type could be */
char value[MAX_APDU-6];
} BACNET_CHARACTER_STRING; } BACNET_CHARACTER_STRING;
/* FIXME: convert the bacdcode library to use BACNET_OCTET_STRING /* FIXME: convert the bacdcode library to use BACNET_OCTET_STRING
@@ -59,7 +61,8 @@ typedef struct BACnet_Character_String
typedef struct BACnet_Octet_String typedef struct BACnet_Octet_String
{ {
size_t length; size_t length;
uint8_t value[MAX_APDU]; /* limit - 6 octets is the most our tag and type could be */
uint8_t value[MAX_APDU-6];
} BACNET_OCTET_STRING; } BACNET_OCTET_STRING;
#ifdef __cplusplus #ifdef __cplusplus
@@ -70,13 +73,19 @@ void bitstring_init(BACNET_BIT_STRING *bit_string);
void bitstring_set_bit(BACNET_BIT_STRING *bit_string, uint8_t bit, bool value); void bitstring_set_bit(BACNET_BIT_STRING *bit_string, uint8_t bit, bool value);
bool bitstring_bit(BACNET_BIT_STRING *bit_string, uint8_t bit); bool bitstring_bit(BACNET_BIT_STRING *bit_string, uint8_t bit);
uint8_t bitstring_bits_used(BACNET_BIT_STRING *bit_string); uint8_t bitstring_bits_used(BACNET_BIT_STRING *bit_string);
uint8_t bitstring_bits_capacity(BACNET_BIT_STRING *bit_string);
/* returns false if the string exceeds capacity /* returns false if the string exceeds capacity
initialize by using length=0 */ initialize by using length=0 */
bool characterstring_init( bool characterstring_init(
BACNET_CHARACTER_STRING *char_string, BACNET_CHARACTER_STRING *char_string,
uint8_t encoding,
char *value, char *value,
size_t length); size_t length);
/* used for ANSI C-Strings */
bool characterstring_init_ansi(
BACNET_CHARACTER_STRING *char_string,
char *value);
/* returns false if the string exceeds capacity */ /* returns false if the string exceeds capacity */
bool characterstring_append( bool characterstring_append(
BACNET_CHARACTER_STRING *char_string, BACNET_CHARACTER_STRING *char_string,
@@ -88,9 +97,15 @@ bool characterstring_append(
bool characterstring_truncate( bool characterstring_truncate(
BACNET_CHARACTER_STRING *char_string, BACNET_CHARACTER_STRING *char_string,
size_t length); size_t length);
/* returns the length. Returns the value in parameter. */ bool characterstring_set_encoding(
size_t characterstring_value(BACNET_CHARACTER_STRING *char_string, char *value); BACNET_CHARACTER_STRING *char_string,
uint8_t encoding);
/* Returns the value */
char *characterstring_value(BACNET_CHARACTER_STRING *char_string);
/* returns the length */
size_t characterstring_length(BACNET_CHARACTER_STRING *char_string); size_t characterstring_length(BACNET_CHARACTER_STRING *char_string);
uint8_t characterstring_encoding(BACNET_CHARACTER_STRING *char_string);
size_t characterstring_capacity(BACNET_CHARACTER_STRING *char_string);
/* returns false if the string exceeds capacity /* returns false if the string exceeds capacity
initialize by using length=0 */ initialize by using length=0 */
@@ -109,9 +124,11 @@ bool octetstring_append(
bool octetstring_truncate( bool octetstring_truncate(
BACNET_OCTET_STRING *octet_string, BACNET_OCTET_STRING *octet_string,
size_t length); size_t length);
/* returns the length. Returns the value in parameter. */ /* Returns the value */
size_t octetstring_value(BACNET_OCTET_STRING *octet_string, uint8_t *value); uint8_t *octetstring_value(BACNET_OCTET_STRING *octet_string);
/* Returns the length.*/
size_t octetstring_length(BACNET_OCTET_STRING *octet_string); size_t octetstring_length(BACNET_OCTET_STRING *octet_string);
size_t octetstring_capacity(BACNET_OCTET_STRING *octet_string);
#ifdef __cplusplus #ifdef __cplusplus
} }
+147 -48
View File
@@ -25,6 +25,7 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <string.h> /* for memmove*/
#include "bacdef.h" #include "bacdef.h"
#include "bacdcode.h" #include "bacdcode.h"
#include "bacenum.h" #include "bacenum.h"
@@ -39,16 +40,16 @@
static uint32_t Object_Instance_Number = 0; static uint32_t Object_Instance_Number = 0;
// FIXME: it is likely that this name is configurable, // FIXME: it is likely that this name is configurable,
// so consider a fixed sized string // so consider a fixed sized string
static const char *Object_Name = "SimpleServer"; static char Object_Name[16] = "SimpleServer";
static BACNET_DEVICE_STATUS System_Status = STATUS_OPERATIONAL; static BACNET_DEVICE_STATUS System_Status = STATUS_OPERATIONAL;
static const char *Vendor_Name = "ASHRAE"; static char Vendor_Name[16] = "ASHRAE";
// vendor id assigned by ASHRAE // vendor id assigned by ASHRAE
static uint16_t Vendor_Identifier = 0; static uint16_t Vendor_Identifier = 0;
static const char *Model_Name = "GNU"; static char Model_Name[16] = "GNU";
static const char *Firmware_Revision = "1.0"; static char Firmware_Revision[16] = "1.0";
static const char *Application_Software_Version = "1.0"; static char Application_Software_Version[16] = "1.0";
//static char *Location = "USA"; static char Location[16] = "USA";
static const char *Description = "server"; static char Description[16] = "server";
//static uint8_t Protocol_Version = 1; - constant, not settable //static uint8_t Protocol_Version = 1; - constant, not settable
//static uint8_t Protocol_Revision = 4; - constant, not settable //static uint8_t Protocol_Revision = 4; - constant, not settable
//Protocol_Services_Supported //Protocol_Services_Supported
@@ -88,10 +89,16 @@ uint32_t Device_Object_Instance_Number(void)
return Object_Instance_Number; return Object_Instance_Number;
} }
void Device_Set_Object_Instance_Number(uint32_t object_id) bool Device_Set_Object_Instance_Number(uint32_t object_id)
{ {
// FIXME: bounds check? bool status = true; /* return value */
Object_Instance_Number = object_id;
if (object_id <= BACNET_MAX_INSTANCE)
Object_Instance_Number = object_id;
else
status = false;
return status;
} }
bool Device_Valid_Object_Instance_Number(uint32_t object_id) bool Device_Valid_Object_Instance_Number(uint32_t object_id)
@@ -117,9 +124,18 @@ const char *Device_Vendor_Name(void)
return Vendor_Name; return Vendor_Name;
} }
void Device_Set_Vendor_Name(const char *name) bool Device_Set_Vendor_Name(const char *name, size_t length)
{ {
Vendor_Name = name; bool status = false; /*return value*/
if (length < sizeof(Vendor_Name))
{
memmove(Vendor_Name,name,length);
Vendor_Name[length] = 0;
status = true;
}
return status;
} }
uint16_t Device_Vendor_Identifier(void) uint16_t Device_Vendor_Identifier(void)
@@ -137,9 +153,18 @@ const char *Device_Model_Name(void)
return Model_Name; return Model_Name;
} }
void Device_Set_Model_Name(const char *name) bool Device_Set_Model_Name(const char *name, size_t length)
{ {
Model_Name = name; bool status = false; /*return value*/
if (length < sizeof(Model_Name))
{
memmove(Model_Name,name,length);
Model_Name[length] = 0;
status = true;
}
return status;
} }
const char *Device_Firmware_Revision(void) const char *Device_Firmware_Revision(void)
@@ -147,9 +172,18 @@ const char *Device_Firmware_Revision(void)
return Firmware_Revision; return Firmware_Revision;
} }
void Device_Set_Firmware_Revision(const char *name) bool Device_Set_Firmware_Revision(const char *name, size_t length)
{ {
Firmware_Revision = name; bool status = false; /*return value*/
if (length < sizeof(Firmware_Revision))
{
memmove(Firmware_Revision,name,length);
Firmware_Revision[length] = 0;
status = true;
}
return status;
} }
const char *Device_Application_Software_Version(void) const char *Device_Application_Software_Version(void)
@@ -157,9 +191,18 @@ const char *Device_Application_Software_Version(void)
return Application_Software_Version; return Application_Software_Version;
} }
void Device_Set_Application_Software_Version(const char *name) bool Device_Set_Application_Software_Version(const char *name, size_t length)
{ {
Application_Software_Version = name; bool status = false; /*return value*/
if (length < sizeof(Application_Software_Version))
{
memmove(Application_Software_Version,name,length);
Application_Software_Version[length] = 0;
status = true;
}
return status;
} }
const char *Device_Description(void) const char *Device_Description(void)
@@ -167,9 +210,37 @@ const char *Device_Description(void)
return Description; return Description;
} }
void Device_Set_Description(const char *name) bool Device_Set_Description(const char *name, size_t length)
{ {
Description = name; bool status = false; /*return value*/
if (length < sizeof(Description))
{
memmove(Description,name,length);
Description[length] = 0;
status = true;
}
return status;
}
const char *Device_Location(void)
{
return Location;
}
bool Device_Set_Location(const char *name, size_t length)
{
bool status = false; /*return value*/
if (length < sizeof(Location))
{
memmove(Location,name,length);
Location[length] = 0;
status = true;
}
return status;
} }
uint8_t Device_Protocol_Version(void) uint8_t Device_Protocol_Version(void)
@@ -301,6 +372,7 @@ int Device_Encode_Property_APDU(
int apdu_len = 0; // return value int apdu_len = 0; // return value
int len = 0; // apdu len intermediate value int len = 0; // apdu len intermediate value
BACNET_BIT_STRING bit_string; BACNET_BIT_STRING bit_string;
BACNET_CHARACTER_STRING char_string;
unsigned i = 0; unsigned i = 0;
int object_type = 0; int object_type = 0;
uint32_t instance = 0; uint32_t instance = 0;
@@ -313,32 +385,44 @@ int Device_Encode_Property_APDU(
Object_Instance_Number); Object_Instance_Number);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
apdu_len = encode_tagged_character_string(&apdu[0], Object_Name); characterstring_init(&char_string,CHARACTER_ANSI,
Object_Name,strlen(Object_Name));
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
break; break;
case PROP_OBJECT_TYPE: case PROP_OBJECT_TYPE:
apdu_len = encode_tagged_enumerated(&apdu[0], OBJECT_DEVICE); apdu_len = encode_tagged_enumerated(&apdu[0], OBJECT_DEVICE);
break; break;
case PROP_DESCRIPTION: case PROP_DESCRIPTION:
apdu_len = encode_tagged_character_string(&apdu[0], Description); characterstring_init(&char_string,CHARACTER_ANSI,
Description,strlen(Description));
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
break; break;
case PROP_SYSTEM_STATUS: case PROP_SYSTEM_STATUS:
apdu_len = encode_tagged_enumerated(&apdu[0], System_Status); apdu_len = encode_tagged_enumerated(&apdu[0], System_Status);
break; break;
case PROP_VENDOR_NAME: case PROP_VENDOR_NAME:
apdu_len = encode_tagged_character_string(&apdu[0], Vendor_Name); characterstring_init(&char_string,CHARACTER_ANSI,
Vendor_Name,strlen(Vendor_Name));
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
break; break;
case PROP_VENDOR_IDENTIFIER: case PROP_VENDOR_IDENTIFIER:
apdu_len = encode_tagged_unsigned(&apdu[0], Vendor_Identifier); apdu_len = encode_tagged_unsigned(&apdu[0], Vendor_Identifier);
break; break;
case PROP_MODEL_NAME: case PROP_MODEL_NAME:
apdu_len = encode_tagged_character_string(&apdu[0], Model_Name); characterstring_init(&char_string,CHARACTER_ANSI,
Model_Name,strlen(Model_Name));
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
break; break;
case PROP_FIRMWARE_REVISION: case PROP_FIRMWARE_REVISION:
apdu_len = encode_tagged_character_string(&apdu[0], Firmware_Revision); characterstring_init(&char_string,CHARACTER_ANSI,
Firmware_Revision,strlen(Firmware_Revision));
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
break; break;
case PROP_APPLICATION_SOFTWARE_VERSION: case PROP_APPLICATION_SOFTWARE_VERSION:
apdu_len = encode_tagged_character_string(&apdu[0], characterstring_init(&char_string,CHARACTER_ANSI,
Application_Software_Version); Application_Software_Version,
strlen(Application_Software_Version));
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
break; break;
// if you support time // if you support time
//case PROP_LOCAL_TIME: //case PROP_LOCAL_TIME:
@@ -376,7 +460,7 @@ int Device_Encode_Property_APDU(
// initialize all the services to not-supported // initialize all the services to not-supported
bitstring_set_bit(&bit_string, (uint8_t)i, false); bitstring_set_bit(&bit_string, (uint8_t)i, false);
} }
// initialize those we support /* FIXME: set the services that YOUR device executes */
bitstring_set_bit(&bit_string, SERVICE_SUPPORTED_WHO_IS, true); 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_I_AM, true);
bitstring_set_bit(&bit_string, SERVICE_SUPPORTED_READ_PROPERTY, true); bitstring_set_bit(&bit_string, SERVICE_SUPPORTED_READ_PROPERTY, true);
@@ -389,8 +473,10 @@ int Device_Encode_Property_APDU(
// initialize all the object types to not-supported // initialize all the object types to not-supported
bitstring_set_bit(&bit_string, (uint8_t)i, false); bitstring_set_bit(&bit_string, (uint8_t)i, false);
} }
/* FIXME: indicate the objects that YOU support */
bitstring_set_bit(&bit_string, OBJECT_DEVICE, true); bitstring_set_bit(&bit_string, OBJECT_DEVICE, true);
bitstring_set_bit(&bit_string, OBJECT_ANALOG_INPUT, true); bitstring_set_bit(&bit_string, OBJECT_ANALOG_INPUT, true);
bitstring_set_bit(&bit_string, OBJECT_ANALOG_OUTPUT, true);
apdu_len = encode_tagged_bitstring(&apdu[0], &bit_string); apdu_len = encode_tagged_bitstring(&apdu[0], &bit_string);
break; break;
case PROP_OBJECT_LIST: case PROP_OBJECT_LIST:
@@ -490,10 +576,9 @@ bool Device_Write_Property(
if (wp_data->value.tag == BACNET_APPLICATION_TAG_OBJECT_ID) if (wp_data->value.tag == BACNET_APPLICATION_TAG_OBJECT_ID)
{ {
if ((wp_data->value.type.Object_Id.type == OBJECT_DEVICE) && if ((wp_data->value.type.Object_Id.type == OBJECT_DEVICE) &&
(wp_data->value.type.Object_Id.instance <= BACNET_MAX_INSTANCE)) (Device_Set_Object_Instance_Number(
wp_data->value.type.Object_Id.instance)))
{ {
Device_Set_Object_Instance_Number(
wp_data->value.type.Object_Id.instance);
I_Am_Request = true; I_Am_Request = true;
status = true; status = true;
} }
@@ -561,18 +646,18 @@ bool Device_Write_Property(
*error_code = ERROR_CODE_INVALID_DATA_TYPE; *error_code = ERROR_CODE_INVALID_DATA_TYPE;
} }
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
if (wp_data->value.tag == BACNET_APPLICATION_TAG_CHARACTER_STRING) if (wp_data->value.tag == BACNET_APPLICATION_TAG_CHARACTER_STRING)
{ {
BACNET_CHARACTER_STRING Character_String = wp_data->value.type.Character_String; status = Device_Set_Vendor_Name(
characterstring_value(&wp_data->value.type.Character_String),
char decoded_string[MAX_APDU] = { "" }; characterstring_length(&wp_data->value.type.Character_String));
int decoded = 0; if (!status)
//decoded = decode_character_string(&data->application_data[tag_len], len_value_type, &decoded_string[0], sizeof(decoded_string)); {
*error_class = ERROR_CLASS_PROPERTY;
//Device_Set_Vendor_Name(const char *name); *error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY;
status = true; }
} }
else else
{ {
@@ -580,7 +665,7 @@ bool Device_Write_Property(
*error_code = ERROR_CODE_INVALID_DATA_TYPE; *error_code = ERROR_CODE_INVALID_DATA_TYPE;
} }
break; break;
default: default:
*error_class = ERROR_CLASS_PROPERTY; *error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED; *error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
@@ -597,20 +682,34 @@ bool Device_Write_Property(
void testDevice(Test * pTest) void testDevice(Test * pTest)
{ {
Device_Set_Object_Instance_Number(111); bool status = false;
ct_test(pTest, Device_Object_Instance_Number() == 111); const char *name = "Patricia";
status = Device_Set_Object_Instance_Number(0);
ct_test(pTest, Device_Object_Instance_Number() == 0);
ct_test(pTest, status == true);
status = Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
ct_test(pTest, Device_Object_Instance_Number() == BACNET_MAX_INSTANCE);
ct_test(pTest, status == true);
status = Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE/2);
ct_test(pTest, Device_Object_Instance_Number() == (BACNET_MAX_INSTANCE/2));
ct_test(pTest, status == true);
status = Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE+1);
ct_test(pTest, Device_Object_Instance_Number() != (BACNET_MAX_INSTANCE+1));
ct_test(pTest, status == false);
Device_Set_System_Status(STATUS_NON_OPERATIONAL); Device_Set_System_Status(STATUS_NON_OPERATIONAL);
ct_test(pTest, Device_System_Status() == STATUS_NON_OPERATIONAL); ct_test(pTest, Device_System_Status() == STATUS_NON_OPERATIONAL);
Device_Set_Vendor_Name("MyName"); Device_Set_Vendor_Name(name,strlen(name));
ct_test(pTest, strcmp(Device_Vendor_Name(),"MyName") == 0); ct_test(pTest, strcmp(Device_Vendor_Name(),name) == 0);
Device_Set_Vendor_Identifier(42); Device_Set_Vendor_Identifier(42);
ct_test(pTest, Device_Vendor_Identifier() == 42); ct_test(pTest, Device_Vendor_Identifier() == 42);
Device_Set_Model_Name("MyModel"); Device_Set_Model_Name(name,strlen(name));
ct_test(pTest, strcmp(Device_Model_Name(),"MyModel") == 0); ct_test(pTest, strcmp(Device_Model_Name(),name) == 0);
return; return;
} }
+9 -6
View File
@@ -45,7 +45,7 @@ extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
uint32_t Device_Object_Instance_Number(void); uint32_t Device_Object_Instance_Number(void);
void Device_Set_Object_Instance_Number(uint32_t object_id); bool Device_Set_Object_Instance_Number(uint32_t object_id);
bool Device_Valid_Object_Instance_Number(uint32_t object_id); bool Device_Valid_Object_Instance_Number(uint32_t object_id);
unsigned Device_Object_List_Count(void); unsigned Device_Object_List_Count(void);
bool Device_Object_List_Identifier(unsigned array_index, bool Device_Object_List_Identifier(unsigned array_index,
@@ -56,22 +56,25 @@ BACNET_DEVICE_STATUS Device_System_Status(void);
void Device_Set_System_Status(BACNET_DEVICE_STATUS status); void Device_Set_System_Status(BACNET_DEVICE_STATUS status);
const char *Device_Vendor_Name(void); const char *Device_Vendor_Name(void);
void Device_Set_Vendor_Name(const char *name); bool Device_Set_Vendor_Name(const char *name, size_t length);
uint16_t Device_Vendor_Identifier(void); uint16_t Device_Vendor_Identifier(void);
void Device_Set_Vendor_Identifier(uint16_t vendor_id); void Device_Set_Vendor_Identifier(uint16_t vendor_id);
const char *Device_Model_Name(void); const char *Device_Model_Name(void);
void Device_Set_Model_Name(const char *name); bool Device_Set_Model_Name(const char *name, size_t length);
const char *Device_Firmware_Revision(void); const char *Device_Firmware_Revision(void);
void Device_Set_Firmware_Revision(const char *name); bool Device_Set_Firmware_Revision(const char *name, size_t length);
const char *Device_Application_Software_Version(void); const char *Device_Application_Software_Version(void);
void Device_Set_Application_Software_Version(const char *name); bool Device_Set_Application_Software_Version(const char *name, size_t length);
const char *Device_Description(void); const char *Device_Description(void);
void Device_Set_Description(const char *name); bool Device_Set_Description(const char *name, size_t length);
const char *Device_Location(void);
bool Device_Set_Location(const char *name, size_t length);
// some stack-centric constant values - no set methods // some stack-centric constant values - no set methods
uint8_t Device_Protocol_Version(void); uint8_t Device_Protocol_Version(void);
+1
View File
@@ -8,6 +8,7 @@ CFLAGS = -Wall -I. -Itest -DTEST -DTEST_DEVICE -g
SRCS = bacdcode.c \ SRCS = bacdcode.c \
bigend.c \ bigend.c \
bacstr.c \
device.c \ device.c \
test/ctest.c test/ctest.c
+5 -6
View File
@@ -713,7 +713,6 @@ void AtomicReadFileHandler(
int bytes_sent = 0; int bytes_sent = 0;
BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT; BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT;
BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT; BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT;
char buffer[MAX_APDU - 16] = ""; // for reply data, less apdu overhead
fprintf(stderr,"Received Atomic-Read-File Request!\n"); fprintf(stderr,"Received Atomic-Read-File Request!\n");
len = arf_decode_service_request( len = arf_decode_service_request(
@@ -754,9 +753,8 @@ void AtomicReadFileHandler(
{ {
if (data.access == FILE_STREAM_ACCESS) if (data.access == FILE_STREAM_ACCESS)
{ {
data.fileData = (uint8_t *)&buffer[0]; if (data.type.stream.requestedOctetCount <
data.fileDataLength = sizeof(buffer); octetstring_capacity(&data.fileData))
if (data.type.stream.requestedOctetCount < data.fileDataLength)
{ {
if (bacfile_read_data(&data)) if (bacfile_read_data(&data))
{ {
@@ -855,12 +853,13 @@ void AtomicReadFileAckHandler(
(void)fseek(pFile, (void)fseek(pFile,
data.type.stream.fileStartPosition, data.type.stream.fileStartPosition,
SEEK_SET); SEEK_SET);
if (fwrite(data.fileData,data.fileDataLength,1,pFile) != 1) if (fwrite(octetstring_value(&data.fileData),
octetstring_length(&data.fileData),1,pFile) != 1)
fprintf(stderr,"Failed to write to %s (%u)!\n", fprintf(stderr,"Failed to write to %s (%u)!\n",
pFilename, instance); pFilename, instance);
fclose(pFile); fclose(pFile);
} }
} }
} }
else if (data.access == FILE_RECORD_ACCESS) else if (data.access == FILE_RECORD_ACCESS)
{ {
+1
View File
@@ -7,6 +7,7 @@ BASEDIR = .
CFLAGS = -Wall -I. -Itest -DTEST -DTEST_IAM -g CFLAGS = -Wall -I. -Itest -DTEST -DTEST_IAM -g
SRCS = bacdcode.c \ SRCS = bacdcode.c \
bacstr.c \
bigend.c \ bigend.c \
npdu.c \ npdu.c \
apdu.c \ apdu.c \
+1
View File
@@ -7,6 +7,7 @@ BASEDIR = .
CFLAGS = -Wall -I. -Itest -DTEST -DTEST_NPDU -g CFLAGS = -Wall -I. -Itest -DTEST -DTEST_NPDU -g
SRCS = bacdcode.c \ SRCS = bacdcode.c \
bacstr.c \
bigend.c \ bigend.c \
npdu.c \ npdu.c \
apdu.c \ apdu.c \
+2 -16
View File
@@ -47,20 +47,6 @@
// buffers used for receiving // buffers used for receiving
static uint8_t Rx_Buf[MAX_MPDU] = {0}; static uint8_t Rx_Buf[MAX_MPDU] = {0};
static void Init_Device_Parameters(void)
{
// configure my initial values
Device_Set_Object_Instance_Number(111);
Device_Set_Vendor_Name("Lithonia Lighting");
Device_Set_Vendor_Identifier(42);
Device_Set_Model_Name("Simple BACnet Server");
Device_Set_Firmware_Revision("1.00");
Device_Set_Application_Software_Version("none");
Device_Set_Description("Example of a simple BACnet server");
return;
}
static void LocalIAmHandler( static void LocalIAmHandler(
uint8_t *service_request, uint8_t *service_request,
uint16_t service_len, uint16_t service_len,
@@ -275,8 +261,8 @@ int main(int argc, char *argv[])
signal(SIGINT, sig_handler); signal(SIGINT, sig_handler);
signal(SIGHUP, sig_handler); signal(SIGHUP, sig_handler);
signal(SIGTERM, sig_handler); signal(SIGTERM, sig_handler);
// setup this BACnet Server // setup this BACnet Server device
Init_Device_Parameters(); Device_Set_Object_Instance_Number(111);
Init_Service_Handlers(); Init_Service_Handlers();
#ifdef BACDL_ETHERNET #ifdef BACDL_ETHERNET
// init the physical layer // init the physical layer
+1 -15
View File
@@ -67,20 +67,6 @@ volatile struct mstp_port_struct_t MSTP_Port; // port data
static uint8_t MSTP_MAC_Address = 0x05; // local MAC address static uint8_t MSTP_MAC_Address = 0x05; // local MAC address
#endif #endif
static void Init_Device_Parameters(void)
{
// configure my initial values
Device_Set_Object_Instance_Number(126);
Device_Set_Vendor_Name("Lithonia Lighting");
Device_Set_Vendor_Identifier(42);
Device_Set_Model_Name("Simple BACnet Server");
Device_Set_Firmware_Revision("1.00");
Device_Set_Application_Software_Version("none");
Device_Set_Description("Example of a simple BACnet server");
return;
}
static void Init_Service_Handlers(void) static void Init_Service_Handlers(void)
{ {
// we need to handle who-is to support dynamic device binding // we need to handle who-is to support dynamic device binding
@@ -264,7 +250,7 @@ int main(int argc, char *argv[])
(void)argc; (void)argc;
(void)argv; (void)argv;
Init_Device_Parameters(); Device_Set_Object_Instance_Number(126);
Init_Service_Handlers(); Init_Service_Handlers();
// init the physical layer // init the physical layer
#ifdef BACDL_BIP #ifdef BACDL_BIP
+1
View File
@@ -7,6 +7,7 @@ BASEDIR = .
CFLAGS = -Wall -I. -Itest -DTEST -DTEST_REJECT -g CFLAGS = -Wall -I. -Itest -DTEST -DTEST_REJECT -g
SRCS = bacdcode.c \ SRCS = bacdcode.c \
bacstr.c \
bigend.c \ bigend.c \
reject.c \ reject.c \
test/ctest.c test/ctest.c
+1
View File
@@ -7,6 +7,7 @@ BASEDIR = .
CFLAGS = -Wall -I. -Itest -DTEST -DTEST_READ_PROPERTY -g CFLAGS = -Wall -I. -Itest -DTEST -DTEST_READ_PROPERTY -g
SRCS = bacdcode.c \ SRCS = bacdcode.c \
bacstr.c \
bigend.c \ bigend.c \
rp.c \ rp.c \
test/ctest.c test/ctest.c
+1
View File
@@ -9,6 +9,7 @@ CFLAGS = -Wall -I. -Itest -DTEST -DTEST_READ_PROPERTY_MULTIPLE -g
SRCS = bacdcode.c \ SRCS = bacdcode.c \
bacerror.c \ bacerror.c \
bacapp.c \ bacapp.c \
bacstr.c \
bigend.c \ bigend.c \
rpm.c \ rpm.c \
test/ctest.c test/ctest.c
+97 -67
View File
@@ -4,70 +4,15 @@
rm test.log rm test.log
touch test.log touch test.log
make -f crc.mak clean
make -f crc.mak
./crc >> test.log
make -f crc.mak clean
make -f ringbuf.mak clean
make -f ringbuf.mak
./ringbuf >> test.log
make -f ringbuf.mak clean
make -f mstp.mak clean
make -f mstp.mak
./mstp >> test.log
make -f mstp.mak clean
make -f iam.mak clean
make -f iam.mak
./iam >> test.log
make -f iam.mak clean
make -f whois.mak clean
make -f whois.mak
./whois >> test.log
make -f whois.mak clean
make -f bacdcode.mak clean
make -f bacdcode.mak
./bacdcode >> test.log
make -f bacdcode.mak clean
make -f iam.mak clean
make -f iam.mak
./iam >> test.log
make -f iam.mak clean
make -f whois.mak clean
make -f whois.mak
./whois >> test.log
make -f whois.mak clean
make -f npdu.mak clean
make -f npdu.mak
./npdu >> test.log
make -f npdu.mak clean
make -f reject.mak clean
make -f reject.mak
./reject >> test.log
make -f reject.mak clean
make -f abort.mak clean make -f abort.mak clean
make -f abort.mak make -f abort.mak
./abort >> test.log ./abort >> test.log
make -f abort.mak clean make -f abort.mak clean
make -f bacerror.mak clean make -f address.mak clean
make -f bacerror.mak make -f address.mak
./bacerror >> test.log ./address >> test.log
make -f bacerror.mak clean make -f address.mak clean
make -f device.mak clean
make -f device.mak
./device >> test.log
make -f device.mak clean
make -f ai.mak clean make -f ai.mak clean
make -f ai.mak make -f ai.mak
@@ -79,17 +24,102 @@ make -f ao.mak
./analog_output >> test.log ./analog_output >> test.log
make -f ao.mak clean make -f ao.mak clean
make -f wp.mak clean make -f arf.mak clean
make -f wp.mak make -f arf.mak
./writeproperty >> test.log ./atomicreadfile >> test.log
make -f wp.mak clean make -f arf.mak clean
make -f address.mak clean make -f awf.mak clean
make -f address.mak make -f awf.mak
./address >> test.log ./atomicwritefile >> test.log
make -f address.mak clean make -f awf.mak clean
make -f bacapp.mak clean
make -f bacapp.mak
./bacapp >> test.log
make -f bacapp.mak clean
make -f bacdcode.mak clean
make -f bacdcode.mak
./bacdcode >> test.log
make -f bacdcode.mak clean
make -f bacerror.mak clean
make -f bacerror.mak
./bacerror >> test.log
make -f bacerror.mak clean
make -f bacstr.mak clean
make -f bacstr.mak
./bacstr >> test.log
make -f bacstr.mak clean
make -f crc.mak clean
make -f crc.mak
./crc >> test.log
make -f crc.mak clean
make -f device.mak clean
make -f device.mak
./device >> test.log
make -f device.mak clean
make -f iam.mak clean
make -f iam.mak
./iam >> test.log
make -f iam.mak clean
make -f indtext.mak clean make -f indtext.mak clean
make -f indtext.mak make -f indtext.mak
./indtext >> test.log ./indtext >> test.log
make -f indtext.mak clean make -f indtext.mak clean
make -f mstp.mak clean
make -f mstp.mak
./mstp >> test.log
make -f mstp.mak clean
make -f npdu.mak clean
make -f npdu.mak
./npdu >> test.log
make -f npdu.mak clean
make -f reject.mak clean
make -f reject.mak
./reject >> test.log
make -f reject.mak clean
make -f ringbuf.mak clean
make -f ringbuf.mak
./ringbuf >> test.log
make -f ringbuf.mak clean
make -f rp.mak clean
make -f rp.mak
./readproperty >> test.log
make -f rp.mak clean
make -f rpm.mak clean
make -f rpm.mak
./rpm >> test.log
make -f rpm.mak clean
make -f sbuf.mak clean
make -f sbuf.mak
./sbuf >> test.log
make -f sbuf.mak clean
make -f tsm.mak clean
make -f tsm.mak
./tsm >> test.log
make -f tsm.mak clean
make -f whois.mak clean
make -f whois.mak
./whois >> test.log
make -f whois.mak clean
make -f wp.mak clean
make -f wp.mak
./writeproperty >> test.log
make -f wp.mak clean
+4 -15
View File
@@ -250,23 +250,12 @@ void tsm_free_invoke_id(uint8_t invokeID)
#include <string.h> #include <string.h>
#include "ctest.h" #include "ctest.h"
// flag to send an I-Am
bool I_Am_Request = true;
void testTSM(Test * pTest) void testTSM(Test * pTest)
{ {
//unsigned i; /* FIXME: add some unit testing...*/
uint8_t invokeID = 0;
BACNET_ADDRESS dest = {0};
uint8_t pdu[MAX_PDU] = {0};
uint16_t pdu_len = 0;
memset(pdu,0xa5,sizeof(pdu));
pdu_len = sizeof(pdu);
invokeID = tsm_request_confirmed_unsegmented_transaction(
&dest,
&pdu[0],
pdu_len);
ct_test(pTest, invokeID != 0);
return; return;
} }
+9 -1
View File
@@ -6,9 +6,17 @@ BASEDIR = .
#CFLAGS = -Wall -I. -g #CFLAGS = -Wall -I. -g
CFLAGS = -Wall -I. -Itest -DTEST -DTEST_TSM -g CFLAGS = -Wall -I. -Itest -DTEST -DTEST_TSM -g
SRCS = bacdcode.c \ SRCS = address.c \
bacdcode.c \
bacstr.c \
bigend.c \ bigend.c \
device.c \ device.c \
ai.c \
ao.c \
iam.c \
npdu.c \
apdu.c \
datalink.c \
tsm.c \ tsm.c \
test/ctest.c test/ctest.c
+1
View File
@@ -7,6 +7,7 @@ BASEDIR = .
CFLAGS = -Wall -I. -Itest -DTEST -DTEST_WHOIS -g CFLAGS = -Wall -I. -Itest -DTEST -DTEST_WHOIS -g
SRCS = bacdcode.c \ SRCS = bacdcode.c \
bacstr.c \
bigend.c \ bigend.c \
whois.c \ whois.c \
test/ctest.c test/ctest.c
+1
View File
@@ -7,6 +7,7 @@ BASEDIR = .
CFLAGS = -Wall -I. -Itest -DTEST -DTEST_WRITE_PROPERTY -DBACDL_BIP=1 -g CFLAGS = -Wall -I. -Itest -DTEST -DTEST_WRITE_PROPERTY -DBACDL_BIP=1 -g
SRCS = bacdcode.c \ SRCS = bacdcode.c \
bacstr.c \
bigend.c \ bigend.c \
bacapp.c \ bacapp.c \
wp.c \ wp.c \