R2A --> R3A
diff --git a/LLC_v7.1.0_CNL113577.tpd b/LLC_v7.1.0_CNL113577.tpd
new file mode 100644
index 0000000..a3ccf51
--- /dev/null
+++ b/LLC_v7.1.0_CNL113577.tpd
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2017 Ericsson
+
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Eclipse Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/epl-v10.html
+
+
+ File: LLC_v7.1.0_CNL113577.tpd
+ Description: tpd project file
+ Rev: R3A
+ Prodnr: CNL 113 577
+
+ -->
+<TITAN_Project_File_Information version="1.0">
+ <ProjectName>LLC_v7.1.0_CNL113577</ProjectName>
+ <ReferencedProjects>
+ <ReferencedProject name="ProtocolModules_Common" projectLocationURI="../COMMON/ProtocolModules_Common.tpd"/>
+ </ReferencedProjects>
+ <Files>
+ <FileResource projectRelativePath="LLC_Types.ttcn" relativeURI="src/LLC_Types.ttcn"/>
+ <FileResource projectRelativePath="LLC_EncDec.cc" relativeURI="src/LLC_EncDec.cc"/>
+ </Files>
+ <ActiveConfiguration>Default</ActiveConfiguration>
+ <Configurations>
+ <Configuration name="Default">
+ <ProjectProperties>
+ <MakefileSettings>
+ <generateInternalMakefile>true</generateInternalMakefile>
+ <GNUMake>true</GNUMake>
+ <incrementalDependencyRefresh>true</incrementalDependencyRefresh>
+ <targetExecutable>bin/LLC_v7.1.0_CNL113577</targetExecutable>
+ <buildLevel>Level3-Creatingobjectfileswithdependencyupdate</buildLevel>
+ </MakefileSettings>
+ <LocalBuildSettings>
+ <workingDirectory>bin</workingDirectory>
+ </LocalBuildSettings>
+ </ProjectProperties>
+ </Configuration>
+ </Configurations>
+</TITAN_Project_File_Information>
diff --git a/doc/LLC_v7.1_1551.doc b/doc/LLC_v7.1_1551.doc
new file mode 100644
index 0000000..51bc5d8
--- /dev/null
+++ b/doc/LLC_v7.1_1551.doc
Binary files differ
diff --git a/doc/LLC_v7.1_PRI.doc b/doc/LLC_v7.1_PRI.doc
new file mode 100644
index 0000000..509fb1b
--- /dev/null
+++ b/doc/LLC_v7.1_PRI.doc
Binary files differ
diff --git a/src/LLC_EncDec.cc b/src/LLC_EncDec.cc
index b96b961..66d19d1 100644
--- a/src/LLC_EncDec.cc
+++ b/src/LLC_EncDec.cc
@@ -9,12 +9,12 @@
///////////////////////////////////////////////////////////////////////////////
//
// File: LLC_EncDec.cc
-// Rev: R2A
+// Rev: R3A
// Prodnr: CNL 113 577
// Updated: 2008-01-22
// Contact: http://ttcn.ericsson.se
// Reference: 3GPP TS 44.064 7.1.0
-
+
#include "LLC_Types.hh"
#include <string.h>
@@ -29,15 +29,46 @@
// For UI frames if PM bit is 0 (unprotected) then CRC will be calculated over Header + N202 octets
#define N202 4
-unsigned int mCRCTable[TABLE_LENGTH];
+unsigned int mCRCTable[TABLE_LENGTH] = {
+ 0x00000000, 0x00d6a776, 0x00f64557, 0x0020e221, 0x00b78115, 0x00612663, 0x0041c442, 0x00976334,
+ 0x00340991, 0x00e2aee7, 0x00c24cc6, 0x0014ebb0, 0x00838884, 0x00552ff2, 0x0075cdd3, 0x00a36aa5,
+ 0x00681322, 0x00beb454, 0x009e5675, 0x0048f103, 0x00df9237, 0x00093541, 0x0029d760, 0x00ff7016,
+ 0x005c1ab3, 0x008abdc5, 0x00aa5fe4, 0x007cf892, 0x00eb9ba6, 0x003d3cd0, 0x001ddef1, 0x00cb7987,
+ 0x00d02644, 0x00068132, 0x00266313, 0x00f0c465, 0x0067a751, 0x00b10027, 0x0091e206, 0x00474570,
+ 0x00e42fd5, 0x003288a3, 0x00126a82, 0x00c4cdf4, 0x0053aec0, 0x008509b6, 0x00a5eb97, 0x00734ce1,
+ 0x00b83566, 0x006e9210, 0x004e7031, 0x0098d747, 0x000fb473, 0x00d91305, 0x00f9f124, 0x002f5652,
+ 0x008c3cf7, 0x005a9b81, 0x007a79a0, 0x00acded6, 0x003bbde2, 0x00ed1a94, 0x00cdf8b5, 0x001b5fc3,
+ 0x00fb4733, 0x002de045, 0x000d0264, 0x00dba512, 0x004cc626, 0x009a6150, 0x00ba8371, 0x006c2407,
+ 0x00cf4ea2, 0x0019e9d4, 0x00390bf5, 0x00efac83, 0x0078cfb7, 0x00ae68c1, 0x008e8ae0, 0x00582d96,
+ 0x00935411, 0x0045f367, 0x00651146, 0x00b3b630, 0x0024d504, 0x00f27272, 0x00d29053, 0x00043725,
+ 0x00a75d80, 0x0071faf6, 0x005118d7, 0x0087bfa1, 0x0010dc95, 0x00c67be3, 0x00e699c2, 0x00303eb4,
+ 0x002b6177, 0x00fdc601, 0x00dd2420, 0x000b8356, 0x009ce062, 0x004a4714, 0x006aa535, 0x00bc0243,
+ 0x001f68e6, 0x00c9cf90, 0x00e92db1, 0x003f8ac7, 0x00a8e9f3, 0x007e4e85, 0x005eaca4, 0x00880bd2,
+ 0x00437255, 0x0095d523, 0x00b53702, 0x00639074, 0x00f4f340, 0x00225436, 0x0002b617, 0x00d41161,
+ 0x00777bc4, 0x00a1dcb2, 0x00813e93, 0x005799e5, 0x00c0fad1, 0x00165da7, 0x0036bf86, 0x00e018f0,
+ 0x00ad85dd, 0x007b22ab, 0x005bc08a, 0x008d67fc, 0x001a04c8, 0x00cca3be, 0x00ec419f, 0x003ae6e9,
+ 0x00998c4c, 0x004f2b3a, 0x006fc91b, 0x00b96e6d, 0x002e0d59, 0x00f8aa2f, 0x00d8480e, 0x000eef78,
+ 0x00c596ff, 0x00133189, 0x0033d3a8, 0x00e574de, 0x007217ea, 0x00a4b09c, 0x008452bd, 0x0052f5cb,
+ 0x00f19f6e, 0x00273818, 0x0007da39, 0x00d17d4f, 0x00461e7b, 0x0090b90d, 0x00b05b2c, 0x0066fc5a,
+ 0x007da399, 0x00ab04ef, 0x008be6ce, 0x005d41b8, 0x00ca228c, 0x001c85fa, 0x003c67db, 0x00eac0ad,
+ 0x0049aa08, 0x009f0d7e, 0x00bfef5f, 0x00694829, 0x00fe2b1d, 0x00288c6b, 0x00086e4a, 0x00dec93c,
+ 0x0015b0bb, 0x00c317cd, 0x00e3f5ec, 0x0035529a, 0x00a231ae, 0x007496d8, 0x005474f9, 0x0082d38f,
+ 0x0021b92a, 0x00f71e5c, 0x00d7fc7d, 0x00015b0b, 0x0096383f, 0x00409f49, 0x00607d68, 0x00b6da1e,
+ 0x0056c2ee, 0x00806598, 0x00a087b9, 0x007620cf, 0x00e143fb, 0x0037e48d, 0x001706ac, 0x00c1a1da,
+ 0x0062cb7f, 0x00b46c09, 0x00948e28, 0x0042295e, 0x00d54a6a, 0x0003ed1c, 0x00230f3d, 0x00f5a84b,
+ 0x003ed1cc, 0x00e876ba, 0x00c8949b, 0x001e33ed, 0x008950d9, 0x005ff7af, 0x007f158e, 0x00a9b2f8,
+ 0x000ad85d, 0x00dc7f2b, 0x00fc9d0a, 0x002a3a7c, 0x00bd5948, 0x006bfe3e, 0x004b1c1f, 0x009dbb69,
+ 0x0086e4aa, 0x005043dc, 0x0070a1fd, 0x00a6068b, 0x003165bf, 0x00e7c2c9, 0x00c720e8, 0x0011879e,
+ 0x00b2ed3b, 0x00644a4d, 0x0044a86c, 0x00920f1a, 0x00056c2e, 0x00d3cb58, 0x00f32979, 0x00258e0f,
+ 0x00eef788, 0x003850fe, 0x0018b2df, 0x00ce15a9, 0x0059769d, 0x008fd1eb, 0x00af33ca, 0x007994bc,
+ 0x00dafe19, 0x000c596f, 0x002cbb4e, 0x00fa1c38, 0x006d7f0c, 0x00bbd87a, 0x009b3a5b, 0x004d9d2d
+};
static void BuildCrc24Table()
{
- unsigned int i,j;
- unsigned int reg;
-
- //TRACE_FUNC( "BuildCrc24Table" );
+ unsigned int i,j;
+ unsigned int reg;
for( i = 0; i < TABLE_LENGTH; i++ )
{
@@ -46,8 +77,7 @@
{
if( reg & 1 )
{
-
- reg = (reg>>1) ^ (unsigned int) CRC_POLY_LLC2;
+ reg = (reg>>1) ^ (unsigned int) CRC_POLY_LLC2;
}
else
{
@@ -55,14 +85,9 @@
}
}
reg &= 0x00ffffffL;
-
- mCRCTable[i] = (unsigned int)reg;
- //TTCN_Logger::begin_event(TTCN_DEBUG);
-
- //TTCN_Logger::log_event("mCRCTable[%d]= %d",i,mCRCTable[i]);
-
- // TTCN_Logger::end_event();
+ mCRCTable[i] = (unsigned int)reg;
+ //printf("mCRCTable[%d]= 0x%08x\n",i,mCRCTable[i]);
}
}
@@ -70,200 +95,162 @@
unsigned int Calculate_CRC(TTCN_Buffer& pdu)
{
+ const unsigned char* loc_pdu = pdu.get_data();
-const unsigned char* loc_pdu = pdu.get_data();
-
- //TTCN_Logger::begin_event(TTCN_DEBUG);
-
- //for (size_t i =0; i< pdu.get_len();i++)
- // {
- // TTCN_Logger::log_event("%02x ",loc_pdu[i]);
- // }
-
-//TTCN_Logger::log_event("\n");
-
-//TTCN_Logger::end_event();
-
-BuildCrc24Table();
+//BuildCrc24Table();
//TTCN_Logger::begin_event(TTCN_DEBUG);
//TTCN_Logger::log_event("mCRCTable[%d]= %d\n",255,mCRCTable[255]);
//TTCN_Logger::log_event("mCRCTable[%d]= 0x%08x (%u)",255,mCRCTable[255]);
-//TTCN_Logger::log_event("\n");
+//TTCN_Logger::log_event("\n");
//TTCN_Logger::end_event();
-unsigned int reg = 0xFFFFFF;
+ unsigned int reg = 0xFFFFFF;
+ unsigned int length = pdu.get_len();
-unsigned int length = pdu.get_len();
-
-
-
-if ( ((loc_pdu[1] >>5) & 0x07) == 0x06 ) //UI frame
-{
- if ((loc_pdu[2] & 0x01) == 0x00) // PM bit is 0 (unprotected)
- {
- if(length > 3 + N202) // pdu length is longer than header + N202
- {
- length = 3 + N202; // length = header length + N202
-
- }
- }
-}
-
-
-
-while ( length--)
+ if(((loc_pdu[1] >>5) & 0x07) == 0x06) //UI frame
{
- reg =
- ((reg>>8) & 0x00ffff)^mCRCTable[(reg^*((unsigned char*)loc_pdu++)) & 0xffL];
+ if ((loc_pdu[2] & 0x01) == 0x00) // PM bit is 0 (unprotected)
+ {
+ if(length > 3 + N202) // pdu length is longer than header + N202
+ {
+ length = 3 + N202; // length = header length + N202
+ }
+ }
}
- //TTCN_Logger::log(TTCN_DEBUG, "reg:%08x\n",reg);
- // 1's complement of FCS
+
+ while ( length--)
+ {
+ reg = ((reg>>8) & 0x00ffff)^mCRCTable[(reg^*((unsigned char*)loc_pdu++)) & 0xffL];
+ }
+
reg ^= 0xffffffL;
-
+
reg = ((reg >> 16) & 0x000000ff)+ ((reg) & 0x0000ff00) + ((reg <<16 )& 0x00ff0000);
- //unsigned int tempint = *(unsigned int*)loc_crcBuffer;
- //reg = (unsigned int*)loc_crcBuffer ;
- //TTCN_Logger::log(TTCN_DEBUG, "reg:%08x\n",reg);
-
-return reg & 0x00ffffffL;
+
+ return reg & 0x00ffffffL;
}
+
//---------------------------------------------------------------------------------------
namespace LLC__Types {
OCTETSTRING enc__PDU__LLC(const PDU__LLC& pdu)
{
- TTCN_Buffer bb;
- PDU__LLC pdu2(pdu);
-
- if (pdu2.get_selection() == PDU__LLC::ALT_pDU__LLC__U)
- {
+ TTCN_Buffer bb;
+ PDU__LLC pdu2(pdu);
- if (pdu2.pDU__LLC__U().information__field__U().get_selection() == Information__field__U::ALT_uA)
- {int record_of_size = pdu2.pDU__LLC__U().information__field__U().uA().size_of();
-
- for (int i = 0; i < (record_of_size) ; i++)
- {
- // AUTOMATICALLY CALCULATE WHICH LENGTH FORMAT SHOULD BE USED AND CHANGE SHORT LENGTH FORM
- // TO LONG LENGTH FORM IF NECESSARY WHEN L3 PDU IS INCLUDED
- if ( pdu2.pDU__LLC__U().information__field__U().uA()[i].typefield() == int2bit(11,5) )
- {
- if( pdu2.pDU__LLC__U().information__field__U().uA()[i].xID__Data().l3param().lengthof() > 3)
- {
- pdu2.pDU__LLC__U().information__field__U().uA()[i].xID__length().long__len() =
- pdu2.pDU__LLC__U().information__field__U().uA()[i].xID__Data().l3param().lengthof();
- }
- }
- }
- }
+ if (pdu2.get_selection() == PDU__LLC::ALT_pDU__LLC__UI)
+ {
+ if ( pdu2.pDU__LLC__UI().fCS().ispresent())
+ {
+ if ( pdu2.pDU__LLC__UI().fCS() == int2oct(0,3) )
+ { // IF ZERO, THEN ENCODER NEEDS TO GENERATE CRC
+ pdu2.pDU__LLC__UI().fCS() = OMIT_VALUE;
+ pdu2.encode(PDU__LLC_descr_ ,bb, TTCN_EncDec::CT_RAW);
+ unsigned int crcBuffer = Calculate_CRC(bb);
+ bb.put_os(int2oct(crcBuffer,3));
+ return OCTETSTRING (bb.get_len(), bb.get_data());
+ }
+ else
+ { // IF ENCODER SENDS OUT NONZERO CRC GIVEN IN TTCN TEMPLATE
+ pdu2.encode(PDU__LLC_descr_ ,bb, TTCN_EncDec::CT_RAW);
+ return OCTETSTRING (bb.get_len(), bb.get_data());
+ }
+ }
+ else
+ { //FCS OMIT
+ pdu2.encode(PDU__LLC_descr_ ,bb, TTCN_EncDec::CT_RAW);
+ unsigned int crcBuffer = Calculate_CRC(bb);
+ bb.put_os(int2oct(crcBuffer,3));
+ return OCTETSTRING (bb.get_len(), bb.get_data());
+ }
+ }
+ else if (pdu2.get_selection() == PDU__LLC::ALT_pDU__LLC__U)
+ {
+ if (pdu2.pDU__LLC__U().information__field__U().get_selection() == Information__field__U::ALT_uA)
+ {
+ int record_of_size = pdu2.pDU__LLC__U().information__field__U().uA().size_of();
- if (pdu2.pDU__LLC__U().information__field__U().get_selection() == Information__field__U::ALT_sABM)
- {int record_of_size = pdu2.pDU__LLC__U().information__field__U().sABM().size_of();
-
- for (int i = 0; i < (record_of_size) ; i++)
- {
- // AUTOMATICALLY CALCULATE WHICH LENGTH FORMAT SHOULD BE USED AND CHANGE SHORT LENGTH FORM
- // TO LONG LENGTH FORM IF NECESSARY WHEN L3 PDU IS INCLUDED
- if ( pdu2.pDU__LLC__U().information__field__U().sABM()[i].typefield() == int2bit(11,5) )
- {
- if( pdu2.pDU__LLC__U().information__field__U().sABM()[i].xID__Data().l3param().lengthof() > 3)
- {
- pdu2.pDU__LLC__U().information__field__U().sABM()[i].xID__length().long__len() =
- pdu2.pDU__LLC__U().information__field__U().sABM()[i].xID__Data().l3param().lengthof();
- }
- }
- }
- }
-
- if (pdu2.pDU__LLC__U().information__field__U().get_selection() == Information__field__U::ALT_xID)
- {int record_of_size = pdu2.pDU__LLC__U().information__field__U().xID().size_of();
-
- for (int i = 0; i < (record_of_size) ; i++)
- {
- // AUTOMATICALLY CALCULATE WHICH LENGTH FORMAT SHOULD BE USED AND CHANGE SHORT LENGTH FORM
- // TO LONG LENGTH FORM IF NECESSARY WHEN L3 PDU IS INCLUDED
- if ( pdu2.pDU__LLC__U().information__field__U().xID()[i].typefield() == int2bit(11,5) )
- {
- if( pdu2.pDU__LLC__U().information__field__U().xID()[i].xID__Data().l3param().lengthof() > 3)
- {
- pdu2.pDU__LLC__U().information__field__U().xID()[i].xID__length().long__len() =
- pdu2.pDU__LLC__U().information__field__U().xID()[i].xID__Data().l3param().lengthof();
- }
- }
- }
- }
- }
-
-
- if (pdu2.get_selection() == PDU__LLC::ALT_pDU__LLC__U)
- {
- if ( pdu2.pDU__LLC__U().fCS().ispresent())
- {
- if ( pdu2.pDU__LLC__U().fCS() == int2oct(0,3) ) // IF ENCODER NEEDS TO GENERATE CRC
- {
- pdu2.pDU__LLC__U().fCS() = OMIT_VALUE;
- pdu2.encode(PDU__LLC_descr_ ,bb, TTCN_EncDec::CT_RAW);
- unsigned int crcBuffer = Calculate_CRC(bb);
- bb.put_os(int2oct(crcBuffer,3));
- return OCTETSTRING (bb.get_len(), bb.get_data());
-
- }
-
- else { // IF ENCODER SENDS OUT NONZERO CRC GIVEN IN TTCN TEMPLATE
- pdu2.encode(PDU__LLC_descr_ ,bb, TTCN_EncDec::CT_RAW);
- return OCTETSTRING (bb.get_len(), bb.get_data());
- }
- }
- else { //FCS OMIT
- pdu2.encode(PDU__LLC_descr_ ,bb, TTCN_EncDec::CT_RAW);
- unsigned int crcBuffer = Calculate_CRC(bb);
- bb.put_os(int2oct(crcBuffer,3));
- return OCTETSTRING (bb.get_len(), bb.get_data());
-
- }
- }
-
-
-
- else if (pdu2.get_selection() == PDU__LLC::ALT_pDU__LLC__UI)
- {
- if ( pdu2.pDU__LLC__UI().fCS().ispresent())
- {
- if ( pdu2.pDU__LLC__UI().fCS() == int2oct(0,3) ) // IF ENCODER NEEDS TO GENERATE CRC
- {
- pdu2.pDU__LLC__UI().fCS() = OMIT_VALUE;
- pdu2.encode(PDU__LLC_descr_ ,bb, TTCN_EncDec::CT_RAW);
- unsigned int crcBuffer = Calculate_CRC(bb);
- bb.put_os(int2oct(crcBuffer,3));
- return OCTETSTRING (bb.get_len(), bb.get_data());
-
- }
-
- else { // IF ENCODER SENDS OUT NONZERO CRC GIVEN IN TTCN TEMPLATE
- pdu2.encode(PDU__LLC_descr_ ,bb, TTCN_EncDec::CT_RAW);
- return OCTETSTRING (bb.get_len(), bb.get_data());
- }
- }
- else { //FCS OMIT
- pdu2.encode(PDU__LLC_descr_ ,bb, TTCN_EncDec::CT_RAW);
- unsigned int crcBuffer = Calculate_CRC(bb);
- bb.put_os(int2oct(crcBuffer,3));
- return OCTETSTRING (bb.get_len(), bb.get_data());
- }
- }
- else {TTCN_error("Can not encode LLC PDU"); //Neither UI NOR U
-
- return OCTETSTRING (bb.get_len(), bb.get_data()); // this is dummy to avoid warning during compilation
- }
- //pdu2.encode(PDU__LLC_descr_ ,bb, TTCN_EncDec::CT_RAW);
- //unsigned int crcBuffer = Calculate_CRC(bb);
-
- //bb.put_os( int2oct(crcBuffer,3));
-
-
- //return OCTETSTRING (bb.get_len(), bb.get_data());
-
+ for (int i = 0; i < (record_of_size) ; i++)
+ { // AUTOMATICALLY CALCULATE WHICH LENGTH FORMAT SHOULD BE USED AND CHANGE SHORT LENGTH FORM
+ // TO LONG LENGTH FORM IF NECESSARY WHEN L3 PDU IS INCLUDED
+ if ( pdu2.pDU__LLC__U().information__field__U().uA()[i].typefield() == int2bit(11,5) )
+ {
+ if( pdu2.pDU__LLC__U().information__field__U().uA()[i].xID__Data().l3param().lengthof() > 3)
+ {
+ pdu2.pDU__LLC__U().information__field__U().uA()[i].xID__length().long__len() =
+ pdu2.pDU__LLC__U().information__field__U().uA()[i].xID__Data().l3param().lengthof();
+ }
+ }
+ }
+ }
+
+ if (pdu2.pDU__LLC__U().information__field__U().get_selection() == Information__field__U::ALT_sABM)
+ {
+ int record_of_size = pdu2.pDU__LLC__U().information__field__U().sABM().size_of();
+
+ for (int i = 0; i < (record_of_size) ; i++)
+ { // AUTOMATICALLY CALCULATE WHICH LENGTH FORMAT SHOULD BE USED AND CHANGE SHORT LENGTH FORM
+ // TO LONG LENGTH FORM IF NECESSARY WHEN L3 PDU IS INCLUDED
+ if ( pdu2.pDU__LLC__U().information__field__U().sABM()[i].typefield() == int2bit(11,5) )
+ {
+ if( pdu2.pDU__LLC__U().information__field__U().sABM()[i].xID__Data().l3param().lengthof() > 3)
+ {
+ pdu2.pDU__LLC__U().information__field__U().sABM()[i].xID__length().long__len() =
+ pdu2.pDU__LLC__U().information__field__U().sABM()[i].xID__Data().l3param().lengthof();
+ }
+ }
+ }
+ }
+
+ if (pdu2.pDU__LLC__U().information__field__U().get_selection() == Information__field__U::ALT_xID)
+ {
+ int record_of_size = pdu2.pDU__LLC__U().information__field__U().xID().size_of();
+
+ for (int i = 0; i < (record_of_size) ; i++)
+ { // AUTOMATICALLY CALCULATE WHICH LENGTH FORMAT SHOULD BE USED AND CHANGE SHORT LENGTH FORM
+ // TO LONG LENGTH FORM IF NECESSARY WHEN L3 PDU IS INCLUDED
+ if ( pdu2.pDU__LLC__U().information__field__U().xID()[i].typefield() == int2bit(11,5) )
+ {
+ if( pdu2.pDU__LLC__U().information__field__U().xID()[i].xID__Data().l3param().lengthof() > 3)
+ {
+ pdu2.pDU__LLC__U().information__field__U().xID()[i].xID__length().long__len() =
+ pdu2.pDU__LLC__U().information__field__U().xID()[i].xID__Data().l3param().lengthof();
+ }
+ }
+ }
+ }
+
+ if ( pdu2.pDU__LLC__U().fCS().ispresent())
+ {
+ if ( pdu2.pDU__LLC__U().fCS() == int2oct(0,3) ) // IF ENCODER NEEDS TO GENERATE CRC
+ {
+ pdu2.pDU__LLC__U().fCS() = OMIT_VALUE;
+ pdu2.encode(PDU__LLC_descr_ ,bb, TTCN_EncDec::CT_RAW);
+ unsigned int crcBuffer = Calculate_CRC(bb);
+ bb.put_os(int2oct(crcBuffer,3));
+ return OCTETSTRING (bb.get_len(), bb.get_data());
+ }
+ else
+ { // IF ENCODER SENDS OUT NONZERO CRC GIVEN IN TTCN TEMPLATE
+ pdu2.encode(PDU__LLC_descr_ ,bb, TTCN_EncDec::CT_RAW);
+ return OCTETSTRING (bb.get_len(), bb.get_data());
+ }
+ }
+ else
+ { //FCS OMIT
+ pdu2.encode(PDU__LLC_descr_ ,bb, TTCN_EncDec::CT_RAW);
+ unsigned int crcBuffer = Calculate_CRC(bb);
+ bb.put_os(int2oct(crcBuffer,3));
+ return OCTETSTRING (bb.get_len(), bb.get_data());
+ }
+ }
+ else
+ {
+ TTCN_error("Can not encode LLC PDU"); //Neither UI NOR U
+ return OCTETSTRING (bb.get_len(), bb.get_data()); // this is dummy to avoid warning during compilation
+ }
}
@@ -273,45 +260,56 @@
}
-PDU__LLC dec__PDU__LLC(const OCTETSTRING& stream)
+PDU__LLC dec__PDU__LLC(const OCTETSTRING& stream, const BOOLEAN& checkFCS)
{
- PDU__LLC retv;
- TTCN_Buffer bb;
- OCTETSTRING crc = int2oct(0,3);
-
- size_t datalength = stream.lengthof()-3;
- const unsigned char * CRC_AS_RECEIVED = (const unsigned char *)stream+datalength;
- bb.put_s(datalength,(const unsigned char *)stream);
-
- unsigned int CRC_CALCULATED = Calculate_CRC(bb);
-
- // COMPARE CRC RECEIVED IN LLC PDU WITH CRC CALCULATED FROM LLC PDU
- if(
- (CRC_AS_RECEIVED[ 0 ] != (CRC_CALCULATED & 0xff0000 ) >> 16) ||
- (CRC_AS_RECEIVED[ 1 ] != (CRC_CALCULATED & 0xff00 ) >> 8) ||
- (CRC_AS_RECEIVED[ 2 ] != (CRC_CALCULATED & 0xff ) )
- )
- {
- TTCN_warning("CRC ERROR IN LLC PDU"); // CRC IS NOT AS EXPECTED
- crc=OCTETSTRING(3,CRC_AS_RECEIVED);
- }
- // CRC IS
- // FILL CRC octets with zeroes if CRC is OK
-
- retv.decode(PDU__LLC_descr_, bb, TTCN_EncDec::CT_RAW);
-
- if (retv.get_selection() == PDU__LLC::ALT_pDU__LLC__UI){
- retv.pDU__LLC__UI().fCS() = crc;
- }
-
- if (retv.get_selection() == PDU__LLC::ALT_pDU__LLC__U){
- retv.pDU__LLC__U().fCS() = crc;
- }
-
-
- return retv;
-
+ PDU__LLC retv;
+ TTCN_Buffer bb;
+ size_t datalength = stream.lengthof()-3;
+ bb.put_s(datalength,(const unsigned char *)stream);
+ retv.decode(PDU__LLC_descr_, bb, TTCN_EncDec::CT_RAW);
+
+ const unsigned char * CRC_AS_RECEIVED = (const unsigned char *)stream+datalength;
+
+ if(checkFCS)
+ {
+ // FILL CRC octets with zeroes if CRC is OK
+ OCTETSTRING crc = int2oct(0,3);
+ unsigned int CRC_CALCULATED = Calculate_CRC(bb);
+
+ // COMPARE CRC RECEIVED IN LLC PDU WITH CRC CALCULATED FROM LLC PDU
+ if( (CRC_AS_RECEIVED[ 0 ] != (CRC_CALCULATED & 0xff0000 ) >> 16) ||
+ (CRC_AS_RECEIVED[ 1 ] != (CRC_CALCULATED & 0xff00 ) >> 8) ||
+ CRC_AS_RECEIVED[ 2 ] != (CRC_CALCULATED & 0xff ) )
+ {
+ TTCN_warning("CRC ERROR IN LLC PDU"); // CRC IS NOT AS EXPECTED
+ crc=OCTETSTRING(3,CRC_AS_RECEIVED);
+ }
+
+ if (retv.get_selection() == PDU__LLC::ALT_pDU__LLC__UI)
+ {
+ retv.pDU__LLC__UI().fCS() = crc;
+ }
+
+ if (retv.get_selection() == PDU__LLC::ALT_pDU__LLC__U)
+ {
+ retv.pDU__LLC__U().fCS() = crc;
+ }
+ }
+ else
+ {
+ if (retv.get_selection() == PDU__LLC::ALT_pDU__LLC__UI)
+ {
+ retv.pDU__LLC__UI().fCS() = OCTETSTRING(3,CRC_AS_RECEIVED);
+ }
+ else if (retv.get_selection() == PDU__LLC::ALT_pDU__LLC__U)
+ {
+ retv.pDU__LLC__U().fCS() = OCTETSTRING(3,CRC_AS_RECEIVED);
+ }
+ }
+
+
+ return retv;
}
}//namespace
diff --git a/src/LLC_Types.ttcn b/src/LLC_Types.ttcn
index d07a77f..6f752e4 100644
--- a/src/LLC_Types.ttcn
+++ b/src/LLC_Types.ttcn
@@ -11,72 +11,70 @@
// File: LLC_Types.ttcn
// Description: This module contains the Logical Link Control protocol (LLC)
// 44.064 v7.1.0 with attributes for RAW encoding/decoding.
-// Rev: R2A
+// Rev: R3A
// Prodnr: CNL 113 577
// Updated: 2008-01-22
// Contact: http://ttcn.ericsson.se
// Reference: 3GPP TS 44.064 7.1.0
-
+
module LLC_Types
-{
+{
import from General_Types all;
external function enc_PDU_LLC(in PDU_LLC pdu) return octetstring;
-external function dec_PDU_LLC(in octetstring stream) return PDU_LLC;
+external function dec_PDU_LLC(in octetstring stream,in boolean checkFCS := true) return PDU_LLC;
+
+////////////////////////////////
+// XID fields
+////////////////////////////////
type record Version
{
- integer version_value (0..15),
- BIT4 spare
+ integer version_value (0..15),
+ BIT4 spare
} with {
variant (version_value) "FIELDLENGTH(4)";
}
-type octetstring IOV_UI length(4)
-
+type octetstring IOV_UI length(4)
type octetstring IOV_I length(4)
-
type record T200
{
- BIT4 spare,
- integer t200Value
+ BIT4 spare,
+ integer t200Value
} with {
variant (t200Value) "FIELDLENGTH(12)";
variant (t200Value) "BYTEORDER(last)";
variant "FIELDORDER(msb)";
};
-
type record N200
{
- integer retransmissions (0..15),
- BIT4 spare
+ integer retransmissions (0..15),
+ BIT4 spare
} with {
variant (retransmissions) "FIELDLENGTH(4)";
-}
-
+};
type record N201_U
{
- BIT5 spare,
- integer n201UValue
+ BIT5 spare,
+ integer n201UValue
} with {
variant (n201UValue) "FIELDLENGTH(11)";
variant (n201UValue) "BYTEORDER(last)";
variant "FIELDORDER(msb)";
};
-
type record N201_I
{
- BIT5 spare,
- integer n201IValue
-}
-with {
+ BIT5 spare,
+ integer n201IValue
+} with {
variant (n201IValue) "FIELDLENGTH(11)";
variant (n201IValue) "BYTEORDER(last)";
variant "FIELDORDER(msb)";
@@ -84,28 +82,27 @@
type record MD
{
- BIT1 spare,
- integer mDValue
+ BIT1 spare,
+ integer mDValue
} with {
variant (mDValue) "FIELDLENGTH(15)";
variant (mDValue) "BYTEORDER(last)";
variant "FIELDORDER(msb)";
};
-
type record MU
{
- BIT1 spare,
- integer mUValue
+ BIT1 spare,
+ integer mUValue
} with {
variant (mUValue) "FIELDLENGTH(15)";
variant (mUValue) "BYTEORDER(last)";
variant "FIELDORDER(msb)";
};
-type integer KD with {variant "FIELDLENGTH(8)";};
+type integer KD with {variant "FIELDLENGTH(8)";};
-type integer KU with {variant "FIELDLENGTH(8)";};
+type integer KU with {variant "FIELDLENGTH(8)";};
type octetstring L3param;
@@ -113,116 +110,116 @@
type union XID_Data
{
- Version version,
- IOV_UI iOV_UI,
- IOV_I iOV_I,
- T200 t200,
- N200 n200,
- N201_U n201_U,
- N201_I n201_I,
- MD mD,
- MU mU,
- KD kD,
- KU kU,
- L3param l3param,
- Reset_LLC reset
+ Version version,
+ IOV_UI iOV_UI,
+ IOV_I iOV_I,
+ T200 t200,
+ N200 n200,
+ N201_U n201_U,
+ N201_I n201_I,
+ MD mD,
+ MU mU,
+ KD kD,
+ KU kU,
+ L3param l3param,
+ Reset_LLC reset
}
-
type union XID_length
{
integer short_len,
integer long_len
-}with {
+} with {
variant (short_len) "FIELDLENGTH(2)";
variant (long_len) "FIELDLENGTH(8)";
variant (long_len) "BYTEORDER(last)";
variant (short_len) "FIELDORDER(msb)";
variant (long_len) "FIELDORDER(msb)";
-
}
-
type record XID
{
- BIT1 xl,
- BIT5 typefield,
- XID_length xID_length,
- //Header_XID header_XID,
- XID_Data xID_Data
-} with {
- variant (xID_Data) "CROSSTAG( version, typefield = '00000'B;
- iOV_UI, typefield = '00001'B;
- iOV_I, typefield = '00010'B;
- t200, typefield = '00011'B;
- n200, typefield = '00100'B;
- n201_U, typefield = '00101'B;
- n201_I, typefield = '00110'B;
- mD, typefield = '00111'B;
- mU, typefield = '01000'B;
- kD, typefield = '01001'B;
- kU, typefield = '01010'B;
- l3param, typefield = '01011'B;
- reset, typefield = '01100'B;
-
- )";
+ BIT1 xl,
+ BIT5 typefield,
+ XID_length xID_length,
+// Header_XID header_XID,
+ XID_Data xID_Data
+} with {
+ variant (xID_Data) "CROSSTAG(
+ version, typefield = '00000'B;
+ iOV_UI, typefield = '00001'B;
+ iOV_I, typefield = '00010'B;
+ t200, typefield = '00011'B;
+ n200, typefield = '00100'B;
+ n201_U, typefield = '00101'B;
+ n201_I, typefield = '00110'B;
+ mD, typefield = '00111'B;
+ mU, typefield = '01000'B;
+ kD, typefield = '01001'B;
+ kU, typefield = '01010'B;
+ l3param, typefield = '01011'B;
+ reset, typefield = '01100'B;
+ )";
variant "FIELDORDER(msb)";
- variant (xID_length) "CROSSTAG( short_len, xl = '0'B;
- long_len, xl = '1'B;)";
+ variant (xID_length) "CROSSTAG( short_len, xl = '0'B;
+ long_len, xl = '1'B;)";
variant (xID_length) "LENGTHTO (xID_Data)"
-
- variant (xID_length) "PADDING(yes)"
+ variant (xID_length) "PADDING(yes)"
};
+////////////////////////////////
+// Rejected Frame Control fields
+////////////////////////////////
type record RejectedFrameControlField_UI
{
- Control_field_UI control_field,
- OCT4 spare
+ Control_field_UI control_field,
+ OCT4 spare
}
type record RejectedFrameControlField_U
{
- Control_field_U control_field,
- OCT5 spare
-}
+ Control_field_U control_field,
+ OCT5 spare
+}
-type union RejectedFrameControlField
+type union RejectedFrameControlField
{
- RejectedFrameControlField_UI rejectedFrameControlField_UI,
- RejectedFrameControlField_U rejectedFrameControlField_U
+ RejectedFrameControlField_UI rejectedFrameControlField_UI,
+ RejectedFrameControlField_U rejectedFrameControlField_U
} with {
- variant "TAG(rejectedFrameControlField_UI, control_field.format = '110'B;
- rejectedFrameControlField_U, control_field.format = '111'B;
- )";
+ variant "TAG(rejectedFrameControlField_UI, control_field.format = '110'B;
+ rejectedFrameControlField_U, control_field.format = '111'B;
+ )";
};
+////////////////////////////////
+// Information fields
+////////////////////////////////
type record of XID UA_Information;
type record of XID SABM_Information;
type record of XID XID_Information;
-
type octetstring DM_Information length(0);
-
type record FRMR_Information
{
RejectedFrameControlField rejectedFrameControlField,
- BIT4 spare1,
- BIT9 vS,
- BIT1 spare2,
- BIT9 vR,
- BIT1 cR,
- BIT4 spare3,
- BIT1 w4,
- BIT1 w3,
- BIT1 w2,
- BIT1 w1
+ BIT4 spare1,
+ BIT9 vS,
+ BIT1 spare2,
+ BIT9 vR,
+ BIT1 cR,
+ BIT4 spare3,
+ BIT1 w4,
+ BIT1 w3,
+ BIT1 w2,
+ BIT1 w1
} with {
variant (vS) "BYTEORDER(last)";
variant (vR) "BYTEORDER(last)";
@@ -230,31 +227,31 @@
};
+////////////////////////////////
+// Information fields
+////////////////////////////////
type record Address_field
{
- BIT4 sAPI,
- BIT2 spare, // '00'B
- BIT1 cR,
- BIT1 pD //'0' for LLC
+ BIT4 sAPI,
+ BIT2 spare, // '00'B
+ BIT1 cR,
+ BIT1 pD //'0' for LLC
}
type record Control_field_U
{
- BIT4 mBits,
- BIT1 pF,
- BIT3 format // '111'B
+ BIT4 mBits,
+ BIT1 pF,
+ BIT3 format // '111'B
}
-
-
type record Control_field_UI
-
{
- BIT3 format, // '110'B
- BIT2 spare,
- integer nU, //BIT9
- BIT1 e,
- BIT1 pM
+ BIT3 format, // '110'B
+ BIT2 spare,
+ integer nU, //BIT9
+ BIT1 e,
+ BIT1 pM
} with {
variant (nU) "FIELDLENGTH(9)";
@@ -262,67 +259,63 @@
variant "FIELDORDER(msb)";
}
-
type union Information_field_U
{
- UA_Information uA,
- SABM_Information sABM,
- FRMR_Information fRMR,
- DM_Information dM,
- XID_Information xID
+ UA_Information uA,
+ SABM_Information sABM,
+ FRMR_Information fRMR,
+ DM_Information dM,
+ XID_Information xID
};
+////////////////////////////////
+// PDU definitions
+////////////////////////////////
type record PDU_LLC_UI
{
- Address_field address_field,
- Control_field_UI control_field,
- octetstring information_field_UI,
- OCT3 fCS optional
+ Address_field address_field,
+ Control_field_UI control_field,
+ octetstring information_field_UI,
+ OCT3 fCS optional
// fCS ENCODING:
- //'000000'O in send template -> generate CRC,
- // omit in send template -> generate CRC,
+ //'000000'O in send template -> generate CRC,
+ // omit in send template -> generate CRC,
// otherwise send out fCS in send template
- //
+ //
// DECODING:
- // decoder generates '000000'O if CRC OK
+ // decoder generates '000000'O if CRC OK and if CRC check is requested
}
-
-
type record PDU_LLC_U
{
- Address_field address_field,
- Control_field_U control_field,
- Information_field_U information_field_U,
- OCT3 fCS optional
+ Address_field address_field,
+ Control_field_U control_field,
+ Information_field_U information_field_U,
+ OCT3 fCS optional
// ENCODING:
- //'000000'O in send template -> generate CRC,
- // omit in send template -> generate CRC,
+ //'000000'O in send template -> generate CRC,
+ // omit in send template -> generate CRC,
// otherwise send out fCS in send template
- //
+ //
// DECODING:
- // decoder generates '000000'O if CRC OK
-} with {
- variant (information_field_U) "CROSSTAG( uA, control_field.mBits = '0110'B;
- sABM, control_field.mBits = '0111'B;
- fRMR, control_field.mBits = '1000'B;
- dM, control_field.mBits = '0001'B;
- xID, control_field.mBits = '1011'B;
- )";
+ // decoder generates '000000'O if CRC OK and if CRC check is requested
+} with {
+ variant (information_field_U) "CROSSTAG( uA, control_field.mBits = '0110'B;
+ sABM, control_field.mBits = '0111'B;
+ fRMR, control_field.mBits = '1000'B;
+ dM, control_field.mBits = '0001'B;
+ xID, control_field.mBits = '1011'B;
+ )";
};
-
type union PDU_LLC
{
PDU_LLC_UI pDU_LLC_UI,
PDU_LLC_U pDU_LLC_U
-} with { variant "TAG (
- pDU_LLC_UI, control_field.format ='110'B;
- pDU_LLC_U, control_field.format ='111'B;
+} with { variant "TAG (pDU_LLC_UI, control_field.format ='110'B;
+ pDU_LLC_U, control_field.format ='111'B;
)"
};
-
-
}with{ encode "RAW"}// end of module