From a814f263cc46d88736ef7cdb6466d78657855ca8 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Mon, 24 Jul 2017 13:21:35 +0200 Subject: Import BSSAP+, BSSGP, BSSMAP, GTP, GTPv2, LLC and MobileL3 this has been kindly provided by Ericsson and will soon (September-ish) be released officially as FOSS on the eclipse.org git server. --- .../doc/LLC_v7.1.0_CNL113577_PRI.pdf | Bin 0 -> 27025 bytes .../doc/LLC_v7.1.0_CNL113577_UG.pdf | Bin 0 -> 38179 bytes LLC_v7.1.0_CNL113577_LATEST/src/LLC_EncDec.cc | 318 ++++++++++++++++++++ LLC_v7.1.0_CNL113577_LATEST/src/LLC_Types.ttcn | 329 +++++++++++++++++++++ 4 files changed, 647 insertions(+) create mode 100644 LLC_v7.1.0_CNL113577_LATEST/doc/LLC_v7.1.0_CNL113577_PRI.pdf create mode 100644 LLC_v7.1.0_CNL113577_LATEST/doc/LLC_v7.1.0_CNL113577_UG.pdf create mode 100644 LLC_v7.1.0_CNL113577_LATEST/src/LLC_EncDec.cc create mode 100644 LLC_v7.1.0_CNL113577_LATEST/src/LLC_Types.ttcn (limited to 'LLC_v7.1.0_CNL113577_LATEST') diff --git a/LLC_v7.1.0_CNL113577_LATEST/doc/LLC_v7.1.0_CNL113577_PRI.pdf b/LLC_v7.1.0_CNL113577_LATEST/doc/LLC_v7.1.0_CNL113577_PRI.pdf new file mode 100644 index 00000000..f834e6a2 Binary files /dev/null and b/LLC_v7.1.0_CNL113577_LATEST/doc/LLC_v7.1.0_CNL113577_PRI.pdf differ diff --git a/LLC_v7.1.0_CNL113577_LATEST/doc/LLC_v7.1.0_CNL113577_UG.pdf b/LLC_v7.1.0_CNL113577_LATEST/doc/LLC_v7.1.0_CNL113577_UG.pdf new file mode 100644 index 00000000..a61bf2eb Binary files /dev/null and b/LLC_v7.1.0_CNL113577_LATEST/doc/LLC_v7.1.0_CNL113577_UG.pdf differ diff --git a/LLC_v7.1.0_CNL113577_LATEST/src/LLC_EncDec.cc b/LLC_v7.1.0_CNL113577_LATEST/src/LLC_EncDec.cc new file mode 100644 index 00000000..8fe0f088 --- /dev/null +++ b/LLC_v7.1.0_CNL113577_LATEST/src/LLC_EncDec.cc @@ -0,0 +1,318 @@ +/////////////////////////////////////////////////////////////////////////////// +// // +// Copyright Test Competence Center (TCC) ETH 2008 // +// // +// The copyright to the computer program(s) herein is the property of TCC. // +// The program(s) may be used and/or copied only with the written permission // +// of TCC or in accordance with the terms and conditions stipulated in the // +// agreement/contract under which the program(s) has been supplied. // +// // +/////////////////////////////////////////////////////////////////////////////// +// +// File: LLC_EncDec.cc +// Rev: R1A0 +// 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 + +// GIVEN IN CODE RECEIVED FROM ERV +#define CRC_POLY_LLC2 0xad85dd + +// GIVEN IN SPECIFICATION +//#define CRC_POLY_LLC2 0xbba1b5 + +#define TABLE_LENGTH 256 + +// 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]; + + +static void BuildCrc24Table() +{ + unsigned int i,j; + unsigned int reg; + + //TRACE_FUNC( "BuildCrc24Table" ); + + for( i = 0; i < TABLE_LENGTH; i++ ) + { + reg = i; + for( j = 8; j > 0; j-- ) + { + if( reg & 1 ) + { + + reg = (reg>>1) ^ (unsigned int) CRC_POLY_LLC2; + } + else + { + reg >>= 1; + } + } + 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(); + + } +} + +//--------------------------------------------------------------------------------------- + +unsigned int Calculate_CRC(TTCN_Buffer& pdu) +{ + +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(); + +//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::end_event(); + +unsigned int reg = 0xFFFFFF; + +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--) + { + reg = + ((reg>>8) & 0x00ffff)^mCRCTable[(reg^*((unsigned char*)loc_pdu++)) & 0xffL]; + } + //TTCN_Logger::log(TTCN_DEBUG, "reg:%08x\n",reg); + // 1's complement of FCS + 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; +} +//--------------------------------------------------------------------------------------- + +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) + { + + 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.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()); + +} + + +OCTETSTRING enc__PDU__LLC(const PDU__LLC_template& pdu) +{ + return enc__PDU__LLC(pdu.valueof()); +} + + +PDU__LLC dec__PDU__LLC(const OCTETSTRING& stream) +{ + 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; + + +} + +}//namespace diff --git a/LLC_v7.1.0_CNL113577_LATEST/src/LLC_Types.ttcn b/LLC_v7.1.0_CNL113577_LATEST/src/LLC_Types.ttcn new file mode 100644 index 00000000..7c537a8d --- /dev/null +++ b/LLC_v7.1.0_CNL113577_LATEST/src/LLC_Types.ttcn @@ -0,0 +1,329 @@ +/////////////////////////////////////////////////////////////////////////////// +// // +// Copyright Test Competence Center (TCC) ETH 2008 // +// // +// The copyright to the computer program(s) herein is the property of TCC. // +// The program(s) may be used and/or copied only with the written permission // +// of TCC or in accordance with the terms and conditions stipulated in the // +// agreement/contract under which the program(s) has been supplied. // +// // +/////////////////////////////////////////////////////////////////////////////// +// +// 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: R1A0 +// 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; + +type record Version +{ + integer version_value (0..15), + BIT4 spare + +} with { + variant (version_value) "FIELDLENGTH(4)"; +} + +type octetstring IOV_UI length(4) + + +type octetstring IOV_I length(4) + + +type record T200 +{ + 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 +} with { + variant (retransmissions) "FIELDLENGTH(4)"; +} + + +type record N201_U +{ + 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 { + variant (n201IValue) "FIELDLENGTH(11)"; + variant (n201IValue) "BYTEORDER(last)"; + variant "FIELDORDER(msb)"; +}; + +type record MD +{ + BIT1 spare, + integer mDValue +} with { + variant (mDValue) "FIELDLENGTH(15)"; + variant (mDValue) "BYTEORDER(last)"; + variant "FIELDORDER(msb)"; +}; + + +type record MU +{ + 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 KU with {variant "FIELDLENGTH(8)";}; + +type octetstring L3param; + +type octetstring Reset_LLC length(0); + +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 +} + + +type union XID_length +{ + integer short_len, + integer long_len +}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; + + )"; + variant "FIELDORDER(msb)"; + 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)" +}; + + +type record RejectedFrameControlField_UI +{ + Control_field_UI control_field, + OCT4 spare +} + + +type record RejectedFrameControlField_U +{ + Control_field_U control_field, + OCT5 spare +} + + +type union RejectedFrameControlField +{ + 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; + )"; +}; + + +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 +} with { + variant (vS) "BYTEORDER(last)"; + variant (vR) "BYTEORDER(last)"; + variant "FIELDORDER(msb)"; +}; + + +type record Address_field +{ + 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 +} + + + +type record Control_field_UI + +{ + BIT3 format, // '110'B + BIT2 spare, + integer nU, //BIT9 + BIT1 e, + BIT1 pM +} with { + + variant (nU) "FIELDLENGTH(9)"; + variant (nU) "BYTEORDER(last)"; + variant "FIELDORDER(msb)"; +} + + +type union Information_field_U +{ + UA_Information uA, + SABM_Information sABM, + FRMR_Information fRMR, + DM_Information dM, + XID_Information xID +}; + + +type record PDU_LLC_UI +{ + 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, + // otherwise send out fCS in send template + // + // DECODING: + // decoder generates '000000'O if CRC OK +} + + + +type record PDU_LLC_U +{ + 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, + // 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; + )"; +}; + + +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{ encode "RAW"}// end of module -- cgit v1.2.3