adding BACnet application and context-specfic data parsing for WriteProperty.
This commit is contained in:
+290
-4
@@ -110,7 +110,7 @@ int bacapp_encode_application_data(uint8_t * apdu,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int bacapp_decode_application_data(uint8_t * apdu,
|
int bacapp_decode_application_data(uint8_t * apdu,
|
||||||
uint8_t apdu_len, BACNET_APPLICATION_DATA_VALUE * value)
|
int max_apdu_len, BACNET_APPLICATION_DATA_VALUE * value)
|
||||||
{
|
{
|
||||||
int len = 0;
|
int len = 0;
|
||||||
int tag_len = 0;
|
int tag_len = 0;
|
||||||
@@ -119,8 +119,8 @@ int bacapp_decode_application_data(uint8_t * apdu,
|
|||||||
int object_type = 0;
|
int object_type = 0;
|
||||||
uint32_t instance = 0;
|
uint32_t instance = 0;
|
||||||
|
|
||||||
/* FIXME: use apdu_len! */
|
/* FIXME: use max_apdu_len! */
|
||||||
(void) apdu_len;
|
(void) max_apdu_len;
|
||||||
if (apdu) {
|
if (apdu) {
|
||||||
tag_len = decode_tag_number_and_value(&apdu[0],
|
tag_len = decode_tag_number_and_value(&apdu[0],
|
||||||
&tag_number, &len_value_type);
|
&tag_number, &len_value_type);
|
||||||
@@ -171,6 +171,84 @@ int bacapp_decode_application_data(uint8_t * apdu,
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int bacapp_encode_context_data(uint8_t * apdu,
|
||||||
|
BACNET_APPLICATION_DATA_VALUE * value,
|
||||||
|
BACNET_PROPERTY_ID property)
|
||||||
|
{
|
||||||
|
int apdu_len = 0; /* total length of the apdu, return value */
|
||||||
|
|
||||||
|
if (value && apdu) {
|
||||||
|
switch (property) {
|
||||||
|
case PROP_REQUESTED_SHED_LEVEL:
|
||||||
|
switch (value->tag) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
apdu_len = encode_tagged_unsigned(&apdu[0],
|
||||||
|
value->type.Unsigned_Int);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
apdu_len = encode_tagged_real(&apdu[0],
|
||||||
|
value->type.Real);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
apdu_len = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return apdu_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bacapp_decode_context_data(uint8_t * apdu,
|
||||||
|
int max_apdu_len, BACNET_APPLICATION_DATA_VALUE * value,
|
||||||
|
BACNET_PROPERTY_ID property)
|
||||||
|
{
|
||||||
|
int len = 0;
|
||||||
|
int tag_len = 0;
|
||||||
|
uint8_t tag_number = 0;
|
||||||
|
uint32_t len_value_type = 0;
|
||||||
|
int object_type = 0;
|
||||||
|
uint32_t instance = 0;
|
||||||
|
|
||||||
|
/* FIXME: use max_apdu_len! */
|
||||||
|
(void) max_apdu_len;
|
||||||
|
if (apdu) {
|
||||||
|
tag_len = decode_tag_number_and_value(&apdu[0],
|
||||||
|
&tag_number, &len_value_type);
|
||||||
|
if (tag_len) {
|
||||||
|
len += tag_len;
|
||||||
|
value->tag = tag_number;
|
||||||
|
switch (property) {
|
||||||
|
case PROP_REQUESTED_SHED_LEVEL:
|
||||||
|
switch (tag_number) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
len += decode_unsigned(&apdu[len],
|
||||||
|
len_value_type,
|
||||||
|
&(value->type.Unsigned_Int));
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
len += decode_real(&apdu[len],
|
||||||
|
&(value->type.Real));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
len = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool bacapp_copy(BACNET_APPLICATION_DATA_VALUE * dest_value,
|
bool bacapp_copy(BACNET_APPLICATION_DATA_VALUE * dest_value,
|
||||||
BACNET_APPLICATION_DATA_VALUE * src_value)
|
BACNET_APPLICATION_DATA_VALUE * src_value)
|
||||||
{
|
{
|
||||||
@@ -236,6 +314,63 @@ bool bacapp_copy(BACNET_APPLICATION_DATA_VALUE * dest_value,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* returns the length of data between an opening tag and a closing tag.
|
||||||
|
Expects that the first octet contain the opening tag.
|
||||||
|
Include a value property identifier for context specific data
|
||||||
|
such as the value received in a WriteProperty request */
|
||||||
|
int bacapp_data_len(uint8_t *apdu, int max_apdu_len,
|
||||||
|
BACNET_PROPERTY_ID property)
|
||||||
|
{
|
||||||
|
int len = 0;
|
||||||
|
int total_len = 0;
|
||||||
|
int apdu_len = 0;
|
||||||
|
uint8_t tag_number = 0;
|
||||||
|
uint8_t opening_tag_number = 0;
|
||||||
|
uint8_t opening_tag_number_counter = 0;
|
||||||
|
uint32_t value = 0;
|
||||||
|
BACNET_APPLICATION_DATA_VALUE application_value;
|
||||||
|
|
||||||
|
if (decode_is_opening_tag(&apdu[0])) {
|
||||||
|
len = decode_tag_number_and_value(&apdu[apdu_len],
|
||||||
|
&tag_number, &value);
|
||||||
|
apdu_len += len;
|
||||||
|
opening_tag_number = tag_number;
|
||||||
|
opening_tag_number_counter = 1;
|
||||||
|
while (opening_tag_number_counter) {
|
||||||
|
if (decode_is_opening_tag(&apdu[apdu_len])) {
|
||||||
|
len = decode_tag_number_and_value(&apdu[apdu_len],
|
||||||
|
&tag_number, &value);
|
||||||
|
if (tag_number == opening_tag_number)
|
||||||
|
opening_tag_number_counter++;
|
||||||
|
} else if (decode_is_closing_tag(&apdu[apdu_len])) {
|
||||||
|
len = decode_tag_number_and_value(&apdu[apdu_len],
|
||||||
|
&tag_number, &value);
|
||||||
|
if (tag_number == opening_tag_number)
|
||||||
|
opening_tag_number_counter--;
|
||||||
|
} else if (decode_is_context_specific(&apdu[apdu_len])) {
|
||||||
|
/* context-specific tagged data */
|
||||||
|
len = bacapp_decode_context_data(&apdu[apdu_len],
|
||||||
|
max_apdu_len - apdu_len, &application_value, property);
|
||||||
|
} else {
|
||||||
|
/* application tagged data */
|
||||||
|
len = bacapp_decode_application_data(&apdu[apdu_len],
|
||||||
|
max_apdu_len - apdu_len, &application_value);
|
||||||
|
}
|
||||||
|
apdu_len += len;
|
||||||
|
if (opening_tag_number_counter)
|
||||||
|
total_len += len;
|
||||||
|
/* ERROR! */
|
||||||
|
if (apdu_len > max_apdu_len)
|
||||||
|
{
|
||||||
|
total_len = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return total_len;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef BACAPP_PRINT_ENABLED
|
#ifdef BACAPP_PRINT_ENABLED
|
||||||
bool bacapp_print_value(FILE * stream,
|
bool bacapp_print_value(FILE * stream,
|
||||||
BACNET_APPLICATION_DATA_VALUE * value, BACNET_PROPERTY_ID property)
|
BACNET_APPLICATION_DATA_VALUE * value, BACNET_PROPERTY_ID property)
|
||||||
@@ -448,6 +583,156 @@ bool bacapp_parse_application_data(BACNET_APPLICATION_TAG tag_number,
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "ctest.h"
|
#include "ctest.h"
|
||||||
|
|
||||||
|
void testBACnetApplicationDataLength(Test * pTest)
|
||||||
|
{
|
||||||
|
int apdu_len = 0; /* total length of the apdu, return value */
|
||||||
|
int len = 0; /* total length of the apdu, return value */
|
||||||
|
int test_len = 0; /* length of the data */
|
||||||
|
uint8_t apdu[480] = { 0 };
|
||||||
|
BACNET_TIME local_time;
|
||||||
|
BACNET_DATE local_date;
|
||||||
|
|
||||||
|
/* create some constructed data */
|
||||||
|
/* 1. zero elements */
|
||||||
|
test_len = 0;
|
||||||
|
apdu_len = 0;
|
||||||
|
len = encode_opening_tag(&apdu[apdu_len], 3);
|
||||||
|
apdu_len += len;
|
||||||
|
len = encode_closing_tag(&apdu[apdu_len], 3);
|
||||||
|
apdu_len += len;
|
||||||
|
/* verify the length of the data inside the opening/closing tags */
|
||||||
|
len = constructed_data_len(&apdu[0], apdu_len,
|
||||||
|
PROP_LIST_OF_OBJECT_PROPERTY_REFERENCES);
|
||||||
|
ct_test(pTest, test_len == len);
|
||||||
|
|
||||||
|
/* 2. application tagged data, one element */
|
||||||
|
test_len = 0;
|
||||||
|
apdu_len = 0;
|
||||||
|
len = encode_opening_tag(&apdu[apdu_len], 3);
|
||||||
|
apdu_len += len;
|
||||||
|
len = encode_tagged_unsigned(&apdu[apdu_len], 4194303);
|
||||||
|
test_len += len;
|
||||||
|
apdu_len += len;
|
||||||
|
len = encode_closing_tag(&apdu[apdu_len], 3);
|
||||||
|
apdu_len += len;
|
||||||
|
/* verify the length of the data inside the opening/closing tags */
|
||||||
|
len = constructed_data_len(&apdu[0], apdu_len,
|
||||||
|
PROP_OBJECT_IDENTIFIER);
|
||||||
|
ct_test(pTest, test_len == len);
|
||||||
|
|
||||||
|
/* 3. application tagged data, multiple elements */
|
||||||
|
test_len = 0;
|
||||||
|
apdu_len = 0;
|
||||||
|
len = encode_opening_tag(&apdu[apdu_len], 3);
|
||||||
|
apdu_len += len;
|
||||||
|
len = encode_tagged_null(&apdu[apdu_len]);
|
||||||
|
test_len += len;
|
||||||
|
apdu_len += len;
|
||||||
|
len = encode_tagged_null(&apdu[apdu_len]);
|
||||||
|
test_len += len;
|
||||||
|
apdu_len += len;
|
||||||
|
len = encode_tagged_unsigned(&apdu[apdu_len], 1);
|
||||||
|
test_len += len;
|
||||||
|
apdu_len += len;
|
||||||
|
len = encode_tagged_unsigned(&apdu[apdu_len], 42);
|
||||||
|
test_len += len;
|
||||||
|
apdu_len += len;
|
||||||
|
len = encode_tagged_unsigned(&apdu[apdu_len], 91);
|
||||||
|
test_len += len;
|
||||||
|
apdu_len += len;
|
||||||
|
len = encode_tagged_null(&apdu[apdu_len]);
|
||||||
|
test_len += len;
|
||||||
|
apdu_len += len;
|
||||||
|
len = encode_tagged_null(&apdu[apdu_len]);
|
||||||
|
test_len += len;
|
||||||
|
apdu_len += len;
|
||||||
|
len = encode_tagged_null(&apdu[apdu_len]);
|
||||||
|
test_len += len;
|
||||||
|
apdu_len += len;
|
||||||
|
len = encode_tagged_null(&apdu[apdu_len]);
|
||||||
|
test_len += len;
|
||||||
|
apdu_len += len;
|
||||||
|
len = encode_tagged_null(&apdu[apdu_len]);
|
||||||
|
test_len += len;
|
||||||
|
apdu_len += len;
|
||||||
|
len = encode_tagged_null(&apdu[apdu_len]);
|
||||||
|
test_len += len;
|
||||||
|
apdu_len += len;
|
||||||
|
len = encode_tagged_null(&apdu[apdu_len]);
|
||||||
|
test_len += len;
|
||||||
|
apdu_len += len;
|
||||||
|
len = encode_tagged_null(&apdu[apdu_len]);
|
||||||
|
test_len += len;
|
||||||
|
apdu_len += len;
|
||||||
|
len = encode_tagged_null(&apdu[apdu_len]);
|
||||||
|
test_len += len;
|
||||||
|
apdu_len += len;
|
||||||
|
len = encode_tagged_null(&apdu[apdu_len]);
|
||||||
|
test_len += len;
|
||||||
|
apdu_len += len;
|
||||||
|
len = encode_tagged_null(&apdu[apdu_len]);
|
||||||
|
test_len += len;
|
||||||
|
apdu_len += len;
|
||||||
|
len = encode_closing_tag(&apdu[apdu_len], 3);
|
||||||
|
apdu_len += len;
|
||||||
|
/* verify the length of the data inside the opening/closing tags */
|
||||||
|
len = constructed_data_len(&apdu[0], apdu_len,
|
||||||
|
PROP_PRIORITY_ARRAY);
|
||||||
|
ct_test(pTest, test_len == len);
|
||||||
|
|
||||||
|
/* 4. complex datatype - one element */
|
||||||
|
test_len = 0;
|
||||||
|
apdu_len = 0;
|
||||||
|
len = encode_opening_tag(&apdu[apdu_len], 3);
|
||||||
|
apdu_len += len;
|
||||||
|
len = encode_opening_tag(&apdu[apdu_len], 3);
|
||||||
|
test_len += len;
|
||||||
|
apdu_len += len;
|
||||||
|
local_date.year = 2006; /* AD */
|
||||||
|
local_date.month = 4; /* 1=Jan */
|
||||||
|
local_date.day = 1; /* 1..31 */
|
||||||
|
local_date.wday = 6; /* 1=Monday */
|
||||||
|
len = encode_tagged_date(&apdu[apdu_len], &local_date);
|
||||||
|
test_len += len;
|
||||||
|
apdu_len += len;
|
||||||
|
local_time.hour = 7;
|
||||||
|
local_time.min = 0;
|
||||||
|
local_time.sec = 3;
|
||||||
|
local_time.hundredths = 1;
|
||||||
|
len = encode_tagged_time(&apdu[apdu_len], &local_time);
|
||||||
|
test_len += len;
|
||||||
|
apdu_len += len;
|
||||||
|
len = encode_closing_tag(&apdu[apdu_len], 3);
|
||||||
|
test_len += len;
|
||||||
|
apdu_len += len;
|
||||||
|
len = encode_closing_tag(&apdu[apdu_len], 3);
|
||||||
|
apdu_len += len;
|
||||||
|
/* verify the length of the data inside the opening/closing tags */
|
||||||
|
len = constructed_data_len(&apdu[0], apdu_len,
|
||||||
|
PROP_START_TIME);
|
||||||
|
ct_test(pTest, test_len == len);
|
||||||
|
|
||||||
|
/* 5. complex datatype - multiple elements */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* 6. context tagged data, one element */
|
||||||
|
test_len = 0;
|
||||||
|
apdu_len = 0;
|
||||||
|
len = encode_opening_tag(&apdu[apdu_len], 3);
|
||||||
|
apdu_len += len;
|
||||||
|
len = encode_context_unsigned(&apdu[apdu_len], 1, 91);
|
||||||
|
test_len += len;
|
||||||
|
apdu_len += len;
|
||||||
|
len = encode_closing_tag(&apdu[apdu_len], 3);
|
||||||
|
apdu_len += len;
|
||||||
|
/* verify the length of the data inside the opening/closing tags */
|
||||||
|
len = constructed_data_len(&apdu[0], apdu_len,
|
||||||
|
PROP_REQUESTED_SHED_LEVEL);
|
||||||
|
ct_test(pTest, test_len == len);
|
||||||
|
}
|
||||||
|
|
||||||
/* returns true if matching or same, false if different */
|
/* returns true if matching or same, false if different */
|
||||||
bool bacapp_same_date(BACNET_DATE * date1, BACNET_DATE * date2)
|
bool bacapp_same_date(BACNET_DATE * date1, BACNET_DATE * date2)
|
||||||
{
|
{
|
||||||
@@ -722,7 +1007,8 @@ int main(void)
|
|||||||
/* individual tests */
|
/* individual tests */
|
||||||
rc = ct_addTestFunction(pTest, testBACnetApplicationData);
|
rc = ct_addTestFunction(pTest, testBACnetApplicationData);
|
||||||
assert(rc);
|
assert(rc);
|
||||||
|
rc = ct_addTestFunction(pTest, testBACnetApplicationDataLength);
|
||||||
|
assert(rc);
|
||||||
ct_setStream(pTest, stdout);
|
ct_setStream(pTest, stdout);
|
||||||
ct_run(pTest);
|
ct_run(pTest);
|
||||||
(void) ct_report(pTest);
|
(void) ct_report(pTest);
|
||||||
|
|||||||
+17
-1
@@ -64,14 +64,29 @@ extern "C" {
|
|||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
int bacapp_decode_application_data(uint8_t * apdu,
|
int bacapp_decode_application_data(uint8_t * apdu,
|
||||||
uint8_t apdu_len, BACNET_APPLICATION_DATA_VALUE * value);
|
int max_apdu_len, BACNET_APPLICATION_DATA_VALUE * value);
|
||||||
|
|
||||||
int bacapp_encode_application_data(uint8_t * apdu,
|
int bacapp_encode_application_data(uint8_t * apdu,
|
||||||
BACNET_APPLICATION_DATA_VALUE * value);
|
BACNET_APPLICATION_DATA_VALUE * value);
|
||||||
|
|
||||||
|
int bacapp_decode_context_data(uint8_t * apdu,
|
||||||
|
int max_apdu_len, BACNET_APPLICATION_DATA_VALUE * value,
|
||||||
|
BACNET_PROPERTY_ID property);
|
||||||
|
|
||||||
|
int bacapp_encode_context_data(uint8_t * apdu,
|
||||||
|
BACNET_APPLICATION_DATA_VALUE * value,
|
||||||
|
BACNET_PROPERTY_ID property);
|
||||||
|
|
||||||
bool bacapp_copy(BACNET_APPLICATION_DATA_VALUE * dest_value,
|
bool bacapp_copy(BACNET_APPLICATION_DATA_VALUE * dest_value,
|
||||||
BACNET_APPLICATION_DATA_VALUE * src_value);
|
BACNET_APPLICATION_DATA_VALUE * src_value);
|
||||||
|
|
||||||
|
/* returns the length of data between an opening tag and a closing tag.
|
||||||
|
Expects that the first octet contain the opening tag.
|
||||||
|
Include a value property identifier for context specific data
|
||||||
|
such as the value received in a WriteProperty request */
|
||||||
|
int bacapp_data_len(uint8_t *apdu, int max_apdu_len,
|
||||||
|
BACNET_PROPERTY_ID property);
|
||||||
|
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
#define BACAPP_PRINT_ENABLED
|
#define BACAPP_PRINT_ENABLED
|
||||||
#else
|
#else
|
||||||
@@ -99,6 +114,7 @@ extern "C" {
|
|||||||
bool bacapp_same_value(BACNET_APPLICATION_DATA_VALUE * value,
|
bool bacapp_same_value(BACNET_APPLICATION_DATA_VALUE * value,
|
||||||
BACNET_APPLICATION_DATA_VALUE * test_value);
|
BACNET_APPLICATION_DATA_VALUE * test_value);
|
||||||
|
|
||||||
|
void testBACnetApplicationDataLength(Test * pTest);
|
||||||
void testBACnetApplicationData(Test * pTest);
|
void testBACnetApplicationData(Test * pTest);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -618,20 +618,18 @@ int decode_tag_number(uint8_t * apdu, uint8_t * tag_number)
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool decode_is_opening_tag(uint8_t * apdu)
|
bool decode_is_opening_tag(uint8_t * apdu)
|
||||||
{
|
{
|
||||||
return ((apdu[0] & 0x07) == 6);
|
return ((apdu[0] & 0x07) == 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* from clause 20.2.1.3.2 Constructed Data */
|
/* from clause 20.2.1.3.2 Constructed Data */
|
||||||
/* returns the number of apdu bytes consumed */
|
/* returns the number of apdu bytes consumed */
|
||||||
static bool decode_is_closing_tag(uint8_t * apdu)
|
bool decode_is_closing_tag(uint8_t * apdu)
|
||||||
{
|
{
|
||||||
return ((apdu[0] & 0x07) == 7);
|
return ((apdu[0] & 0x07) == 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* from clause 20.2.1.3.2 Constructed Data */
|
|
||||||
/* returns the number of apdu bytes consumed */
|
|
||||||
/* from clause 20.2.1.3.2 Constructed Data */
|
/* from clause 20.2.1.3.2 Constructed Data */
|
||||||
/* returns the number of apdu bytes consumed */
|
/* returns the number of apdu bytes consumed */
|
||||||
int decode_tag_number_and_value(uint8_t * apdu,
|
int decode_tag_number_and_value(uint8_t * apdu,
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ extern "C" {
|
|||||||
/* returns the number of apdu bytes consumed */
|
/* returns the number of apdu bytes consumed */
|
||||||
int encode_opening_tag(uint8_t * apdu, uint8_t tag_number);
|
int encode_opening_tag(uint8_t * apdu, uint8_t tag_number);
|
||||||
int encode_closing_tag(uint8_t * apdu, uint8_t tag_number);
|
int encode_closing_tag(uint8_t * apdu, uint8_t tag_number);
|
||||||
|
int decode_tag_number(uint8_t * apdu, uint8_t * tag_number);
|
||||||
int decode_tag_number_and_value(uint8_t * apdu, uint8_t * tag_number,
|
int decode_tag_number_and_value(uint8_t * apdu, uint8_t * tag_number,
|
||||||
uint32_t * value);
|
uint32_t * value);
|
||||||
/* returns true if the tag is context specific */
|
/* returns true if the tag is context specific */
|
||||||
@@ -63,6 +64,10 @@ extern "C" {
|
|||||||
bool decode_is_closing_tag_number(uint8_t * apdu, uint8_t tag_number);
|
bool decode_is_closing_tag_number(uint8_t * apdu, uint8_t tag_number);
|
||||||
/* returns true if the tag is context specific and matches */
|
/* returns true if the tag is context specific and matches */
|
||||||
bool decode_is_context_tag(uint8_t * apdu, uint8_t tag_number);
|
bool decode_is_context_tag(uint8_t * apdu, uint8_t tag_number);
|
||||||
|
/* returns true if the tag is an opening tag */
|
||||||
|
bool decode_is_opening_tag(uint8_t * apdu);
|
||||||
|
/* returns true if the tag is a closing tag */
|
||||||
|
bool decode_is_closing_tag(uint8_t * apdu);
|
||||||
|
|
||||||
/* from clause 20.2.2 Encoding of a Null Value */
|
/* from clause 20.2.2 Encoding of a Null Value */
|
||||||
int encode_tagged_null(uint8_t * apdu);
|
int encode_tagged_null(uint8_t * apdu);
|
||||||
|
|||||||
@@ -258,18 +258,13 @@ typedef enum {
|
|||||||
PROP_DUTY_WINDOW = 213,
|
PROP_DUTY_WINDOW = 213,
|
||||||
PROP_EXPECTED_SHED_LEVEL = 214,
|
PROP_EXPECTED_SHED_LEVEL = 214,
|
||||||
PROP_FULL_DUTY_BASELINE = 215,
|
PROP_FULL_DUTY_BASELINE = 215,
|
||||||
/* FIXME: is this the right enumeration? */
|
/* note: missing enumerations for now */
|
||||||
/* PROP_NODE_SUBTYPE = 216, */
|
|
||||||
/* PROP_NODE_TYPE = 217, */
|
|
||||||
PROP_REQUESTED_SHED_LEVEL = 218,
|
PROP_REQUESTED_SHED_LEVEL = 218,
|
||||||
PROP_SHED_DURATION = 219,
|
PROP_SHED_DURATION = 219,
|
||||||
PROP_SHED_LEVEL_DESCRIPTIONS = 220,
|
PROP_SHED_LEVEL_DESCRIPTIONS = 220,
|
||||||
PROP_SHED_LEVELS = 221,
|
PROP_SHED_LEVELS = 221,
|
||||||
PROP_STATE_DESCRIPTION = 222,
|
PROP_STATE_DESCRIPTION = 222,
|
||||||
/* FIXME: is this the right enumeration? */
|
/* note: missing enumerations for now */
|
||||||
/* PROP_STRUCTURED_OBJECT_LIST = 223, */
|
|
||||||
/* PROP_SUBORDINATE_ANNOTATIONS = 224, */
|
|
||||||
/* PROP_SUBORDINATE_LIST = 225, */
|
|
||||||
/* enumerations 226-235 are used in Addendum f to
|
/* enumerations 226-235 are used in Addendum f to
|
||||||
ANSI/ASHRAE 135-2004 */
|
ANSI/ASHRAE 135-2004 */
|
||||||
PROP_LOG_DEVICE_OBJECT_PROPERTIES = 236,
|
PROP_LOG_DEVICE_OBJECT_PROPERTIES = 236,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
|
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the
|
* a copy of this software and associated documentation files (the
|
||||||
|
|||||||
+7
-3
@@ -67,8 +67,9 @@ int wp_encode_apdu(uint8_t * apdu,
|
|||||||
/* propertyValue */
|
/* propertyValue */
|
||||||
len = encode_opening_tag(&apdu[apdu_len], 3);
|
len = encode_opening_tag(&apdu[apdu_len], 3);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
len =
|
for (len = 0; len < data->application_data_len; len++) {
|
||||||
bacapp_encode_application_data(&apdu[apdu_len], &data->value);
|
apdu[apdu_len++] = data->application_data[len];
|
||||||
|
}
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
len = encode_closing_tag(&apdu[apdu_len], 3);
|
len = encode_closing_tag(&apdu[apdu_len], 3);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
@@ -127,10 +128,13 @@ int wp_decode_service_request(uint8_t * apdu,
|
|||||||
return -1;
|
return -1;
|
||||||
/* a tag number of 3 is not extended so only one octet */
|
/* a tag number of 3 is not extended so only one octet */
|
||||||
len++;
|
len++;
|
||||||
|
/* determine the length of the data blob */
|
||||||
|
|
||||||
|
|
||||||
/* FIXME: decode the length of the context specific tag value */
|
/* FIXME: decode the length of the context specific tag value */
|
||||||
if (decode_is_context_specific(&apdu[len]))
|
if (decode_is_context_specific(&apdu[len]))
|
||||||
return -2;
|
return -2;
|
||||||
/* FIXME: what if the length is more than 255 */
|
/* FIXME: what if the length is more than 255 */
|
||||||
len += bacapp_decode_application_data(&apdu[len],
|
len += bacapp_decode_application_data(&apdu[len],
|
||||||
(uint8_t)(apdu_len - len), &data->value);
|
(uint8_t)(apdu_len - len), &data->value);
|
||||||
/* FIXME: check the return value; abort if no valid data? */
|
/* FIXME: check the return value; abort if no valid data? */
|
||||||
|
|||||||
+4
-2
@@ -41,13 +41,15 @@
|
|||||||
|
|
||||||
/* write property can have application tagged data, or context tagged data,
|
/* write property can have application tagged data, or context tagged data,
|
||||||
or even complex data types (i.e. opening and closing tag around data).
|
or even complex data types (i.e. opening and closing tag around data).
|
||||||
It could also have more than one value. */
|
It could also have more than one value or element. */
|
||||||
|
|
||||||
typedef struct BACnet_Write_Property_Data {
|
typedef struct BACnet_Write_Property_Data {
|
||||||
BACNET_OBJECT_TYPE object_type;
|
BACNET_OBJECT_TYPE object_type;
|
||||||
uint32_t object_instance;
|
uint32_t object_instance;
|
||||||
BACNET_PROPERTY_ID object_property;
|
BACNET_PROPERTY_ID object_property;
|
||||||
int32_t array_index; /* use BACNET_ARRAY_ALL when not setting */
|
int32_t array_index; /* use BACNET_ARRAY_ALL when not setting */
|
||||||
BACNET_APPLICATION_DATA_VALUE value;
|
uint8_t *application_data;
|
||||||
|
int application_data_len;
|
||||||
uint8_t priority; /* use BACNET_NO_PRIORITY if no priority */
|
uint8_t priority; /* use BACNET_NO_PRIORITY if no priority */
|
||||||
} BACNET_WRITE_PROPERTY_DATA;
|
} BACNET_WRITE_PROPERTY_DATA;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user