Moved the max seg and max apdu encode from npdu. Created decode and unit tests.

This commit is contained in:
skarg
2005-03-17 19:16:08 +00:00
parent 167c54a72d
commit e96a9f7aa1
3 changed files with 128 additions and 71 deletions
+94
View File
@@ -118,6 +118,77 @@ uint8_t encode_max_segs_max_apdu(int max_segs, int max_apdu)
return octet;
}
// from clause 20.1.2.4 max-segments-accepted
// and clause 20.1.2.5 max-APDU-length-accepted
// returns the encoded octet
int decode_max_segs(uint8_t octet)
{
int max_segs = 0;
switch (octet & 0xF0)
{
case 0:
max_segs = 0;
break;
case 0x10:
max_segs = 2;
break;
case 0x20:
max_segs = 4;
break;
case 0x30:
max_segs = 8;
break;
case 0x40:
max_segs = 16;
break;
case 0x50:
max_segs = 32;
break;
case 0x60:
max_segs = 64;
break;
case 0x70:
max_segs = 65;
break;
default:
break;
}
return max_segs;
}
int decode_max_apdu(uint8_t octet)
{
int max_apdu = 0;
switch (octet & 0x0F)
{
case 0:
max_apdu = 50;
break;
case 1:
max_apdu = 128;
break;
case 2:
max_apdu = 206;
break;
case 3:
max_apdu = 480;
break;
case 4:
max_apdu = 1024;
break;
case 5:
max_apdu = 1476;
break;
default:
break;
}
return max_apdu;
}
int encode_unsigned16(uint8_t * apdu, uint16_t value)
{
union {
@@ -1255,6 +1326,26 @@ void testBACDCodeObject(Test * pTest)
return;
}
void testBACDCodeMaxSegsApdu(Test * pTest)
{
int max_segs[8] = {0,2,4,8,16,32,64,65};
int max_apdu[6] = {50,128,206,480,1024,1476};
int i = 0;
int j = 0;
uint8_t octet = 0;
// test
for (i = 0; i < 8; i++)
{
for (j = 0; j < 6; j++)
{
octet = encode_max_segs_max_apdu(max_segs[i], max_apdu[j]);
ct_test(pTest, max_segs[i] == decode_max_segs(octet));
ct_test(pTest, max_apdu[j] == decode_max_apdu(octet));
}
}
}
#ifdef TEST_DECODE
int main(void)
{
@@ -1277,6 +1368,9 @@ int main(void)
assert(rc);
rc = ct_addTestFunction(pTest, testBACDCodeObject);
assert(rc);
rc = ct_addTestFunction(pTest, testBACDCodeMaxSegsApdu);
assert(rc);
// configure output
ct_setStream(pTest, stdout);
ct_run(pTest);
(void) ct_report(pTest);
+2
View File
@@ -147,5 +147,7 @@ int decode_unsigned32(uint8_t * apdu, uint32_t *value);
// 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);
int decode_max_segs(uint8_t octet);
int decode_max_apdu(uint8_t octet);
#endif
+32 -71
View File
@@ -39,77 +39,7 @@
#include "bacenum.h"
#include "bits.h"
#include "npdu.h"
/* 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
*/
uint8_t npdu_encode_max_seg_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;
}
#include "apdu.h"
int npdu_encode_raw(
uint8_t *npdu,
@@ -339,6 +269,37 @@ int npdu_decode(
return len;
}
void npdu_handler(
BACNET_ADDRESS *src, // source address
uint8_t *pdu, // PDU data
uint16_t pdu_len) // length PDU
{
int apdu_offset = 0;
BACNET_ADDRESS dest = {0};
BACNET_NPDU_DATA npdu_data = {0};
apdu_offset = npdu_decode(
&pdu[0], // data to decode
&dest, // destination address - get the DNET/DLEN/DADR if in there
src, // source address - get the SNET/SLEN/SADR if in there
&npdu_data); // amount of data to decode
if (npdu_data.network_layer_message)
{
//FIXME: network layer message received! Handle it!
}
else
{
apdu_handler(
src,
npdu_data.data_expecting_reply,
&pdu[apdu_offset],
pdu_len - apdu_offset);
}
return;
}
#ifdef TEST
#include <assert.h>
#include <string.h>