Added new functions for handling opening/closing tags. Corrected encode of unsigned.
This commit is contained in:
+104
-3
@@ -47,6 +47,81 @@
|
|||||||
// NOTE: byte order plays a role in decoding multibyte values
|
// NOTE: byte order plays a role in decoding multibyte values
|
||||||
// http://www.unixpapa.com/incnote/byteorder.html
|
// http://www.unixpapa.com/incnote/byteorder.html
|
||||||
|
|
||||||
|
/* max-segments-accepted
|
||||||
|
B'000' Unspecified number of segments accepted.
|
||||||
|
B'001' 2 segments accepted.
|
||||||
|
B'010' 4 segments accepted.
|
||||||
|
B'011' 8 segments accepted.
|
||||||
|
B'100' 16 segments accepted.
|
||||||
|
B'101' 32 segments accepted.
|
||||||
|
B'110' 64 segments accepted.
|
||||||
|
B'111' Greater than 64 segments accepted.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* max-APDU-length-accepted
|
||||||
|
B'0000' Up to MinimumMessageSize (50 octets)
|
||||||
|
B'0001' Up to 128 octets
|
||||||
|
B'0010' Up to 206 octets (fits in a LonTalk frame)
|
||||||
|
B'0011' Up to 480 octets (fits in an ARCNET frame)
|
||||||
|
B'0100' Up to 1024 octets
|
||||||
|
B'0101' Up to 1476 octets (fits in an ISO 8802-3 frame)
|
||||||
|
B'0110' reserved by ASHRAE
|
||||||
|
B'0111' reserved by ASHRAE
|
||||||
|
B'1000' reserved by ASHRAE
|
||||||
|
B'1001' reserved by ASHRAE
|
||||||
|
B'1010' reserved by ASHRAE
|
||||||
|
B'1011' reserved by ASHRAE
|
||||||
|
B'1100' reserved by ASHRAE
|
||||||
|
B'1101' reserved by ASHRAE
|
||||||
|
B'1110' reserved by ASHRAE
|
||||||
|
B'1111' reserved by ASHRAE
|
||||||
|
*/
|
||||||
|
// from clause 20.1.2.4 max-segments-accepted
|
||||||
|
// and clause 20.1.2.5 max-APDU-length-accepted
|
||||||
|
// returns the encoded octet
|
||||||
|
uint8_t encode_max_segs_max_apdu(int max_segs, int max_apdu)
|
||||||
|
{
|
||||||
|
uint8_t octet = 0;
|
||||||
|
|
||||||
|
if (max_segs < 2)
|
||||||
|
octet = 0;
|
||||||
|
else if (max_segs < 4)
|
||||||
|
octet = 0x10;
|
||||||
|
else if (max_segs < 8)
|
||||||
|
octet = 0x20;
|
||||||
|
else if (max_segs < 16)
|
||||||
|
octet = 0x30;
|
||||||
|
else if (max_segs < 32)
|
||||||
|
octet = 0x40;
|
||||||
|
else if (max_segs < 64)
|
||||||
|
octet = 0x50;
|
||||||
|
else if (max_segs == 64)
|
||||||
|
octet = 0x60;
|
||||||
|
else
|
||||||
|
octet = 0x70;
|
||||||
|
|
||||||
|
// max_apdu must be 50 octets minimum
|
||||||
|
assert(max_apdu >= 50);
|
||||||
|
if (max_apdu == 50)
|
||||||
|
octet |= 0x00;
|
||||||
|
else if (max_apdu <= 128)
|
||||||
|
octet |= 0x01;
|
||||||
|
//fits in a LonTalk frame
|
||||||
|
else if (max_apdu <= 206)
|
||||||
|
octet |= 0x02;
|
||||||
|
//fits in an ARCNET or MS/TP frame
|
||||||
|
else if (max_apdu <= 480)
|
||||||
|
octet |= 0x03;
|
||||||
|
else if (max_apdu <= 1024)
|
||||||
|
octet |= 0x04;
|
||||||
|
// fits in an ISO 8802-3 frame
|
||||||
|
else if (max_apdu <= 1476)
|
||||||
|
octet |= 0x05;
|
||||||
|
|
||||||
|
return octet;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// from clause 20.2.1 General Rules for Encoding BACnet Tags
|
// from clause 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_tag(uint8_t * apdu, uint8_t tag_number, bool context_specific,
|
int encode_tag(uint8_t * apdu, uint8_t tag_number, bool context_specific,
|
||||||
@@ -188,14 +263,14 @@ bool decode_is_context_specific(uint8_t * apdu)
|
|||||||
|
|
||||||
// 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
|
||||||
bool decode_is_opening_tag(uint8_t * apdu)
|
static 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
|
||||||
bool decode_is_closing_tag(uint8_t * apdu)
|
static bool decode_is_closing_tag(uint8_t * apdu)
|
||||||
{
|
{
|
||||||
return ((apdu[0] & 0x07) == 7);
|
return ((apdu[0] & 0x07) == 7);
|
||||||
}
|
}
|
||||||
@@ -306,6 +381,32 @@ bool decode_is_context_tag(uint8_t * apdu, uint8_t tag_number)
|
|||||||
return (context_specific && (my_tag_number == tag_number));
|
return (context_specific && (my_tag_number == tag_number));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// from clause 20.2.1.3.2 Constructed Data
|
||||||
|
// returns the true if the tag is an opening tag and the tag number matches
|
||||||
|
bool decode_is_opening_tag_number(uint8_t * apdu, uint8_t tag_number)
|
||||||
|
{
|
||||||
|
uint8_t my_tag_number = 0;
|
||||||
|
bool opening_tag = false;
|
||||||
|
|
||||||
|
opening_tag = decode_is_opening_tag(apdu);
|
||||||
|
decode_tag_number(apdu,&my_tag_number);
|
||||||
|
|
||||||
|
return (opening_tag && (my_tag_number == tag_number));
|
||||||
|
}
|
||||||
|
|
||||||
|
// from clause 20.2.1.3.2 Constructed Data
|
||||||
|
// returns the true if the tag is a closing tag and the tag number matches
|
||||||
|
bool decode_is_closing_tag_number(uint8_t * apdu, uint8_t tag_number)
|
||||||
|
{
|
||||||
|
uint8_t my_tag_number = 0;
|
||||||
|
bool closing_tag = false;
|
||||||
|
|
||||||
|
closing_tag = decode_is_closing_tag(apdu);
|
||||||
|
decode_tag_number(apdu,&my_tag_number);
|
||||||
|
|
||||||
|
return (closing_tag && (my_tag_number == tag_number));
|
||||||
|
}
|
||||||
|
|
||||||
// from clause 20.2.6 Encoding of a Real Number Value
|
// from clause 20.2.6 Encoding of a Real Number Value
|
||||||
// returns the number of apdu bytes consumed
|
// returns the number of apdu bytes consumed
|
||||||
int decode_real(uint8_t * apdu, float *real_value)
|
int decode_real(uint8_t * apdu, float *real_value)
|
||||||
@@ -572,7 +673,7 @@ int encode_context_unsigned(uint8_t * apdu, int tag_number, int value)
|
|||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
len = encode_bacnet_unsigned(&apdu[1], value);
|
len = encode_bacnet_unsigned(&apdu[1], value);
|
||||||
len = encode_tag(&apdu[0], tag_number, true, len);
|
len += encode_tag(&apdu[0], tag_number, true, len);
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,11 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
// from clause 20.1.2.4 max-segments-accepted
|
||||||
|
// and clause 20.1.2.5 max-APDU-length-accepted
|
||||||
|
// returns the encoded octet
|
||||||
|
uint8_t encode_max_segs_max_apdu(int max_segs, int max_apdu);
|
||||||
|
|
||||||
// from clause 20.2.1 General Rules for Encoding BACnet Tags
|
// from clause 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_tag(uint8_t * apdu, uint8_t tag_number, bool context_specific,
|
int encode_tag(uint8_t * apdu, uint8_t tag_number, bool context_specific,
|
||||||
@@ -50,12 +55,12 @@ 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
|
||||||
bool decode_is_context_specific(uint8_t * apdu);
|
bool decode_is_context_specific(uint8_t * apdu);
|
||||||
// returns true if the tag is an opening tag
|
|
||||||
bool decode_is_opening_tag(uint8_t * apdu);
|
|
||||||
// returns true if the tag is an closing tag
|
|
||||||
bool decode_is_closing_tag(uint8_t * apdu);
|
|
||||||
// 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 the true if the tag is an opening tag and the tag number matches
|
||||||
|
bool decode_is_opening_tag_number(uint8_t * apdu, uint8_t tag_number);
|
||||||
|
// returns the true if the tag is a closing tag and the tag number matches
|
||||||
|
bool decode_is_closing_tag_number(uint8_t * apdu, uint8_t tag_number);
|
||||||
|
|
||||||
// from clause 20.2.6 Encoding of a Real Number Value
|
// from clause 20.2.6 Encoding of a Real Number Value
|
||||||
// and 20.2.1 General Rules for Encoding BACnet Tags
|
// and 20.2.1 General Rules for Encoding BACnet Tags
|
||||||
|
|||||||
Reference in New Issue
Block a user