-context specific decoders for all of the primitive times to go with the context specific encoders
-unconfirmed/confirmed EventNotificationRequest structure/encoder/decoder
-BACnetTimestamp structure/encoder/decoder
-BACnetPropertyStates structure/encoder/decoder
-BACnetDeviceObjectPropertyReference structure/encoder/decoder

Changes:
-decode_context_object_id::object_type changed to uint16_t
-explicit casts have been added to some functions to remove compiler warnings
-encode_bacnet_date::year behaviour has been changed slightly
This commit is contained in:
minack
2008-10-14 04:02:34 +00:00
parent 1dad528da8
commit 60ac0d0f8a
16 changed files with 3593 additions and 33 deletions
+711 -25
View File
@@ -71,6 +71,24 @@
B'1110' reserved by ASHRAE
B'1111' reserved by ASHRAE
*/
/* Encoding of BACNET Length/Value/Type tag
From clause 20.2.1.3.1
B'000' interpreted as Value = FALSE if application class == BOOLEAN
B'001' interpreted as Value = TRUE if application class == BOOLEAN
B'000' interpreted as Length = 0 if application class != BOOLEAN
B'001' interpreted as Length = 1
B'010' interpreted as Length = 2
B'011' interpreted as Length = 3
B'100' interpreted as Length = 4
B'101' interpreted as Length > 4
B'110' interpreted as Type = Opening Tag
B'111' interpreted as Type = Closing Tag
*/
/* from clause 20.1.2.4 max-segments-accepted */
/* and clause 20.1.2.5 max-APDU-length-accepted */
/* returns the encoded octet */
@@ -285,7 +303,7 @@ int encode_closing_tag(
static bool decode_is_extended_tag_number(
uint8_t * apdu)
{
return ((apdu[0] & 0xF0) == 0xF0);
return (bool)((apdu[0] & 0xF0) == 0xF0);
}
/* from clause 20.2.1.3.2 Constructed Data */
@@ -293,7 +311,7 @@ static bool decode_is_extended_tag_number(
static bool decode_is_extended_value(
uint8_t * apdu)
{
return ((apdu[0] & 0x07) == 5);
return (bool)((apdu[0] & 0x07) == 5);
}
/* from clause 20.2.1.3.2 Constructed Data */
@@ -301,7 +319,7 @@ static bool decode_is_extended_value(
bool decode_is_context_specific(
uint8_t * apdu)
{
return ((apdu[0] & BIT3) == BIT3);
return (bool)((apdu[0] & BIT3) == BIT3);
}
int decode_tag_number(
@@ -319,7 +337,7 @@ int decode_tag_number(
len++;
} else {
if (tag_number) {
*tag_number = (apdu[0] >> 4);
*tag_number = (uint8_t)(apdu[0] >> 4);
}
}
@@ -329,7 +347,7 @@ int decode_tag_number(
bool decode_is_opening_tag(
uint8_t * apdu)
{
return ((apdu[0] & 0x07) == 6);
return (bool)((apdu[0] & 0x07) == 6);
}
/* from clause 20.2.1.3.2 Constructed Data */
@@ -337,7 +355,7 @@ bool decode_is_opening_tag(
bool decode_is_closing_tag(
uint8_t * apdu)
{
return ((apdu[0] & 0x07) == 7);
return (bool)((apdu[0] & 0x07) == 7);
}
/* from clause 20.2.1.3.2 Constructed Data */
@@ -398,10 +416,26 @@ bool decode_is_context_tag(
uint8_t my_tag_number = 0;
bool context_specific = false;
context_specific = decode_is_context_specific(apdu);
decode_tag_number(apdu, &my_tag_number);
return (context_specific && (my_tag_number == tag_number));
return (bool)(context_specific && (my_tag_number == tag_number));
}
bool decode_is_context_tag_with_length(
uint8_t * apdu,
uint8_t tag_number,
int * tag_length)
{
uint8_t my_tag_number = 0;
bool context_specific = false;
context_specific = decode_is_context_specific(apdu);
*tag_length = decode_tag_number(apdu, &my_tag_number);
return (bool)(context_specific && (my_tag_number == tag_number));
}
/* from clause 20.2.1.3.2 Constructed Data */
@@ -413,10 +447,10 @@ bool decode_is_opening_tag_number(
uint8_t my_tag_number = 0;
bool opening_tag = false;
opening_tag = ((apdu[0] & 0x07) == 6);
opening_tag = (bool)((apdu[0] & 0x07) == 6);
decode_tag_number(apdu, &my_tag_number);
return (opening_tag && (my_tag_number == tag_number));
return (bool)(opening_tag && (my_tag_number == tag_number));
}
/* from clause 20.2.1.3.2 Constructed Data */
@@ -428,10 +462,10 @@ bool decode_is_closing_tag_number(
uint8_t my_tag_number = 0;
bool closing_tag = false;
closing_tag = ((apdu[0] & 0x07) == 7);
closing_tag = (bool)((apdu[0] & 0x07) == 7);
decode_tag_number(apdu, &my_tag_number);
return (closing_tag && (my_tag_number == tag_number));
return (bool)(closing_tag && (my_tag_number == tag_number));
}
/* from clause 20.2.3 Encoding of a Boolean Value */
@@ -456,13 +490,13 @@ int encode_application_boolean(
/* context tagged is encoded differently */
int encode_context_boolean(
uint8_t * apdu,
int tag_number,
uint8_t tag_number,
bool boolean_value)
{
int len = 0; /* return value */
len = encode_tag(&apdu[0], (uint8_t) tag_number, true, 1);
apdu[len] = boolean_value ? 1 : 0;
apdu[len] = (bool)(boolean_value ? 1 : 0);
len++;
return len;
@@ -480,6 +514,29 @@ bool decode_context_boolean(
return boolean_value;
}
int decode_context_boolean2(
uint8_t * apdu,
uint8_t tag_number,
bool *boolean_value)
{
int len = 0;
if (decode_is_context_tag_with_length(&apdu[len], tag_number, &len)) {
if (apdu[len]) {
*boolean_value = true;
}
else
{
*boolean_value = false;
}
len++;
}
else
{
len = -1;
}
return len;
}
/* from clause 20.2.3 Encoding of a Boolean Value */
/* and 20.2.1 General Rules for Encoding BACnet Tags */
/* returns the number of apdu bytes consumed */
@@ -567,7 +624,7 @@ int decode_bitstring(
bitstring_set_octet(bit_string, (uint8_t) i,
byte_reverse_bits(apdu[len++]));
}
unused_bits = apdu[0] & 0x07;
unused_bits = (uint8_t)(apdu[0] & 0x07);
bitstring_set_bits_used(bit_string, (uint8_t) bytes_used,
unused_bits);
}
@@ -576,6 +633,27 @@ int decode_bitstring(
return len;
}
int decode_context_bitstring(
uint8_t * apdu,
uint8_t tag_number,
BACNET_BIT_STRING * bit_string)
{
uint32_t len_value;
int len = 0;
if (decode_is_context_tag(&apdu[len], tag_number)) {
len += decode_tag_number_and_value(&apdu[len], &tag_number,
&len_value);
len += decode_bitstring(&apdu[len], len_value, bit_string);
}
else
{
len = -1;
}
return len;
}
/* from clause 20.2.10 Encoding of a Bit String Value */
/* returns the number of apdu bytes consumed */
int encode_bitstring(
@@ -593,9 +671,9 @@ int encode_bitstring(
} else {
used_bytes = bitstring_bytes_used(bit_string);
remaining_used_bits =
bitstring_bits_used(bit_string) - ((used_bytes - 1) * 8);
(uint8_t)(bitstring_bits_used(bit_string) - ((used_bytes - 1) * 8));
/* number of unused bits in the subsequent final octet */
apdu[len++] = 8 - remaining_used_bits;
apdu[len++] = (uint8_t)(8 - remaining_used_bits);
for (i = 0; i < used_bytes; i++) {
apdu[len++] = byte_reverse_bits(bitstring_octet(bit_string, i));
}
@@ -650,12 +728,30 @@ int decode_object_id(
int len = 0;
len = decode_unsigned32(apdu, &value);
*object_type = ((value >> BACNET_INSTANCE_BITS) & BACNET_MAX_OBJECT);
*object_type = (uint16_t)(((value >> BACNET_INSTANCE_BITS) & BACNET_MAX_OBJECT));
*instance = (value & BACNET_MAX_INSTANCE);
return len;
}
int decode_context_object_id(
uint8_t * apdu,
uint8_t tag_number,
uint16_t * object_type,
uint32_t * instance)
{
int len = 0;
if (decode_is_context_tag_with_length(&apdu[len], tag_number, &len)) {
len += decode_object_id(&apdu[len], object_type, instance);
}
else
{
len = -1;
}
return len;
}
/* from clause 20.2.14 Encoding of an Object Identifier Value */
/* returns the number of apdu bytes consumed */
int encode_bacnet_object_id(
@@ -807,6 +903,34 @@ int decode_octet_string(
return len;
}
int decode_context_octet_string(
uint8_t * apdu,
uint8_t tag_number,
BACNET_OCTET_STRING * octet_string)
{
int len = 0; /* return value */
bool status = false;
uint32_t len_value = 0;
if (decode_is_context_tag(&apdu[len], tag_number))
{
len += decode_tag_number_and_value(&apdu[len], &tag_number,
&len_value);
status = octetstring_init(octet_string, &apdu[len], len_value);
if (status) {
len += len_value;
}
}
else
{
len = -1;
}
return len;
}
/* from clause 20.2.9 Encoding of a Character String Value */
/* returns the number of apdu bytes consumed */
int encode_bacnet_character_string(
@@ -889,6 +1013,35 @@ int decode_character_string(
return len;
}
int decode_context_character_string(
uint8_t * apdu,
uint8_t tag_number,
BACNET_CHARACTER_STRING * char_string)
{
int len = 0; /* return value */
bool status = false;
uint32_t len_value = 0;
if (decode_is_context_tag(&apdu[len], tag_number))
{
len += decode_tag_number_and_value(&apdu[len], &tag_number,
&len_value);
status =
characterstring_init(char_string, apdu[len], (char *) &apdu[len+1],
len_value - 1);
if (status) {
len += len_value;
}
}
else
{
len = -1;
}
return len;
}
/* from clause 20.2.4 Encoding of an Unsigned Integer Value */
/* and 20.2.1 General Rules for Encoding BACnet Tags */
/* returns the number of apdu bytes consumed */
@@ -923,6 +1076,27 @@ int decode_unsigned(
return len_value;
}
int decode_context_unsigned(
uint8_t * apdu,
uint8_t tag_number,
uint32_t * value)
{
uint32_t len_value;
int len = 0;
if (decode_is_context_tag(&apdu[len], tag_number)) {
len += decode_tag_number_and_value(&apdu[len], &tag_number,
&len_value);
len += decode_unsigned(&apdu[len], len_value, value);
}
else
{
len = -1;
}
return len;
}
/* from clause 20.2.4 Encoding of an Unsigned Integer Value */
/* and 20.2.1 General Rules for Encoding BACnet Tags */
/* returns the number of apdu bytes consumed */
@@ -1002,6 +1176,27 @@ int decode_enumerated(
return len;
}
int decode_context_enumerated(
uint8_t * apdu,
uint8_t tag_value,
int *value)
{
int len = 0;
uint8_t tag_number;
uint32_t len_value;
if (decode_is_context_tag(&apdu[len], tag_value)) {
len += decode_tag_number_and_value(&apdu[len], &tag_number,
&len_value);
len += decode_enumerated(&apdu[len], len_value, value);
}
else
{
len = -1;
}
return len;
}
/* from clause 20.2.11 Encoding of an Enumerated Value */
/* and 20.2.1 General Rules for Encoding BACnet Tags */
/* returns the number of apdu bytes consumed */
@@ -1081,6 +1276,26 @@ int decode_signed(
return len_value;
}
int decode_context_signed(
uint8_t * apdu,
uint8_t tag_number,
int32_t * value)
{
uint32_t len_value;
int len = 0;
if (decode_is_context_tag(&apdu[len], tag_number)) {
len += decode_tag_number_and_value(&apdu[len], &tag_number,
&len_value);
len += decode_signed(&apdu[len], len_value, value);
}
else
{
len = -1;
}
return len;
}
/* from clause 20.2.5 Encoding of a Signed Integer Value */
/* and 20.2.1 General Rules for Encoding BACnet Tags */
/* returns the number of apdu bytes consumed */
@@ -1281,6 +1496,45 @@ int decode_bacnet_time(
return 4;
}
int decode_application_time(
uint8_t * apdu,
BACNET_TIME * btime)
{
int len = 0;
uint8_t tag_number;
decode_tag_number(&apdu[len], &tag_number);
if ( tag_number == BACNET_APPLICATION_TAG_TIME )
{
len++;
len += decode_bacnet_time(&apdu[len], btime);
}
else
{
len = -1;
}
return len;
}
int decode_context_bacnet_time(
uint8_t * apdu,
uint8_t tag_number,
BACNET_TIME * btime)
{
int len = 0;
if (decode_is_context_tag_with_length(&apdu[len], tag_number, &len)) {
len += decode_bacnet_time(&apdu[len], btime);
}
else
{
len = -1;
}
return len;
}
/* BACnet Date */
/* year = years since 1900 */
/* month 1=Jan */
@@ -1295,14 +1549,23 @@ int encode_bacnet_date(
BACNET_DATE * bdate)
{
/* allow 2 digit years */
if (bdate->year < 1900) {
if (bdate->year <= 38) {
bdate->year += 2000;
} else {
bdate->year += 1900;
}
if (bdate->year >= 1900) {
apdu[0] = (uint8_t)(bdate->year - 1900);
}
apdu[0] = bdate->year - 1900;
else if ( bdate->year < 0x100 )
{
apdu[0] = (uint8_t)bdate->year;
}
else
{
/*
** Don't try and guess what the user meant here. Just fail
*/
return -1;
}
apdu[1] = bdate->month;
apdu[2] = bdate->day;
apdu[3] = bdate->wday;
@@ -1310,6 +1573,7 @@ int encode_bacnet_date(
return 4;
}
/* from clause 20.2.12 Encoding of a Date Value */
/* and 20.2.1 General Rules for Encoding BACnet Tags */
/* returns the number of apdu bytes consumed */
@@ -1353,7 +1617,7 @@ int decode_date(
uint8_t * apdu,
BACNET_DATE * bdate)
{
bdate->year = apdu[0] + 1900;
bdate->year = (uint16_t)(apdu[0] + 1900);
bdate->month = apdu[1];
bdate->day = apdu[2];
bdate->wday = apdu[3];
@@ -1361,6 +1625,45 @@ int decode_date(
return 4;
}
int decode_application_date(
uint8_t * apdu,
BACNET_DATE * bdate)
{
int len = 0;
uint8_t tag_number;
decode_tag_number(&apdu[len], &tag_number);
if ( tag_number == BACNET_APPLICATION_TAG_DATE )
{
len++;
len += decode_date(&apdu[len], bdate);
}
else
{
len = -1;
}
return len;
}
int decode_context_date(
uint8_t * apdu,
uint8_t tag_number,
BACNET_DATE * bdate)
{
int len = 0;
if (decode_is_context_tag_with_length(&apdu[len], tag_number, &len)) {
len += decode_date(&apdu[len], bdate);
}
else
{
len = -1;
}
return len;
}
/* returns the number of apdu bytes consumed */
int encode_simple_ack(
uint8_t * apdu,
@@ -1990,6 +2293,358 @@ void testBACDCodeBitString(
}
}
void testUnsignedContextDecodes(Test * pTest)
{
uint8_t apdu[MAX_APDU];
int inLen;
int outLen;
int outLen2;
/* 32 bit number */
uint32_t in = 0xdeadbeef;
uint32_t out;
outLen2 = decode_context_unsigned(apdu, 9, &out);
in = 0xdeadbeef;
inLen = encode_context_unsigned(apdu, 10, in);
outLen = decode_context_unsigned(apdu, 10, &out);
ct_test(pTest, inLen == outLen);
ct_test(pTest, in == out);
ct_test(pTest, outLen2 == -1);
/* 16 bit number */
in = 0xdead;
inLen = encode_context_unsigned(apdu, 10, in);
outLen = decode_context_unsigned(apdu, 10, &out);
ct_test(pTest, inLen == outLen);
ct_test(pTest, in == out);
/* 8 bit number */
in = 0xde;
inLen = encode_context_unsigned(apdu, 10, in);
outLen = decode_context_unsigned(apdu, 10, &out);
ct_test(pTest, inLen == outLen);
ct_test(pTest, in == out);
/* 4 bit number */
in = 0xd;
inLen = encode_context_unsigned(apdu, 10, in);
outLen = decode_context_unsigned(apdu, 10, &out);
ct_test(pTest, inLen == outLen);
ct_test(pTest, in == out);
/* 2 bit number */
in = 0x2;
inLen = encode_context_unsigned(apdu, 10, in);
outLen = decode_context_unsigned(apdu, 10, &out);
ct_test(pTest, inLen == outLen);
ct_test(pTest, in == out);
}
void testSignedContextDecodes(Test * pTest)
{
uint8_t apdu[MAX_APDU];
int inLen;
int outLen;
int outLen2;
/* 32 bit number */
int32_t in = 0xdeadbeef;
int32_t out;
outLen2 = decode_context_signed(apdu, 9, &out);
in = 0xdeadbeef;
inLen = encode_context_signed(apdu, 10, in);
outLen = decode_context_signed(apdu, 10, &out);
ct_test(pTest, inLen == outLen);
ct_test(pTest, in == out);
ct_test(pTest, outLen2 == -1);
/* 16 bit number */
in = 0xdead;
inLen = encode_context_signed(apdu, 10, in);
outLen = decode_context_signed(apdu, 10, &out);
ct_test(pTest, inLen == outLen);
ct_test(pTest, in == out);
/* 8 bit number */
in = 0xde;
inLen = encode_context_signed(apdu, 10, in);
outLen = decode_context_signed(apdu, 10, &out);
ct_test(pTest, inLen == outLen);
ct_test(pTest, in == out);
/* 4 bit number */
in = 0xd;
inLen = encode_context_signed(apdu, 10, in);
outLen = decode_context_signed(apdu, 10, &out);
ct_test(pTest, inLen == outLen);
ct_test(pTest, in == out);
/* 2 bit number */
in = 0x2;
inLen = encode_context_signed(apdu, 10, in);
outLen = decode_context_signed(apdu, 10, &out);
ct_test(pTest, inLen == outLen);
ct_test(pTest, in == out);
}
void testEnumeratedContextDecodes(Test * pTest)
{
uint8_t apdu[MAX_APDU];
int inLen;
int outLen;
int outLen2;
/* 32 bit number */
int32_t in = 0xdeadbeef;
int32_t out;
outLen2 = decode_context_enumerated(apdu, 9, &out);
in = 0xdeadbeef;
inLen = encode_context_enumerated(apdu, 10, in);
outLen = decode_context_enumerated(apdu, 10, &out);
ct_test(pTest, inLen == outLen);
ct_test(pTest, in == out);
ct_test(pTest, outLen2 == -1);
/* 16 bit number */
in = 0xdead;
inLen = encode_context_enumerated(apdu, 10, in);
outLen = decode_context_enumerated(apdu, 10, &out);
ct_test(pTest, inLen == outLen);
ct_test(pTest, in == out);
/* 8 bit number */
in = 0xde;
inLen = encode_context_enumerated(apdu, 10, in);
outLen = decode_context_enumerated(apdu, 10, &out);
ct_test(pTest, inLen == outLen);
ct_test(pTest, in == out);
/* 4 bit number */
in = 0xd;
inLen = encode_context_enumerated(apdu, 10, in);
outLen = decode_context_enumerated(apdu, 10, &out);
ct_test(pTest, inLen == outLen);
ct_test(pTest, in == out);
/* 2 bit number */
in = 0x2;
inLen = encode_context_enumerated(apdu, 10, in);
outLen = decode_context_enumerated(apdu, 10, &out);
ct_test(pTest, inLen == outLen);
ct_test(pTest, in == out);
}
void testFloatContextDecodes(Test * pTest)
{
uint8_t apdu[MAX_APDU];
int inLen;
int outLen;
int outLen2;
/* 32 bit number */
float in;
float out;
in = 0.1234f;
inLen = encode_context_real(apdu, 10, in);
outLen = decode_context_real(apdu, 10, &out);
outLen2 = decode_context_real(apdu, 9, &out);
ct_test(pTest, inLen == outLen);
ct_test(pTest, in == out);
ct_test(pTest, outLen2 == -1);
in = 0.0f;
inLen = encode_context_real(apdu, 10, in);
outLen = decode_context_real(apdu, 10, &out);
outLen2 = decode_context_real(apdu, 9, &out);
ct_test(pTest, inLen == outLen);
ct_test(pTest, in == out);
}
void testObjectIDContextDecodes(Test * pTest)
{
uint8_t apdu[MAX_APDU];
int inLen;
int outLen;
int outLen2;
/* 32 bit number */
uint16_t in_type;
uint32_t in_id;
uint16_t out_type;
uint32_t out_id;
in_type = 0xde;
in_id = 0xbeef;
inLen = encode_context_object_id(apdu, 10, in_type, in_id);
outLen = decode_context_object_id(apdu, 10, &out_type, &out_id);
outLen2 = decode_context_object_id(apdu, 9, &out_type, &out_id);
ct_test(pTest, inLen == outLen);
ct_test(pTest, in_type == out_type);
ct_test(pTest, in_id == out_id);
ct_test(pTest, outLen2 == -1);
}
void testCharacterStringContextDecodes(Test * pTest)
{
uint8_t apdu[MAX_APDU];
int inLen;
int outLen;
int outLen2;
BACNET_CHARACTER_STRING in;
BACNET_CHARACTER_STRING out;
characterstring_init_ansi(&in, "This is a test");
inLen = encode_context_character_string(apdu, 10, &in);
outLen= decode_context_character_string(apdu, 10, &out);
outLen2= decode_context_character_string(apdu, 9, &out);
ct_test(pTest, outLen2 == -1);
ct_test(pTest, inLen == outLen);
ct_test(pTest, in.length == out.length);
ct_test(pTest, in.encoding == out.encoding);
ct_test(pTest, strcmp(in.value, out.value) == 0);
}
void testBitStringContextDecodes(Test * pTest)
{
uint8_t apdu[MAX_APDU];
int inLen;
int outLen;
int outLen2;
BACNET_BIT_STRING in;
BACNET_BIT_STRING out;
bitstring_init(&in);
bitstring_set_bit(&in, 1, true);
bitstring_set_bit(&in, 3, true);
bitstring_set_bit(&in, 6, true);
bitstring_set_bit(&in, 10, false);
bitstring_set_bit(&in, 11, true);
bitstring_set_bit(&in, 12, false);
inLen = encode_context_bitstring(apdu, 10, &in);
outLen= decode_context_bitstring(apdu, 10, &out);
outLen2= decode_context_bitstring(apdu, 9, &out);
ct_test(pTest, outLen2 == -1);
ct_test(pTest, inLen == outLen);
ct_test(pTest, in.bits_used == out.bits_used);
ct_test(pTest, memcmp(in.value, out.value, MAX_BITSTRING_BYTES) == 0);
}
void testOctetStringContextDecodes(Test * pTest)
{
uint8_t apdu[MAX_APDU];
int inLen;
int outLen;
int outLen2;
BACNET_OCTET_STRING in;
BACNET_OCTET_STRING out;
uint8_t initData[] = {0xde,0xad,0xbe,0xef};
octetstring_init(&in, initData, sizeof(initData));
inLen = encode_context_octet_string(apdu, 10, &in);
outLen= decode_context_octet_string(apdu, 10, &out);
outLen2= decode_context_octet_string(apdu, 9, &out);
ct_test(pTest, outLen2 == -1);
ct_test(pTest, inLen == outLen);
ct_test(pTest, in.length == out.length);
ct_test(pTest, memcmp(in.value, out.value, MAX_APDU - 6) == 0);
}
void testTimeContextDecodes(Test * pTest)
{
uint8_t apdu[MAX_APDU];
int inLen;
int outLen;
int outLen2;
BACNET_TIME in;
BACNET_TIME out;
in.hour = 10;
in.hundredths = 20;
in.min = 30;
in.sec = 40;
inLen = encode_context_time(apdu, 10, &in);
outLen= decode_context_bacnet_time(apdu, 10, &out);
outLen2= decode_context_bacnet_time(apdu, 9, &out);
ct_test(pTest, outLen2 == -1);
ct_test(pTest, inLen == outLen);
ct_test(pTest, in.hour == out.hour);
ct_test(pTest, in.hundredths == out.hundredths);
ct_test(pTest, in.min == out.min);
ct_test(pTest, in.sec == out.sec);
}
void testDateContextDecodes(Test * pTest)
{
uint8_t apdu[MAX_APDU];
int inLen;
int outLen;
int outLen2;
BACNET_DATE in;
BACNET_DATE out;
in.day = 3;
in.month = 10;
in.wday = 5;
in.year = 1945;
inLen = encode_context_date(apdu, 10, &in);
outLen= decode_context_date(apdu, 10, &out);
outLen2= decode_context_date(apdu, 9, &out);
ct_test(pTest, outLen2 == -1);
ct_test(pTest, inLen == outLen);
ct_test(pTest, in.day == out.day);
ct_test(pTest, in.month == out.month);
ct_test(pTest, in.wday == out.wday);
ct_test(pTest, in.year == out.year);
}
#ifdef TEST_DECODE
int main(
void)
@@ -2023,6 +2678,37 @@ int main(
assert(rc);
rc = ct_addTestFunction(pTest, testBACDCodeBitString);
assert(rc);
rc = ct_addTestFunction(pTest, testUnsignedContextDecodes);
assert(rc);
rc = ct_addTestFunction(pTest, testSignedContextDecodes);
assert(rc);
rc = ct_addTestFunction(pTest, testEnumeratedContextDecodes);
assert(rc);
rc = ct_addTestFunction(pTest, testCharacterStringContextDecodes);
assert(rc);
rc = ct_addTestFunction(pTest, testFloatContextDecodes);
assert(rc);
rc = ct_addTestFunction(pTest, testObjectIDContextDecodes);
assert(rc);
rc = ct_addTestFunction(pTest, testBitStringContextDecodes);
assert(rc);
rc = ct_addTestFunction(pTest, testTimeContextDecodes);
assert(rc);
rc = ct_addTestFunction(pTest, testDateContextDecodes);
assert(rc);
rc = ct_addTestFunction(pTest, testOctetStringContextDecodes);
assert(rc);
/* configure output */
ct_setStream(pTest, stdout);
ct_run(pTest);