TTCN for LTE | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
When you try to study TTCN in any kind of technology and get the source code from a standard organization and take a first look at it, what was the first impression ? In my case, the first thing popping up in my mind was "What the heck is this ?". I can even find the file which has main()... (C syntax addict -:). Where do I have to start from ? Who on the earth can completely understand all of these ? Am I the only stupid engineer with difficulties finding even the first file I have to look into ?
Then take a deep breath for a couple of seconds... trying to be calm down ... getting out of the panic. and then think again.
Why do I think this is so difficult ? Is it because of the syntax ? No, I don't think so. Then, is it because there is any super-complicated data structure ? There are a couple of data structure which we are not so familiar with from other common languages.. but I don't think it is such a big issue. It is matter of familiarity. Then what's the problem ? At least to me, the things that put me in such a difficult situation is overall source code structure of TTCN i) there are too many function calls and in many cases most of this function calls are nested as well. First I tried to follow this function calls.. go to main routine.. get into the first function call in the routine. you will find a couple of other function calls there.. and pick the first function call.. get into the function .. you will find several other functions ... repeating this several times.. finally got lost in the forest of function calls.
ii) there are too many nested data structure. most of data structure (like 'struct' in c) in LTE is expressed in the form of 'template' and 'record'. In many case (actually in most case), these template are nested.. and you are going to end up with similar situation as the function calls.... get a template.. pick one of the member of the template. and you notice that the member itself is also a form of template.. so pick one of the member of that template.. and you will find that it is also a form of another template.. repeating this a couple of times.. you will find yourself struggling in the swamp of template. Then what is the easy way to overcome this hurdle and master the TTCN in short time ? Unfortunately I don't think there is any easy way for this.
Then what is the best way for it ? I think the answer would vary depending on person and the specific area he is working with. My personal way is i) Identify a couple of component which are most widely used meaning being used in most test cases. ii) Stick to the handfull of component you selected untill you fully understand them. iii) Select a test case which is made up of the common parts in step ii) and the minimum amount of additional component. iv) Repeat the step ii) and iii) and keep extending the knowledge.
Before you jump into the source code of each test cases, I strongly recommend you to go through the following common components first.
CommonEUTRA_Templates Components
Testcase Components (Examples)
You would have a big picture of the overall LTE TTCN structure and the functionality of several important TTCN components, but you would never learn anything for sure unless you try to do on your own or without any practical examples.
So, I will put down many examples and keep adding these examples.. but the examples are just examples. It would not be the answers to the problem that each of you currently have. The only person who can give you the direct answers to the problem you are working on is YOU, yourself -:)
Disclaimer ! Some of the changes here may not apply to the system that you are currently using because some part of TTCN work differently depending on what kind of TTCN adaptor you are using, or in worst case it would not work at all.
type HalfOctet_Type IEI4_Type; e.g > const HalfOctet_Type tsc_EpsDefaultBearerId := '5'H;
type integer ImcsValue_Type (0..31) e.g > ImcsValue_Type p_InitalGrantIMCS := 0
type O4_Type MessageAuthenticationCode e.g > messageAuthenticationCode := '00000000000000000000000000000000'B
type B4_Type SecurityHeaderType e.g> const SecurityHeaderType tsc_SHT_IntegrityProtected := '0001'B;
RRC PDU - car_SRB0_RrcPdu_IND - UL_CCCH_Message
template SRB_COMMON_IND car_SRB0_RrcPdu_IND(template (present) CellId_Type p_CellId, template (present) UL_CCCH_Message p_RrcPdu) := { /* @sic R5s100127 further MCC160 changes sic@ @status APPROVED */ Common := cr_IndAspCommonPart_SRB(p_CellId, tsc_SRB0, ?), Signalling := { Rrc := { Ccch := p_RrcPdu }, Nas := omit } };
{ /* @status APPROVED */ message_ := { c1 := { rrcConnectionRequest := { criticalExtensions := { rrcConnectionRequest_r8 := { ue_Identity := ?, establishmentCause := p_EstablishmentCause, spare := ? } } } } } };
template UL_CCCH_Message cr_RRCConnectionRequest_withSTMSI( template (value) InitialUE_Identity p_InitialUE_Identity, template (present) EstablishmentCause p_EstablishmentCause) := { message_ := { c1 := { rrcConnectionRequest := { criticalExtensions := { rrcConnectionRequest_r8 := { ue_Identity := p_InitialUE_Identity, establishmentCause := p_EstablishmentCause, spare := ? } } } } } };
template UL_CCCH_Message cr_RRCConnectionRequest_withUE_Identity( template (present) InitialUE_Identity p_InitialUE_Identity, template (present) EstablishmentCause p_EstablishmentCause) := { /* @status APPROVED */ message_ := { c1 := { rrcConnectionRequest := { criticalExtensions := { rrcConnectionRequest_r8 := { ue_Identity := p_InitialUE_Identity, establishmentCause := p_EstablishmentCause, spare := ? } } } } } };
RRC PDU - car_SRB0_RrcPdu_IND - DL_CCCH_Message
template (value) DL_CCCH_Message cs_508_RRCConnectionSetup(RRC_TransactionIdentifier p_RRC_TI, template (value) PUCCH_ConfigDedicated p_PUCCH_ConfigDedicated, SR_PUCCH_ResourceIndex_Type p_SR_PUCCH_ResourceIndex, // @sic R5s090312 sic@ template (value) PhysicalConfigDedicated_AntennaInfo_Type p_AntennaInfo, // @sic R5-100786 sic@ SR_ConfigIndex_Type p_SR_ConfigIndex // @sic R5-102177 sic@ ) := { /* Default values according to 36.508 cl. 4.6.1 Table 4.6.1-17 */ /* @status APPROVED */ message_ := { c1 := { rrcConnectionSetup := { rrc_TransactionIdentifier := p_RRC_TI, criticalExtensions := { c1 := { rrcConnectionSetup_r8 := { radioResourceConfigDedicated := cs_508_RadioResourceConfigDedicated_SRB1(cs_MAC_MainConfig_SRB1, cs_508_PhysicalConfigDedicated_Default_SRB1(p_PUCCH_ConfigDedicated, p_SR_PUCCH_ResourceIndex, p_AntennaInfo, p_SR_ConfigIndex)), nonCriticalExtension := omit } } } } } } };
template (value) RadioResourceConfigDedicated cs_508_RadioResourceConfigDedicated_SRB1( template (value) MAC_MainConfig_Type p_MAC_MainConfig, template (value) PhysicalConfigDedicated p_PhysicalConfigDedicated) := { /* Default value according to 36.508 cl. 4.6.3 Table 4.6.3-15 */ /* @status APPROVED */ srb_ToAddModList := { cs_508_SRB1_ToAddMod_DEFAULT }, drb_ToAddModList := omit, drb_ToReleaseList := omit, mac_MainConfig := p_MAC_MainConfig, sps_Config := omit, physicalConfigDedicated := p_PhysicalConfigDedicated };
template (value) PhysicalConfigDedicated cs_508_PhysicalConfigDedicated_Default_SRB1( template (value) PUCCH_ConfigDedicated p_PUCCH_ConfigDedicated, SR_PUCCH_ResourceIndex_Type p_SR_PUCCH_ResourceIndex, // @sic R5s090312 sic@ template (value) PhysicalConfigDedicated_AntennaInfo_Type p_AntennaInfo, // @sic R5-100786 sic@ SR_ConfigIndex_Type p_SR_ConfigIndex // @sic R5-102177 sic@ ) := { /* Default values according to 36.508 cl. 4.8.2.1.6 Table 4.8.2.1.6-1 */ /* @status APPROVED */ pdsch_ConfigDedicated := cs_508_PDSCH_ConfigDedicated_Default, pucch_ConfigDedicated := p_PUCCH_ConfigDedicated, pusch_ConfigDedicated := cs_508_PUSCH_ConfigDedicated_Default, uplinkPowerControlDedicated := cs_508_UplinkPowerControlDedicated_Default, tpc_PDCCH_ConfigPUCCH := omit, tpc_PDCCH_ConfigPUSCH := omit, cqi_ReportConfig := cs_508_CQI_ReportConfig_Default(omit), soundingRS_UL_ConfigDedicated := omit, antennaInfo := p_AntennaInfo, // @sic R5-100786 sic@ schedulingRequestConfig := cs_508_SchedulingRequest_Config_Default( p_SR_PUCCH_ResourceIndex, p_SR_ConfigIndex) };
template (value) PDSCH_ConfigDedicated cs_508_PDSCH_ConfigDedicated_Default := { /* Default values according to 36.508 cl. 4.6.3 Table 4.6.3-6 */ /* @status APPROVED */ p_a := dB_3 // @sic R5-100261 sic@ };
template (value) PUCCH_ConfigDedicated cs_508_PUCCH_ConfigDedicated_Default_FDD := { /* 36.508 Table 4.6.3-9: PUCCH-ConfigDedicated-DEFAULT */ /* @status APPROVED */ ackNackRepetition := { release := NULL }, tdd_AckNackFeedbackMode := omit };
template (value) PUSCH_ConfigDedicated cs_508_PUSCH_ConfigDedicated_Default := { /* Default values according to 36.508 cl. 4.6.3 Table 4.6.3-11 */ /* @status APPROVED */ betaOffset_ACK_Index := 9, betaOffset_RI_Index := 6, betaOffset_CQI_Index := 6 };
template (value) UplinkPowerControlDedicated cs_508_UplinkPowerControlDedicated_Default := { /* Default values according to 36.508 cl. 4.6.3 Table 4.6.3-26 */ /* @status APPROVED */ p0_UE_PUSCH := 0, deltaMCS_Enabled := en0, accumulationEnabled := true, p0_UE_PUCCH := 0, pSRS_Offset := 3, filterCoefficient := fc4 };
template (value) CQI_ReportConfig cs_508_CQI_ReportConfig_Default( template (omit) CQI_ReportPeriodic p_CQI_ReportingPeriodic) := { /* Default values according to 36.508 cl. 4.6.3 Table 4.6.3-2 */ /* @status APPROVED */ cqi_ReportModeAperiodic := rm30, nomPDSCH_RS_EPRE_Offset := 0, cqi_ReportPeriodic := p_CQI_ReportingPeriodic };
template (value) SchedulingRequestConfig cs_508_SchedulingRequest_Config_Default( SR_PUCCH_ResourceIndex_Type p_SR_PUCCH_ResourceIndex, SR_ConfigIndex_Type p_SR_ConfigIndex, // @sic R5-102177 sic@ Dsr_TransMax_Type p_Dsr_TransMax := n4) := { /* Default values according to 36.508 cl. 4.6.3 Table 4.6.3-20 */ /* @status APPROVED */ setup := { sr_PUCCH_ResourceIndex := p_SR_PUCCH_ResourceIndex, // @sic R5s090312 sic@ sr_ConfigIndex := p_SR_ConfigIndex, // @sic R5-102177 sic@ dsr_TransMax := p_Dsr_TransMax } };
Backbone Sequence for Registration
The most common protocol sequence in protocol conformance would be "4.5.2 UE Registration (State 2)" of 36.508. The backbone for this sequence is implemented in EUTRA_CommmonProcedure.ttcn
Following is three major functions to implement this backbone sequence.
Basic Functions - f_EUTRA_SS_ConfigRachProcedure
Basic Functions - f_EUTRA_Preamble
Basic Functions - f_EUTRA_UE_Page_Def
Basic Functions - fl_EUTRA_RRC_ConnectionSetup_DeltaMCS
Basic Functions - f_EUTRA_SS_CommonRadioBearerConfig
Basic Functions - f_EUTRA_SS_CommonRadioBearerConfig_SingleDRB
Basic Functions - f_InitRLC_Record
function f_InitRLC_Record(out RLC_SS_State p_RLC_Rec, RLC_Mode_Type p_RLC_Mode) { if ( p_RLC_Mode == UM_Mode) { p_RLC_Rec.t_Reordering := 0.05; } else { p_RLC_Rec.t_Reordering := 0.08; } p_RLC_Rec.t_PollRetransmit := 0.08; p_RLC_Rec.t_StatusProhibit := 0.06; // @sic R5s100039 sic@ p_RLC_Rec.pollPDU := 128; p_RLC_Rec.pollByte := 125000; p_RLC_Rec.maxRetxThreshold := 4; p_RLC_Rec.UM_SN_Size := 10; // Initialisation of other parameters p_RLC_Rec.AM_VTS := 0; p_RLC_Rec.AM_VRR := 0; p_RLC_Rec.AM_VRH := 0; p_RLC_Rec.UM_VTUS := 0; p_RLC_Rec.UM_VRUR := 0; p_RLC_Rec.UM_VRUX := 0; p_RLC_Rec.UM_VRUH := 0; p_RLC_Rec.TimeStampLastReceivedPDU := { SFN := { Number :=0 }, Subframe := { Number := 0 } } ; p_RLC_Rec.TxPRBS_Pos := 0; p_RLC_Rec.RxPRBS_Pos := 0; p_RLC_Rec.TxDataSize := 0; p_RLC_Rec.RxDataSize := 0; p_RLC_Rec.Next_PDCP_TX_SN := 0; p_RLC_Rec.Next_PDCP_RX_SN := 0; p_RLC_Rec.UL_PDCP_SDU_size := 100; p_RLC_Rec.UL_PDCP_SDU_scaling := false; }
Basic Functions - f_EUTRA_CellConfig_DefPlusUM_SN5
Backbone sequence for Test Case Body (8.1.2.1)
Backbone sequence for Test Case Body (7.2.2.5.1)
System Control (Controlling the Lower Layer Configuration)
EUTRA_CellCfg_Templates.ttcn
EUTRA_AspCommon_Templates.ttcn
EUTRA_SRB_Templates.ttcn
EUTRA_Security_Templates.ttcn
L2_Common_Templates.ttcn
MAC_Templates.ttcn
MAC_717.ttcn
EUTRA_RRCSteps.ttcn
EUTRA_Paging.ttcn
Typical example of SIB2 change is along with the following steps. Step b)~h) would be the common path for all SIB2 changes.. and step i) and later would vary depending on the IEs you want to change.
step a) f_TC_8_1_2_1_EUTRA (RRC_ConnEst.ttcn) : From any test cases step b) --> f_EUTRA_Init(EUTRA_Component.ttcn) step c) --> fl_EUTRA_Common_Init(EUTRA_Component.ttcn) step d) --> f_EUTRA_CellArray_Init(EUTRA_CellInfo.ttcn) step e) --> f_EUTRA_CellInfo_Init(EUTRA_CellInfo.ttcn) step f) --> f_EUTRA_InitSystemInformation(EUTRA_CellInfo.ttcn) step g) --> cs_SI_SIB2(EUTRA_SysInfo_Templates.ttcn) step h) --> cs_508_SystemInformationBlockType2_Def(EUTRA_SysInfo_Templates.ttcn) step i) --> cs_508_RadioResourceConfigCommonSIB_Default(EUTRA_SysInfo_Templates.ttcn) step j) --> cs_508_PUSCH_ConfigCommon_Default(EUTRA_SysInfo_Templates.ttcn) step k) --> cs_UL_ReferenceSignalsPUSCH(EUTRA_SysInfo_Templates.ttcn)
It will be good to familiar with the following templates representing SIB2. Following is the highest level of SIB2 reperesentation.
template (value) RadioResourceConfigCommonSIB cs_508_RadioResourceConfigCommonSIB_Default( N_RB_CQI_Type p_N_RB_CQI, PUSCH_HoppingOffset_Type p_PuschHoppingOffset, template (value) SoundingRS_UL_ConfigCommon p_SoundingRS_UL_ConfigCommon, template (value) PRACH_ConfigSIB p_PRACH_ConfigSIB, P_b_Type p_P_b) := { /* 36.508 Table 4.6.3-14: RadioResourceConfigCommonSIB-DEFAULT; @status APPROVED */ rach_ConfigCommon := cs_508_RACH_ConfigCommon_Default, bcch_Config := cs_508_BCCH_Config_Default, pcch_Config := cs_508_PCCH_Config_Default, prach_Config := p_PRACH_ConfigSIB, pdsch_ConfigCommon := cs_508_PDSCH_ConfigCommon_Default( p_P_b), pusch_ConfigCommon := cs_508_PUSCH_ConfigCommon_Default(p_PuschHoppingOffset ), pucch_ConfigCommon := cs_508_PUCCH_ConfigCommon_Default(p_N_RB_CQI), soundingRS_UL_ConfigCommon := p_SoundingRS_UL_ConfigCommon, uplinkPowerControlCommon := cs_508_UplinkPowerControlCommon_Default, ul_CyclicPrefixLength := len1 // len1, len2 };
From this you can just search the template (cs_*, p_*) you have further interest. For example, if you want to configure pusch related IEs, you can search the template as follows.
template (value) PUSCH_ConfigCommon cs_508_PUSCH_ConfigCommon_Default(integer p_PuschHoppingOffset) := { pusch_ConfigBasic := { n_SB := 1, /* INTEGER (1..4) */ hoppingMode := interSubFrame, /* interSubFrame, intraSubFrame; FFS */ pusch_HoppingOffset := p_PuschHoppingOffset, enable64QAM := false }, ul_ReferenceSignalsPUSCH := cs_UL_ReferenceSignalsPUSCH };
Example 1 > disable "groupHoppingEnabled" IE.---------------------------------------------------------------------
Following shows the IE in SIB2. This is the one we want to change from this example.
| | | +-ul-ReferenceSignalsPUSCH ::= SEQUENCE | | | +-groupHoppingEnabled ::= BOOLEAN [TRUE] | | | +-groupAssignmentPUSCH ::= INTEGER (0..29) [0] | | | +-sequenceHoppingEnabled ::= BOOLEAN [FALSE] | | | +-cyclicShift ::= INTEGER (0..7) [0]
If you follow the following path from any test case,
step a) f_TC_8_1_2_1_EUTRA (RRC_ConnEst.ttcn) : From any test cases step b) --> f_EUTRA_Init(EUTRA_Component.ttcn) step c) --> fl_EUTRA_Common_Init(EUTRA_Component.ttcn) step d) --> f_EUTRA_CellArray_Init(EUTRA_CellInfo.ttcn) step e) --> f_EUTRA_CellInfo_Init(EUTRA_CellInfo.ttcn) step f) --> f_EUTRA_InitSystemInformation(EUTRA_CellInfo.ttcn) step g) --> cs_SI_SIB2(EUTRA_SysInfo_Templates.ttcn) step h) --> cs_508_SystemInformationBlockType2_Def(EUTRA_SysInfo_Templates.ttcn) step i) --> cs_508_RadioResourceConfigCommonSIB_Default(EUTRA_SysInfo_Templates.ttcn) step j) --> cs_508_PUSCH_ConfigCommon_Default(EUTRA_SysInfo_Templates.ttcn) step k) --> cs_UL_ReferenceSignalsPUSCH(EUTRA_SysInfo_Templates.ttcn)
You will eventually find the following part. Take a deep breath first before you get chocked to death, and change the parts in red as you like.
template (value) UL_ReferenceSignalsPUSCH cs_UL_ReferenceSignalsPUSCH := { /* as signalled in RadioResourceConfiguration and SIB2; @status APPROVED */ groupHoppingEnabled := true, groupAssignmentPUSCH := 0, /* INTEGER (0..29)*/ sequenceHoppingEnabled := false, cyclicShift := 0 };
Example 2 > Chaning PRACH Configuration -------------------------------------------------------------------------
This is about changing the following parameters in SIB2.
| | +-prach-Config ::= SEQUENCE | | | +-rootSequenceIndex ::= INTEGER (0..837) [22] | | | +-prach-ConfigInfo ::= SEQUENCE | | | +-prach-ConfigIndex ::= INTEGER (0..63) [3] | | | +-highSpeedFlag ::= BOOLEAN [FALSE] | | | +-zeroCorrelationZoneConfig ::= INTEGER (0..15) [5] | | | +-prach-FreqOffset ::= INTEGER (0..94) [2]
Same step as step a) ~ i). You will find the following template in EUTRA_SysInfo_Templates.ttcn
template (value) PRACH_ConfigSIB cs_508_PRACH_ConfigSIB_FDD ( Prach_FrequencyOffset_Type p_Prach_FrequencyOffset, RootSequenceIndex_Type p_RootSequenceIndex ) := { /* 36.508 Table 4.6.3-7a: PRACH-ConfigSIB-DEFAULT; as signalled in SIB2 */ /* @status APPROVED */ rootSequenceIndex := p_RootSequenceIndex, // R5-096641 prach_ConfigInfo := cs_PRACH_ConfigInfoFDD (p_Prach_FrequencyOffset) };
You will find the following template in EUTRA_SysInfo_Templates.ttcn.
template (value) PRACH_ConfigInfo cs_PRACH_ConfigInfoFDD(Prach_FrequencyOffset_Type p_Prach_FrequencyOffset) := { /* 36.508 Table 4.6.3-7: PRACH-ConfigCommon-DEFAULT */ /* @status APPROVED */ prach_ConfigIndex := 3, /* as per 34.108 cl 4.4.3.4 */ highSpeedFlag := false, zeroCorrelationZoneConfig := 5, /* INTEGER (0..15)*/ prach_FreqOffset := p_Prach_FrequencyOffset };
Example 3 > Configuring SRS -------------------------------------------------------------------------------------.
This is about changing the following part in SIB2
| | +-soundingRS-UL-Config ::= CHOICE [setup] | | | +-setup ::= SEQUENCE [0] | | | +-srs-BandwidthConfig ::= ENUMERATED [bw3] | | | +-srs-SubframeConfig ::= ENUMERATED [sc0] | | | +-ackNackSRS-SimultaneousTransmission ::= BOOLEAN [TRUE] | | | +-srs-MaxUpPts ::= ENUMERATED OPTIONAL:Omit
Same step as step a) ~ i). You will find the following template in EUTRA_SysInfo_Templates.ttcn template (value) SoundingRS_UL_ConfigCommon cs_508_SoundingRS_UL_ConfigCommon_FDD( SrsBandwidthConfiguration_Type p_SrsBandwidthConfiguration) := { /* 36.508 Table 4.6.3-21: SoundingRS-UL-ConfigCommon-DEFAULT; @status APPROVED */ setup := { srs_BandwidthConfig := p_SrsBandwidthConfiguration, srs_SubframeConfig := sc0, ackNackSRS_SimultaneousTransmission := true, srs_MaxUpPts := omit } };
Example 4 > Releasing SRS -------------------------------------------------------------------------------------.
This is about changing the <case 1> to <case 2> in SIB2. This kind of modification is a little more complicated than the one we saw in previous examples. Depending on TTCN Adaptor implementation, this kind of change may not be allowed.
< case 1 > | | +-soundingRS-UL-Config ::= CHOICE [setup] | | | +-setup ::= SEQUENCE [0] | | | +-srs-BandwidthConfig ::= ENUMERATED [bw3] | | | +-srs-SubframeConfig ::= ENUMERATED [sc0] | | | +-ackNackSRS-SimultaneousTransmission ::= BOOLEAN [TRUE] | | | +-srs-MaxUpPts ::= ENUMERATED OPTIONAL:Omit
< case 2 > | | +-soundingRS-UL-Config ::= CHOICE [setup] | | | +-release ::= null
Add a new template with the same type as the existing one in EUTRA_SysInfo_Templates.ttcn. Blue part is the existing template and the red part is the new template. Don't remove the blue part(existing one) since this may be being used some other places.
template (value) SoundingRS_UL_ConfigCommon cs_508_SoundingRS_UL_ConfigCommon_FDD(SrsBandwidthConfiguration_Type p_SrsBandwidthConfiguration) := { /* 36.508 Table 4.6.3-21: SoundingRS-UL-ConfigCommon-DEFAULT; @status APPROVED */
setup := { srs_BandwidthConfig := p_SrsBandwidthConfiguration, srs_SubframeConfig := sc0, ackNackSRS_SimultaneousTransmission := true, srs_MaxUpPts := omit }
};
template (value) SoundingRS_UL_ConfigCommon cs_508_SoundingRS_UL_ConfigRelease_FDD := { release := null };
Modify f_EUTRA_InitSystemInformation in EUTRA_CellInfo.ttcn as follows. Blue part is the original one and the red part is the modified one.
function f_EUTRA_InitSystemInformation ( .... ) return template (value) BcchInfo_Type { .... // --- Initialise SIB2 --- if (p_FDD_TDD.FDD_TDD == FDD) { //FDD // Initialise UL Bandwidth value
v_SIB2 := cs_SI_SIB2 (cs_508_SystemInformationBlockType2_Def ( omit, // UL Bandwidth is omitted v_ChannelBandwidthDependency.N_RB_CQI, v_ChannelBandwidthDependency.Pusch_HoppingOffset, //cs_508_SoundingRS_UL_ConfigCommon_FDD // (v_ChannelBandwidthDependency.SrsBandwidthConfiguration), cs_508_SoundingRS_UL_ConfigRelease_FDD, cs_508_PRACH_ConfigSIB_FDD ( v_ChannelBandwidthDependency.Prach_FrequencyOffset, p_RootSequenceIndex ), / tsc_P_b_1Tx ) ) ;
} else { // TDD .... };
You can reconfigure the RACH paramters by adding f_EUTRA_SS_ConfigRachProcedure in a test case as follows.
function f_TC_8_1_2_1_EUTRA() runs on EUTRA_PTC {
....
f_EUTRA_Init ( c1 );
//Create and configure cell f_EUTRA_CellConfig_Def ( eutra_Cell1 );
f_EUTRA_SS_ConfigRachProcedure ( eutra_Cell1, omit, cs_RachProcedureConfig_Def(omit, f_EUTRA_CellInfo_GetRAR_TA ( eutra_Cell1 ), f_EUTRA_CellInfo_GetDL_ChBandwidth ( eutra_Cell1 ) ) );
/* Preamble to enter UE in E-UTRA RRC_IDLE (state 2) */ f_EUTRA_Preamble (eutra_Cell1, STATE2_IDLEUPDATE); v_KsiValue := f_EUTRA_SecurityKSIasme_Get ( );
f_EUTRA_TestBody_Set ( true ); .... }
You don't see much parameters at the added part. So you need to trace down all the way to the SIB2 configuration as shown below. Be ready for the surprise. It is extremely complicated follow through.
EUTRA_ConfigurationSteps.ttcn
function f_EUTRA_SS_ConfigRachProcedure(CellId_Type p_CellId, template (omit) C_RNTI p_CRNTI, template (value) RachProcedureConfig_Type p_RachProcedureConfig, template (value) TimingInfo_Type p_TimingInfo := cs_TimingInfo_Now, boolean p_CnfFlag := tsc_CnfReq) runs on EUTRA_PTC
f_EUTRA_SS_CommonCellConfig(p_CellId, cas_RachProcedureConfig_REQ(p_CellId, p_CRNTI, p_RachProcedureConfig, p_TimingInfo, p_CnfFlag)); };
EUTRA_CellCfg_Templates.ttcn
template (value) SYSTEM_CTRL_REQ cas_RachProcedureConfig_REQ ( CellId_Type p_CellId, template (omit) C_RNTI p_CRNTI, template (value) RachProcedureConfig_Type p_RachProcedureConfig, template (value) TimingInfo_Type p_TimingInfo := cs_TimingInfo_Now, boolean p_CnfFlag := tsc_CnfReq) := { Common := cs_ReqAspCommonPart_CellCfg(p_CellId, p_TimingInfo, p_CnfFlag), Request := { Cell := { AddOrReconfigure := { Basic := omit, Active := { C_RNTI := p_CRNTI, PhysicalLayerConfigUL := omit, RachProcedureConfig := p_RachProcedureConfig, CcchDcchDtchConfig := omit } } } } };
EUTRA_ASPCommon_Templates.ttcn
template (value) ReqAspCommonPart_Type cs_ReqAspCommonPart_CellCfg( CellId_Type p_CellId, template (value) TimingInfo_Type p_TimingInfo := cs_TimingInfo_Now, boolean p_CnfFlag := tsc_CnfReq) := { CellId := p_CellId, RoutingInfo := { None := true }, TimingInfo := p_TimingInfo, ControlInfo := { CnfFlag := p_CnfFlag, FollowOnFlag := false } };
EUTRA_ASPCommon_Templates.ttcn
template (value) TimingInfo_Type cs_TimingInfo_Now := {Now := true};
EUTRA_ASP_TypeDefs.ttcn
template (value) TimingInfo_Type cs_TimingInfo(SystemFrameNumber_Type p_SFN, integer p_SubframeOffset) := { SubFrame := { SFN := { Number := (p_SFN + (p_SubframeOffset / 10)) mod 1024}, Subframe := { Number := p_SubframeOffset mod 10 } } };
EUTRA_ASP_TypeDefs.ttcn
type record RachProcedureConfig_Type { RACH_ConfigCommon_Type RACH_ConfigCommon optional, RACH_ConfigDedicated_Type RACH_ConfigDedicated optional, RachProcedureList_Type RachProcedureList optional };
EUTRA_ASPCommon_Templates.ttcn
template (value) RACH_ConfigCommon_Type cs_RACH_ConfigCommon_r8( template (value) RACH_ConfigCommon p_RACH_ConfigCommon) := { R8 := p_RACH_ConfigCommon };
EUTRA_SysInfo_Templates.ttcn
template (value) RACH_ConfigCommon cs_508_RACH_ConfigCommon_Default := { preambleInfo := { numberOfRA_Preambles := n52, /* n4, n8, n12, n16 ,n20, n24, n28, n32, n36, n40, n44, n48, n52, n56,n60, n64 DEFAULT n64 */ preamblesGroupAConfig := omit }, powerRampingParameters := { powerRampingStep := dB2, /* dB0, dB2,dB4, dB6 */ preambleInitialReceivedTargetPower := dBm_104 }, ra_SupervisionInfo := { preambleTransMax := n6, /* n1, n2, n3, n4, n5, n6, n7, n8, n10; */ ra_ResponseWindowSize := sf10, /* sf2, sf3, sf4, sf5, sf6, sf7, sf8, sf10; */ mac_ContentionResolutionTimer := sf48 /* sf8, sf16, sf24, sf32, sf40, sf48, sf56, sf64;*/ }, maxHARQ_Msg3Tx := 4 /* INTEGER (1..8); */ };
I am modifying RRC_ConnEst.ttcn as an example.
Step a) Create a new template in RRC_ConnEst.ttcn as follows :
template (value) RachProcedureConfig_Type cs_RachProcedureConfig_UserDefined( RACH_TimingAdvance_Type p_RAR_TA, Dl_Bandwidth_Type p_Dl_Bandwidth ):= { RACH_ConfigCommon := omit, RACH_ConfigDedicated := omit, RachProcedureList := { //RAR Tx successful but no Contention Resolution { RAResponse := cs_RandomAccessResponseConfig_Def( p_RAR_TA, p_Dl_Bandwidth ), ContentionResolutionCtrl := cs_ContReslCtrl_CRNTI } } };
Step 2) Add the following function call in the test case body in RRC_ConnEst.ttcn as follows.
function f_TC_8_1_2_1_EUTRA() runs on EUTRA_PTC {
....
f_EUTRA_Init ( c1 );
//Create and configure cell f_EUTRA_CellConfig_Def ( eutra_Cell1 );
f_EUTRA_SS_ConfigRachProcedure ( eutra_Cell1, omit, cs_RachProcedureConfig_UserDefined(omit, f_EUTRA_CellInfo_GetRAR_TA ( eutra_Cell1 ), f_EUTRA_CellInfo_GetDL_ChBandwidth ( eutra_Cell1 ) ) );
/* Preamble to enter UE in E-UTRA RRC_IDLE (state 2) */ f_EUTRA_Preamble (eutra_Cell1, STATE2_IDLEUPDATE); v_KsiValue := f_EUTRA_SecurityKSIasme_Get ( );
f_EUTRA_TestBody_Set ( true ); .... }
Step c) Modify cs_RandomAccessResponseConfig_Def part in EUTRA_CellCfg_Templates.ttcn to assign a resource block and MCS as you like.
EUTRA_CellCfg_Templates.ttcn
template (value) RandomAccessResponseConfig_Type cs_RandomAccessResponseConfig_Def (RACH_TimingAdvance_Type p_RAR_TA, Dl_Bandwidth_Type p_Dl_Bandwidth, integer p_RA_GrantRIV := 0, integer p_RA_GrantIMCS := 15 ) := { Ctrl := { DciInfo := cs_DciInfo_RandomAccessResponse(p_Dl_Bandwidth), Rar := { List := { { RapId := { Automatic := true }, InitialGrant := cs_InitialGrant_Def(p_RA_GrantRIV, p_RA_GrantIMCS), TimingAdvance := p_RAR_TA, TempC_RNTI := cs_TempC_RNTI_SameAsC_RNTI } } }, BackoffInd := cs_BI_None } };
Note : p_RA_GrantRIV, p_RA_GrantIMCS are the MCS, RB Allocation which is carried by RAR. It means this is the resource allocation for Msg3.
Reference > Refer to following contention resolution types defined in EUTRA_CellCfgTemplates.ttcn
template (value) ContentionResolutionCtrl_Type cs_ContentionResolutionCtrl_Def := { /* @status APPROVED */ TCRNTI_Based := { MacPdu := { ContainedId := { XorMask := tsc_ContentionResolutionId_Unchanged }, ContainedRlcPdu := {None:=true} } } };
template (value) ContentionResolutionCtrl_Type cs_ContReslCtrl_CRNTI(ImcsValue_Type p_IMCS := 0, integer p_Nprb:= 1):= { /* results in Contention resolution for T-CRNTI */ /* @status APPROVED */ CRNTI_Based := { AutomaticGrant := cs_DciInfo_CcchDcchDtchUL_Explicit(p_IMCS, p_Nprb) // (p_IMCS := 0, p_Nprb:= 1) it results in UL GRANT of 16 bits, } };
template (value) ContentionResolutionCtrl_Type cs_ContReslCtrl_None_TCRNTI := { /* results in no Contention resolution for T-CRNTI */ /* @status APPROVED */ TCRNTI_Based := { NoContResolID := true //SS shall not include contention resolution ID } };
Example 1 > ---------------------------------------------------------------------------------------------------
What I am trying to do in this example is as follows : i) SS --> UE : DCI 0 (Start RB, N RB, MCS etc) ii) SS <-- UE : PUSCH
More specifically I want to change Start RB, N RB, MCS at step i). First step you have to do is to figure out where you can define this. One possible location would be as follows. It is in the following function in EUTRA_RRCSteps.ttcn
function f_EUTRA_RRC_ConnectionSetup_Def (CellId_Type p_CellId, template (value) TimingInfo_Type p_TimingInfo, RRC_TransactionIdentifier p_RRC_TI) runs on EUTRA_PTC { ....
// switch on UL grant assignments f_EUTRA_StartDefULGrantTransmission ( p_CellId, cs_TimingInfo_Now );
SRB.send ( cas_SRB0_RrcPdu_REQ ( p_CellId, p_TimingInfo, cs_508_RRCConnectionSetup ( p_RRC_TI, v_EUTRA_FDD_TDD_Info.pucch_Config, v_Sr_PUCCH_ResourceIndex, v_AntennaInfo, v_SR_ConfigIndex ) ) ); };
If you guess the resource allocation will be in f_EUTRA_StartDefULGrantTransmission ( p_CellId, cs_TimingInfo_Now ), you are right. But not that simple as you may expected. If you follow this function, you will have to all the way to the last step in the following links.
step a) f_EUTRA_RRC_ConnectionSetup_Def (EUTRA_RRCSteps.ttcn) step b) --> f_EUTRA_StartDefULGrantTransmission (EUTRA_ConfigurationSteps.ttcn) step c) --> f_EUTRA_SS_CommonCellConfig (EUTRA_ConfigurationSteps.ttcn) step d) --> cas_ULGrantAllocation_Def_REQ (a parameter to f_EUTRA_SS_CommonCellConfig, EUTRA_ConfigurationSteps.ttcn) step e) --> cas_ULGrantAllocation_REQ (a template called in cas_ULGrantAllocation_Def_REQ, EUTRA_CellCfgTemplates.ttcn) step f) --> cs_DciInfo_CcchDcchDtchUL_Def(a parameter used in cas_ULGrantAllocation_REQ , EUTRA_CellCfgTemplates.ttcn) step g) --> cs_FreqDomainSchedulExplicit(a parameter used in s_DciInfo_CcchDcchDtchUL_Def , EUTRA_CellCfgTemplates.ttcn)
You will not find any detailed information from step a) ~ e).. it would just call another function or another templates. Finally you will find some detailed information at step e) as follows.
template (value) SYSTEM_CTRL_REQ cas_ULGrantAllocation_REQ(...) := { /* @desc common template to be used in all UL grant configurations */ /* @status APPROVED */ Common := cs_ReqAspCommonPart_CellCfg(p_CellId, p_TimingInfo, p_CnfFlag), Request := { Cell := { AddOrReconfigure := { Basic := omit, Active := { C_RNTI := omit, PhysicalLayerConfigUL := omit, RachProcedureConfig := omit, CcchDcchDtchConfig := { TimeDomainRestriction := omit, DL := omit,
UL := { DciInfo := p_DciUlInfo, Hopping := { Deactivated := true }, PUCCH_Synch := p_PUCCH_Synch, UL_GrantConfig := p_UL_GrantConfig }, DrxCtrl := omit, TtiBundling := omit } } } } } };
This has pretty much detailed information, but I still don't see any part which explicitely shows Start RB, N RB. You have to go into one step further. Try looking into DciInfo part. It looks as follows :
template (value) DciUlInfo_Type cs_DciInfo_CcchDcchDtchUL_Def := { /* @status APPROVED */ Imcs := tsc_Imcs_qpskMax, // Selected Max allowed for QPSK TransRetransmissionList := cs_TransRetransmissionListUL_Def, FreqDomainSchedul := cs_FreqDomainSchedulExplicit(0, 25) };
Now I see the variable Imcs.. but still don't see cleary Start RB, N RB part. For this you have to go into one step further.
template (value) FreqDomainSchedulExplicit_Type cs_FreqDomainSchedulExplicit( integer p_FirstRbIndex, integer p_Nprb) := { /* Frequency domain explicit scheduling */ /* @status APPROVED */ FirstRbIndex := p_FirstRbIndex, Nprb := p_Nprb };
Finally you arrived at the final destination. Congratulation ! -:)
Example 2 > RB Configuration for RRC Connection Setup -----------------------------------------------------------
What I am trying to do in this example is as follows : i) SS --> UE : DCI 1A (Start RB, N RB, MCS etc) ii) SS <-- UE : PDSCH for a DL message (e.g, RRC Connection Setup).
More specifically I want to change Start RB, N RB, MCS at step i). First step you have to do is to figure out where you can define this. One possible location would be as follows. It is in the following function in EUTRA_RRCSteps.ttcn
function f_EUTRA_RRC_ConnectionSetup_Def (CellId_Type p_CellId, template (value) TimingInfo_Type p_TimingInfo, RRC_TransactionIdentifier p_RRC_TI) runs on EUTRA_PTC { ....
// switch on UL grant assignments f_EUTRA_StartDefULGrantTransmission ( p_CellId, cs_TimingInfo_Now );
SRB.send ( cas_SRB0_RrcPdu_REQ ( p_CellId, p_TimingInfo, cs_508_RRCConnectionSetup ( p_RRC_TI, v_EUTRA_FDD_TDD_Info.pucch_Config, v_Sr_PUCCH_ResourceIndex, v_AntennaInfo, v_SR_ConfigIndex ) ) ); };
But in this case, you don't see case which seems to specify the DCI1A for downlink resource allocation. f_EUTRA_StartDefULGrantTransmission is for UL Grant which means it is about DCI 0, Not DCI 1A. One possible way would be to insert a additional command as follows(this would not be the only way)
function f_EUTRA_RRC_ConnectionSetup_Def (...) runs on EUTRA_PTC { // Get FDD or TDD mode from Cell-configuration: ...
// switch on UL grant assignments f_EUTRA_StartDefULGrantTransmission ( p_CellId, cs_TimingInfo_Now );
SYS.send( cas_DL_DCI_ExplicitConfig_REQ_Preamble(eutra_Cell1, cs_TimingInfo_Now, 8, dci_1A, ra_2_Localised, 6) );
SYS.receive ( car_CellConfig_CNF ( eutra_Cell1 ) );
SRB.send ( cas_SRB0_RrcPdu_REQ ( p_CellId, p_TimingInfo, cs_508_RRCConnectionSetup ( p_RRC_TI, v_EUTRA_FDD_TDD_Info.pucch_Config, v_Sr_PUCCH_ResourceIndex, v_AntennaInfo, v_SR_ConfigIndex ) ) ); };
The addition of the part marked in red is the enough solution in this case, but I want to trace down this addition to the end for learning purpose.
step a) f_EUTRA_RRC_ConnectionSetup_Def (EUTRA_RRCSteps.ttcn) step b) --> Add cas_DL_DCI_ExplicitConfig_REQ_Preamble (EUTRA_RRCSteps.ttcn) step c) --> cs_DciDlInfoExplicit_Preamble(You can directly change MCS here, but not NRB, StartRB) (EUTRA_RRCSteps.ttcn) step d) --> cs_FreqDomainSchedulExplicit (you can change NRB, StartRB here) (EUTRA_CellCfg_Templates.ttcn)
Now I think we start getting some 'feeling' about what's going on here and what we have to do next. Yes.. you're right. We have to dig into cas_DL_DCI_ExplicitConfig_REQ_Preamble.
template (value) SYSTEM_CTRL_REQ cas_DL_DCI_ExplicitConfig_REQ_Preamble( CellId_Type p_CellId, template (value) TimingInfo_Type p_TimingInfo, ImcsValue_Type p_Imcs, PdcchDciFormat_Type p_Format, PdcchResourceAllocation_Type p_ResourceAllocType, integer p_Nprb, integer p_FirstRbIndex := 0 ) := { /* @status APPROVED ... Common := cs_ReqAspCommonPart_CellCfg(p_CellId, p_TimingInfo), Request := { Cell := { AddOrReconfigure := { Basic := omit, Active := { C_RNTI := omit, PhysicalLayerConfigUL := omit, RachProcedureConfig := omit, CcchDcchDtchConfig := { TimeDomainRestriction := omit, DL := { DciInfo := { Explicit := cs_DciDlInfoExplicit_Preamble( p_Imcs, p_Format, p_ResourceAllocType, p_Nprb, p_FirstRbIndex) }, AntennaInfo := omit, MimoInfo := omit, HarqProcessConfig := omit /* @sic R5w100214, R5w100220 sic@ */ }, UL := omit, DrxCtrl := omit, TtiBundling := omit } } } } } };
Let's dig into one step further. (EUTRA_RRCSteps.ttcn)
template (value) DciDlInfoExplicit_Type cs_DciDlInfoExplicit_Preamble( ImcsValue_Type p_Imcs, PdcchDciFormat_Type p_Format, PdcchResourceAllocation_Type p_ResourceAllocType, integer p_Nprb, integer p_FirstRbIndex := 0, template (value) RedundancyVersionListDL_Type p_RedundancyVersionList := cs_RedundancyVersionListDL_Def) := { /* @status APPROVED */ Imcs_1stCW := {Value := p_Imcs}, Imcs_2ndCW := {NotUsed := true}, Format := p_Format, ResourceAllocType := p_ResourceAllocType, FreqDomainSchedul := cs_FreqDomainSchedulExplicit(p_FirstRbIndex, p_Nprb), RedundancyVersionList := p_RedundancyVersionList, MimoInfo := omit };
If you successfully followed up the previous example, cs_FreqDomainSchedulExplicit would look familiar to you.
template (value) FreqDomainSchedulExplicit_Type cs_FreqDomainSchedulExplicit( integer p_FirstRbIndex, integer p_Nprb) := { /* Frequency domain explicit scheduling */ /* @status APPROVED */ FirstRbIndex := p_FirstRbIndex, Nprb := p_Nprb };
SRB.send ( cas_SRB0_RrcPdu_REQ ( p_CellId, p_TimingInfo, cs_RRCConnectionSetup_DeltaMCS ( p_RRC_TI, v_EUTRA_FDD_TDD_Info.pucch_Config, v_Sr_PUCCH_ResourceIndex, v_AntennaInfo, v_SR_ConfigIndex // @sic R5-102177 sic@ ) ) );
EUTRA_SRB_Templates.ttcn =============
template (value) SRB_COMMON_REQ cas_SRB0_RrcPdu_REQ(CellId_Type p_CellId, template (value) TimingInfo_Type p_TimingInfo, template (value) DL_CCCH_Message p_RrcPdu) := { /* @status APPROVED */ Common := cs_ReqAspCommonPart_SRB(p_CellId, tsc_SRB0, p_TimingInfo), Signalling := { Rrc := { Ccch := p_RrcPdu }, Nas := omit } };
EUTRA_SRB_Templates.ttcn =============
template (value) ReqAspCommonPart_Type cs_ReqAspCommonPart_SRB(CellId_Type p_CellId, SRB_Identity_Type p_SrbId, template (value) TimingInfo_Type p_TimingInfo := cs_TimingInfo_Now, boolean p_FollowOnFlag := false) := { /* @status APPROVED */ CellId := p_CellId, RoutingInfo := { RadioBearerId := { Srb := p_SrbId } }, TimingInfo := p_TimingInfo, ControlInfo := { CnfFlag := false, FollowOnFlag := p_FollowOnFlag } };
Following is the list of RRC messages defined in EPS_RRC_Templates.ttcn
A typical usage of NAS message is as follows. (You will see many of examples of using this format in EUTRA_SecuritySteps.ttcn, NAS_SecurityMode.ttcn, NAS_Detach.ttcn, ESM_TestCases.ttcn)
SRB.send(cas_SRB_NasPdu_REQ(p_CellId, p_SRB, cs_TimingInfo_Now, cs_NAS_Request( tsc_SHT_IntegrityProtected_NewSecurityContext, cs_508_SECURITY_MODE_COMMAND( p_SecurityParams.NAS_Ciphering.Algorithm, p_SecurityParams.NAS_Integrity.Algorithm, p_SecurityParams.KSIasme, p_SecurityParams.NAS_SecurityCap))));
The template at the highest level is cas_SRB_NasPdu_REQ and it is defined as follows.
EUTRA_SRB_Templates.ttcn =============
template (value) SRB_COMMON_REQ cas_SRB_NasPdu_REQ(CellId_Type p_CellId, SRB_Identity_Type p_SrbId, template (value) TimingInfo_Type p_TimingInfo, template (value) NAS_MSG_Request_Type p_NasMsg) := { /* SRB1/2: ASP to send NAS message (within RRC DLInformationTransfer) @status APPROVED */ Common := cs_ReqAspCommonPart_SRB(p_CellId, p_SrbId, p_TimingInfo), Signalling := { Rrc := omit, Nas := { p_NasMsg } } };
EUTRA_SRB_Templates.ttcn =============
template (value) ReqAspCommonPart_Type cs_ReqAspCommonPart_SRB(CellId_Type p_CellId, SRB_Identity_Type p_SrbId, template (value) TimingInfo_Type p_TimingInfo := cs_TimingInfo_Now, boolean p_FollowOnFlag := false) := { /* @status APPROVED */ CellId := p_CellId, RoutingInfo := { RadioBearerId := { Srb := p_SrbId } }, TimingInfo := p_TimingInfo, ControlInfo := { CnfFlag := false, FollowOnFlag := p_FollowOnFlag } };
EPS_NAS_Templates.ttcn =============
template (value) NAS_MSG_Request_Type cs_NAS_Request( SecurityHeaderType p_SecurityStatus, template (value) NAS_DL_Message_Type p_Msg) := { /* @status APPROVED */ SecurityProtection := cs_NAS_SecurityProtectionInfo(p_SecurityStatus), Pdu := { Msg := p_Msg, PiggybackedPduList := omit } };
EPS_NAS_Templates.ttcn =============
template (value) NAS_SecurityProtectionInfoDL_Type cs_NAS_SecurityProtectionInfo( SecurityHeaderType p_Status, boolean p_ForceMacError := false) := { /* @status APPROVED */ Status := p_Status, ForceMacError := p_ForceMacError // @sic R5s100358 additional changes sic@ };
EPS_NAS_MsgContainers.ttcn =============
type record NAS_MSG_Request_Type { NAS_SecurityProtectionInfoDL_Type SecurityProtection, /* contains security status */ NAS_DL_Pdu_Type Pdu /* => only one NAS PDU on top level */ };
type record NAS_MSG_Indication_Type { NAS_SecurityProtectionInfoUL_Type SecurityProtection, NAS_UL_Pdu_Type Pdu };
Following is the list of NAS messages defined in EPS_NAS_Templates.ttcn
Authentication Parameter Change
Some of the authentication related parameters can be changed in PIXIT, but some of the parameters should be changed by TTCN.
Example 1 > AUTN and XRES Change ----------------------------------------------------------------------------
You can find the AUTN in NAS_AuxiliaryDefsAndFunctions.ttcn (in Common_NAS folder) as follows :
function f_AuthenticationInit(Common_AuthenticationParams_Type p_Auth_Params) return Common_AuthenticationParams_Type { var Common_AuthenticationParams_Type v_Auth_Params := p_Auth_Params; var B128_Type v_XDOut; var B80_Type v_AUTN_2; var B64_Type v_CDOut; var B64_Type v_XDOut_Half; var B64_Type v_MAC; var B48_Type v_AK; var B48_Type v_AUTN_1; var B48_Type v_AuthSQN := '000000000000000000000000000000000000000000000000'B;
v_XDOut := v_Auth_Params.RandValue xor4b px_AuthK; v_CDOut := v_AuthSQN & px_AuthAMF; v_XDOut_Half := substr( v_XDOut, 0, 64); v_AK := substr( v_XDOut, 24, 48); v_AUTN_1 := v_AuthSQN xor4b v_AK; v_MAC := v_XDOut_Half xor4b v_CDOut; v_AUTN_2 := px_AuthAMF & v_MAC; v_Auth_Params.AUTN := v_AUTN_1 & v_AUTN_2; // v_IKey := 128 bits of v_XDOut, wrapped, starting from offset 16 v_Auth_Params.IK := substr( v_XDOut, 16, (128 - 16)) & substr( v_XDOut, 0, 16); // v_CKey := 128 bits of v_XDOut, wrapped, starting from offset 8 v_Auth_Params.CK := substr( v_XDOut, 8, (128 - 8)) & substr( v_XDOut, 0, 8); v_Auth_Params.XRES := v_XDOut; // ((CK1 XOR CK2) XOR (IK1 XOR IK2)) v_Auth_Params.KcGSM := (substr( v_Auth_Params.CK, 0, 64) xor4b substr( v_Auth_Params.CK, 64, 64)) xor4b (substr( v_Auth_Params.IK, 0, 64) xor4b substr( v_Auth_Params.IK, 64, 64)); v_Auth_Params.KeySeq := int2bit(((bit2int(v_Auth_Params.KeySeq)+1) mod 8), 3);
return (v_Auth_Params); }
You can change the red part into any value you like as follows.
v_Auth_Params.AUTN := '01011110011100100110101101010110101101001110110010010000000000011 010001111001111001011100101111001110010011010111100011010110101'B
v_Auth_Params.XRES := '1010001111001111001011100101111001110010011010110101011010110100'B
Removing Authentication Check on SS side (Removing XRES checking)
You would not want to do this on real test, but you may want to skip this process just to make the test go further at early stage of protocol stack integration test. Method is very simple. Just remove the part that checks XRES value as shown below. (EUTRA_SecuritySteps.ttcn)
function f_EUTRA_NAS_Authentication(.....) runs on EUTRA_PTC return EUTRA_SecurityParams_Type { var SRB_COMMON_IND v_ReceivedAsp; var B32_128_Type v_ReceivedRES; var EUTRA_SecurityParams_Type v_SecurityParams;
// Evaluate Authentication parameters and generate new keys v_SecurityParams := f_EUTRA_Authentication_InitNAS(p_SecurityParams,p_PLMN);
SRB.send(cas_SRB_NasPdu_REQ(p_CellId, p_SRB, cs_TimingInfo_Now, cs_NAS_Request(p_SecurityStatusAuthRequest, cs_AUTHENTICATION_REQUEST( v_SecurityParams.KSIasme, v_SecurityParams.AuthParams.RandValue, v_SecurityParams.AuthParams.AUTN)))); // receive AUTHENTICATION RESPONSE: @sic R5s090210 sic@ alt { [] SRB.receive(car_SRB_NasPdu_IND(p_CellId, p_SRB, cr_NAS_Indication(p_SecurityStatusAuthResponse, cr_AUTHENTICATION_RESPONSE))) -> value v_ReceivedAsp { v_ReceivedRES := v_ReceivedAsp.Signalling.Nas[0] .Pdu.Msg.aUTHENTICATION_RESPONSE.authenticationResponseParameter.res; if (v_ReceivedRES != substr(v_SecurityParams.AuthParams.XRES, 0, lengthof(v_ReceivedRES))) { //f_EUTRA_SetVerdictFailOrInconc(__FILE__, __LINE__, "Authentication Failed"); } } [] SRB.receive(car_SRB_NasPdu_IND(p_CellId, p_SRB, cr_NAS_Indication(?, cr_AUTHENTICATION_FAIL_Any))) { f_EUTRA_SetVerdictFailOrInconc(__FILE__, __LINE__, "Authentication Fail Message"); } } return (v_SecurityParams); };
Actually this parameter should be able to be changed by PIXIT, but if you want to hardcode some value in ttcn for some reason, modify the following part in EUTRA_RRC_Templates.ttcn
template (value) SecurityConfigSMC cs_508_SecurityConfig_SMC(IntegrityProtAlgorithm_Type p_IntegrityProtAlgorithm, CipheringAlgorithm_Type p_CipheringAlgorithm) := { /* Default values according to 36.508 cl. 4.6.4 Table 4.6.4-2 */ /* @status APPROVED */ securityAlgorithmConfig := { cipheringAlgorithm := p_CipheringAlgorithm, integrityProtAlgorithm := p_IntegrityProtAlgorithm } };
One example of modification is as follows :
template (value) SecurityConfigSMC cs_508_SecurityConfig_SMC(IntegrityProtAlgorithm_Type p_IntegrityProtAlgorithm, CipheringAlgorithm_Type p_CipheringAlgorithm) := { /* Default values according to 36.508 cl. 4.6.4 Table 4.6.4-2 */ /* @status APPROVED */ securityAlgorithmConfig := { cipheringAlgorithm := p_CipheringAlgorithm, integrityProtAlgorithm := '111'B } };
There is one thing you have to be careful about this. If you set integrityProtAlgorithm to be the one other than eia1, eia2. It would cause some error since TTCN would expect the integrity Protection Algorithm on PDCP layer. So in this case, you have to disable the MAC_I/X_MAC check routine just to make test case proceed. (I know this is not comformant... but this technote is all about 'breaking' the comformance -:)
The way to disable MAC_I/X_MAC checking is to comment out f_EUTRA_SS_RRC_EnableIntProt_CiphULandDL in f_EUTRA_RRC_ActivateSecurity as follows.
EUTRA_SecuritySteps.ttcn
function f_EUTRA_RRC_ActivateSecurity(CellId_Type p_CellId, EUTRA_SecurityParams_Type p_SecurityParams, NasCount_Type p_NasCountUL) runs on EUTRA_PTC return EUTRA_SecurityParams_Type { var EUTRA_SecurityParams_Type v_SecurityParams := f_EUTRA_Authentication_InitAS (p_SecurityParams, p_NasCountUL); /* Calculate Kenb and KRRCenc, KRRCint, KUPenc */
// Read PDCP SQN for SRB1 and calcuate Ciphering Activation times v_SecurityParams.AS_Ciphering.ActTimeList := f_EUTRA_RRC_CipherActTime_Get(p_CellId); /* note: this works only when timing info is now */
// Note by default DRB is also pre-configured on SS side
//f_EUTRA_SS_RRC_EnableIntProt_CiphULandDL (p_CellId, // v_SecurityParams.AS_Integrity , // v_SecurityParams.AS_Ciphering); f_EUTRA_RRC_InitialSecurityActivation(p_CellId, v_SecurityParams.AS_Integrity.Algorithm, v_SecurityParams.AS_Ciphering.Algorithm); /* SecurityModeComplete is not ciphered acc. to 36.331 cl. 5.3.4.3 and 5.3.1.1 */
return (v_SecurityParams); };
The above single step is all to disable MAC_I/X_MAC check, but just for the reference I traced down all the sub routines used in f_EUTRA_SS_RRC_EnableIntProt_CiphULandDL.
EUTRA_SecuritySteps.ttcn
function f_EUTRA_SS_RRC_EnableIntProt_CiphULandDL(CellId_Type p_CellId, AS_IntegrityInfo_Type p_AS_IntegrityInfo, AS_CipheringInfo_Type p_AS_CipheringInfo, template (value) TimingInfo_Type p_TimingInfo := cs_TimingInfo_Now) runs on EUTRA_PTC { var boolean v_CnfFlag := f_TimingInfo_IsNow(p_TimingInfo); f_EUTRA_SS_AS_SecurityConfig(p_CellId, cas_AsSecurityStart_REQ(p_CellId, cs_AS_IntProt_CiphActivate(p_AS_IntegrityInfo, p_AS_CipheringInfo), p_TimingInfo, v_CnfFlag) ); };
EUTRA_Security_Templates.ttcn
template (value) SYSTEM_CTRL_REQ cas_AsSecurityStart_REQ(CellId_Type p_CellId, template (value) AS_SecStartRestart_Type p_AS_SecStartRestart, template (value) TimingInfo_Type p_TimingInfo := cs_TimingInfo_Now, boolean p_CnfFlag := tsc_CnfReq) := { /* @status APPROVED */ /* Note: when p_TimingInfo is not cs_TimingInfo_Now p_CnfFlag shall be set to tsc_NoCnfReq */ /* @sic R5s100178 sic@ */ Common := cs_ReqAspCommonPart_CellCfg(p_CellId, p_TimingInfo, p_CnfFlag), Request := { AS_Security := { StartRestart := p_AS_SecStartRestart } } };
EUTRA_AspCommon_Templates.ttcn
template (value) ReqAspCommonPart_Type cs_ReqAspCommonPart_CellCfg(CellId_Type p_CellId, template (value) TimingInfo_Type p_TimingInfo := cs_TimingInfo_Now, boolean p_CnfFlag := tsc_CnfReq) := { /* @status APPROVED */ CellId := p_CellId, RoutingInfo := { None := true }, TimingInfo := p_TimingInfo, ControlInfo := { CnfFlag := p_CnfFlag, FollowOnFlag := false } };
EUTRA_SecuritySteps.ttcn
function f_EUTRA_SS_AS_SecurityConfig(CellId_Type p_CellId, template (value) SYSTEM_CTRL_REQ p_SYSTEM_CTRL_REQ) runs on EUTRA_PTC { SYS.send(p_SYSTEM_CTRL_REQ); if (valueof(p_SYSTEM_CTRL_REQ.Common.ControlInfo.CnfFlag) == true) { SYS.receive(car_AsSecurity_CNF(p_CellId)); } }
Example 1 > Applying 'No Integrity' ------------------------------------------------------------------------------
This is only for disabling Integrity in NAS message and this process does not influence integrity procedure in PDCP. For the integrity/ciphering procedure changes in PDCP, refer to example 2.
You can find the following part from EUTRA_SecuritySteps.ttcn in Common_EUTRA folder.
function f_EUTRA_NAS_SecurityModeControl(CellId_Type p_CellId, EUTRA_SecurityParams_Type p_SecurityParams, SRB_Identity_Type p_SRB := tsc_SRB1) runs on EUTRA_PTC return NasCount_Type { /* @sic R5-101147 - no parameter p_NewSecurityCxt sic@ */ var SRB_COMMON_IND v_ReceivedAsp; var NasCount_Type v_NasCountUL;
// send NAS SECURITY MODE COMMAND (integrity protected acc. 24.301 cl. 5.4.3.2): SRB.send(cas_SRB_NasPdu_REQ(p_CellId, p_SRB, cs_TimingInfo_Now, cs_NAS_Request( tsc_SHT_IntegrityProtected_NewSecurityContext, cs_508_SECURITY_MODE_COMMAND( p_SecurityParams.NAS_Ciphering.Algorithm, p_SecurityParams.NAS_Integrity.Algorithm, p_SecurityParams.KSIasme, p_SecurityParams.NAS_SecurityCap)))); // receive NAS SECURITY MODE COMPLETE // (integrity protected and ciphered acc. 24.301 cl. 5.4.3.3): SRB.receive(car_SRB_NasPdu_IND(p_CellId, p_SRB, cr_NAS_Indication (tsc_SHT_IntegrityProtected_Ciphered_NewSecurityContext, cr_508_SECURITY_MODE_COMPLETE))) -> value v_ReceivedAsp;
v_NasCountUL := v_ReceivedAsp.Signalling.Nas[0].SecurityProtection.NasCount; return v_NasCountUL; };
Change tsc_SHT_IntegrityProtected_Ciphered_NewSecurityContext to tsc_SHT_NoSecurityProtection.
If you follow tsc_SHT_IntegrityProtected_Ciphered_NewSecurityContext, it is defined as follows in EPS_NAS_Constants.ttcn in Common_EUTRA_Def folder.
const SecurityHeaderType tsc_SHT_NoSecurityProtection := '0000'B; const SecurityHeaderType tsc_SHT_IntegrityProtected := '0001'B; const SecurityHeaderType tsc_SHT_IntegrityProtected_Ciphered := '0010'B; const SecurityHeaderType tsc_SHT_IntegrityProtected_NewSecurityContext := '0011'B; const SecurityHeaderType tsc_SHT_IntegrityProtected_Ciphered_NewSecurityContext := '0100'B; const SecurityHeaderType tsc_SHT_ServiceRequest := '1100'B;
When you changed the security header as follows, UE would also send "Security Mode Complete" message with '0000' header. In this case, you have to change the "Security Mode Complete" part to matching what UE sends.
In this case you only have to change tsc_SHT_IntegrityProtected_Ciphered_NewSecurityContext part (SRB.recieve) to whatever corresponding to what UE sends. Following is an example.
function f_EUTRA_NAS_SecurityModeControl(CellId_Type p_CellId, EUTRA_SecurityParams_Type p_SecurityParams, SRB_Identity_Type p_SRB := tsc_SRB1) runs on EUTRA_PTC return NasCount_Type { /* @sic R5-101147 - no parameter p_NewSecurityCxt sic@ */ var SRB_COMMON_IND v_ReceivedAsp; var NasCount_Type v_NasCountUL;
// send NAS SECURITY MODE COMMAND (integrity protected acc. 24.301 cl. 5.4.3.2): SRB.send(cas_SRB_NasPdu_REQ(p_CellId, p_SRB, cs_TimingInfo_Now, cs_NAS_Request( tsc_SHT_NoSecurityProtection, cs_508_SECURITY_MODE_COMMAND( p_SecurityParams.NAS_Ciphering.Algorithm, p_SecurityParams.NAS_Integrity.Algorithm, p_SecurityParams.KSIasme, p_SecurityParams.NAS_SecurityCap)))); // receive NAS SECURITY MODE COMPLETE // (integrity protected and ciphered acc. 24.301 cl. 5.4.3.3): SRB.receive(car_SRB_NasPdu_IND(p_CellId, p_SRB, cr_NAS_Indication (tsc_SHT_NoSecurityProtection, cr_508_SECURITY_MODE_COMPLETE))) -> value v_ReceivedAsp;
v_NasCountUL := v_ReceivedAsp.Signalling.Nas[0].SecurityProtection.NasCount; return v_NasCountUL; };
Example 2 > Disabling Integrity/Ciphering in PDCP Layer------------------------------------------------------------
This is only for disabling Integrity/chipering in PDCP and this process does not influence integrity procedure IE in NAS message. For the integrity/ciphering procedure changes in NAS message, refer to example 1.
The method is simple, just comment out the following part from f_EUTRA_RRC_ActivateSecurity in EUTRA_SecuritySteps.ttcn.
function f_EUTRA_RRC_ActivateSecurity(CellId_Type p_CellId, EUTRA_SecurityParams_Type p_SecurityParams, NasCount_Type p_NasCountUL) runs on EUTRA_PTC return EUTRA_SecurityParams_Type { var EUTRA_SecurityParams_Type v_SecurityParams := f_EUTRA_Authentication_InitAS(p_SecurityParams, p_NasCountUL); /* Calculate Kenb and KRRCenc, KRRCint, KUPenc */
// Read PDCP SQN for SRB1 and calcuate Ciphering Activation times v_SecurityParams.AS_Ciphering.ActTimeList := f_EUTRA_RRC_CipherActTime_Get(p_CellId); /* note: this works only when timing info is now */
// Note by default DRB is also pre-configured on SS side
//f_EUTRA_SS_RRC_EnableIntProt_CiphULandDL (p_CellId, // v_SecurityParams.AS_Integrity , // v_SecurityParams.AS_Ciphering);
f_EUTRA_RRC_InitialSecurityActivation(p_CellId, v_SecurityParams.AS_Integrity.Algorithm, v_SecurityParams.AS_Ciphering.Algorithm); /* SecurityModeComplete is not ciphered acc. to 36.331 cl. 5.3.4.3 and 5.3.1.1 */
return (v_SecurityParams); };
RRC Connection Reconfiguration Changes
Example 1 > 'Omit' SRS Configuration --------------------------------------------------------------
This example is for modifying the IE (information element) of the RRC Connection Reconfiguration message, shown in red below.
| +-physicalConfigDedicated ::= SEQUENCE [0000110010] OPTIONAL:Exist | +-pdsch-ConfigDedicated ::= SEQUENCE OPTIONAL:Omit | +-pucch-ConfigDedicated ::= SEQUENCE OPTIONAL:Omit | +-pusch-ConfigDedicated ::= SEQUENCE OPTIONAL:Omit | +-uplinkPowerControlDedicated ::= SEQUENCE OPTIONAL:Omit | +-tpc-PDCCH-ConfigPUCCH ::= CHOICE [setup] OPTIONAL:Exist | | +-setup ::= SEQUENCE | | +-tpc-RNTI ::= BIT STRING SIZE(16) [0000001111111111] | | +-tpc-Index ::= CHOICE [indexOfFormat3] | | +-indexOfFormat3 ::= INTEGER (1..15) [1] | +-tpc-PDCCH-ConfigPUSCH ::= CHOICE [setup] OPTIONAL:Exist | | +-setup ::= SEQUENCE | | +-tpc-RNTI ::= BIT STRING SIZE(16) [0000000111111010] | | +-tpc-Index ::= CHOICE [indexOfFormat3] | | +-indexOfFormat3 ::= INTEGER (1..15) [1] | +-cqi-ReportConfig ::= SEQUENCE OPTIONAL:Omit | +-soundingRS-UL-ConfigDedicated ::= CHOICE OPTIONAL:Omit | +-antennaInfo ::= CHOICE [explicitValue] OPTIONAL:Exist | | +-explicitValue ::= SEQUENCE [0] | | +-transmissionMode ::= ENUMERATED [tm1] | | +-codebookSubsetRestriction ::= CHOICE OPTIONAL:Omit | | +-ue-TransmitAntennaSelection ::= CHOICE [release] | | +-release ::= NULL | +-schedulingRequestConfig ::= CHOICE OPTIONAL:Omit
Overall steps are as follows :
a) f_EUTRA_RRCConnectionReconfigurationWithPiggyNAS (EUTRA_RRCSteps.ttcn) b) --> cs_RRCConnectionReconfiguration_SRB2_1AM_DRB_Est (EUTRA_RRCTemplates.ttcn) c) --> cs_RRCConnectionReconfiguration_SRB2_1AM_DRB_Est (EUTRA_RRCTemplates.ttcn)
First you have to find where to start. The starting point in this case is f_EUTRA_RRCConnectionReconfigurationWithPiggyNAS in EUTRA_RRCSteps.ttcn as shown below. The RRC Reconfiguration part is configured as in red.
function f_EUTRA_RRCConnectionReconfigurationWithPiggyNAS( CellId_Type p_CellId, RRC_TransactionIdentifier p_RRC_TI, template (value) NAS_MSG_Request_Type p_NAS_MSG_Request) runs on EUTRA_PTC { var template (value) EUTRA_FDD_TDD_CellInfo_Type v_EUTRA_FDD_TDD_CellInfo := f_EUTRA_CellInfo_GetFDD_TDD_Info ( p_CellId ); var template (value) PhysicalConfigDedicated_AntennaInfo_Type v_AntennaInfo := f_EUTRA_CellInfo_GetAntennaInfoDedicated (p_CellId);
SRB.send(cas_SRB1_RrcNasPdu_REQ ( p_CellId, cs_TimingInfo_Now, cs_RRCConnectionReconfiguration_SRB2_1AM_DRB_Est( p_RRC_TI, v_EUTRA_FDD_TDD_CellInfo.cqi_ReportConfig, v_EUTRA_FDD_TDD_CellInfo.soundingRS_UL_Config, v_AntennaInfo ), p_NAS_MSG_Request));
//Receive RRCConnectionReconfigurationComplete SRB.receive(car_SRB1_RrcPdu_IND(p_CellId, cr_508_RRCConnectionReconfigurationComplete(p_RRC_TI))); };
Let's dig into one step further into cs_RRCConnectionReconfiguration_SRB2_1AM_DRB_Est to see which specific parameter we have to change. This is the place where you really change the values in this example. Change the red part as shown in the blue.
template (value) DL_DCCH_Message cs_RRCConnectionReconfiguration_SRB2_1AM_DRB_Est( RRC_TransactionIdentifier p_RRC_TI, template (omit) CQI_ReportPeriodic p_CQI_ReportingPeriodic, template (omit) SoundingRS_UL_ConfigDedicated p_SoundingRsUl_ConfigDedicated, template (value) PhysicalConfigDedicated_AntennaInfo_Type p_AntennaInfo // @sic R5-100786 sic@ ) := /* Values according to 36.508 cl. 4.6.1 Table 4.6.1-8 (using condition SRB2-DRB(n, m), where n=1 & m=0) */ /* @status APPROVED */ cs_RRCConnectionReconfiguration_Common(p_RRC_TI, omit, omit, //cs_SRB2_1AM_DRB_Config_Def(p_CQI_ReportingPeriodic, // p_SoundingRsUl_ConfigDedicated,p_AntennaInfo ), cs_SRB2_1AM_DRB_Config_Def_RIM(omit, omit,p_AntennaInfo) omit);
This is all you need to change in this example, but just for a reference let's look into cs_RRCConnectionReconfiguration_Common on step further. The part below shows the real message structure (ASN structure) of RRC Connection Reconfiguration Message.
template (value) DL_DCCH_Message cs_RRCConnectionReconfiguration_Common( RRC_TransactionIdentifier p_RRC_TI, template (omit) MeasConfig p_MeasurementConfiguration, template (omit) MobilityControlInfo p_MobilityControlInformation, template (omit) RadioResourceConfigDedicated p_RadioResourceConfigDedicated, template (omit) SecurityConfigHO p_SecurityConfiguration) := { /* @status APPROVED */ message_ := { c1 := { rrcConnectionReconfiguration := { rrc_TransactionIdentifier := p_RRC_TI, criticalExtensions := { c1 := { rrcConnectionReconfiguration_r8 := { measConfig := p_MeasurementConfiguration, mobilityControlInfo := p_MobilityControlInformation, dedicatedInfoNASList := omit, radioResourceConfigDedicated := p_RadioResourceConfigDedicated, securityConfigHO := p_SecurityConfiguration, nonCriticalExtension := omit } } } } } } };
|