blob: d3548e72d6e5664eca670dfc2a0888ec97ac0cf1 [file] [log] [blame]
Harald Weltea814f262017-07-24 13:21:35 +02001///////////////////////////////////////////////////////////////////////////////
2// //
3// Copyright Test Competence Center (TCC) ETH 2016 //
4// //
5// The copyright to the computer program(s) herein is the property of TCC. //
6// The program(s) may be used and/or copied only with the written permission //
7// of TCC or in accordance with the terms and conditions stipulated in the //
8// agreement/contract under which the program(s) has been supplied. //
9// //
10///////////////////////////////////////////////////////////////////////////////
11//
12// File: GTPC_EncDec.cc
13// Rev: R1B
14// Prodnr: CNL 113 843
15// Contact: http://ttcn.ericsson.se
16// Reference: 3GPP TS 29.060 v13.5.0
17
18#include "GTPC_Types.hh"
19
20namespace GTPC__Types {
21
22
23// find the length of the optional part and decode optional part into OPT_PART
24int find_optpart_length(const unsigned char * opt_part_ptr,GTPC__Header__optional__part& OPT_PART)// pointer to opt part start
25{
26 int opt_part_length = 4; // mandatory minimum length of opt_part
27 OPT_PART.sequenceNumber() = OCTETSTRING(2,opt_part_ptr);
28 OPT_PART.npduNumber() = OCTETSTRING(1,opt_part_ptr+2);
29 OPT_PART.nextExtHeader() = OCTETSTRING(1,opt_part_ptr+3);
30 OPT_PART.gTPC__extensionHeader__List() = OMIT_VALUE;
31
32 int i = 0;
33 bool opt_part_end = false;
34 while(!opt_part_end)
35 {
36 if (opt_part_ptr[opt_part_length-1] != 0x00) // 0x00 means end of optional part
37 {
38 unsigned char lengthfield = opt_part_ptr[opt_part_length];
39
40 OPT_PART.gTPC__extensionHeader__List()()[i].lengthfield() = lengthfield;
41 OPT_PART.gTPC__extensionHeader__List()()[i].content() =
42 OCTETSTRING(4*lengthfield-2,opt_part_ptr + opt_part_length +1);
43 OPT_PART.gTPC__extensionHeader__List()()[i].nextExtHeader() =
44 OCTETSTRING(1,opt_part_ptr + opt_part_length + 4*lengthfield - 1);
45
46 opt_part_length = opt_part_length + 4*lengthfield;
47 i++;
48 }
49 else
50 {opt_part_end = true;}
51 }
52
53 return opt_part_length;
54}
55
56
57void dec__PDU__GTPC_no_optional_part(const unsigned char * udp__pdu,const int pl_udp_pdu_length, const SystemUnderTest& pl__SystemUnderTest,PDU__GTPC& pdu)
58{
59 TTCN_Buffer buf;
60
61 if ((pl__SystemUnderTest == SystemUnderTest::GGSN) || (pl__SystemUnderTest == SystemUnderTest::CGW))
62 // testing GGSN or CGW (not default)
63 {
64 const unsigned char *gtpc_message = (const unsigned char *) udp__pdu;
65 if ((gtpc_message[1] == 0x12) || (gtpc_message[1] == 0x13))
66 // if updatePDPContextRequest or updatePDPContextResponse message is received from GGSN or C-GW
67 {
68 unsigned char pn = gtpc_message[0] & 0x01;
69 pdu.pn__bit() = BITSTRING(1,&pn);
70
71 unsigned char s = (gtpc_message[0] & 0x02) >> 1;
72 pdu.s__bit() = BITSTRING(1,&s);
73
74 unsigned char e = (gtpc_message[0] & 0x04) >> 2;
75 pdu.e__bit() = BITSTRING(1,&e);
76
77 unsigned char spare = (gtpc_message[0] & 0x08) >> 3;
78 pdu.spare() = BITSTRING(1,&spare );
79
80 unsigned char pt = (gtpc_message[0] & 0x10) >> 4;
81 pdu.pt() = BITSTRING(1,&pt );
82
83 unsigned char version = ((gtpc_message[0] & 0x80) >> 7) |
84 ((gtpc_message[0] & 0x40) >> 5) |
85 ((gtpc_message[0] & 0x20) >> 3) ;
86 pdu.version() = BITSTRING(3,&version);
87
88 pdu.messageType() = OCTETSTRING(1,gtpc_message+1);
89
90 pdu.lengthf() = (gtpc_message[2] << 8) + gtpc_message[3];
91
92 pdu.teid() = OCTETSTRING(4,gtpc_message+4);
93
94 pdu.opt__part() = OMIT_VALUE;
95
96 if (gtpc_message[1] == 0x12) //updatePDPContextRequest
97 {
98 if(pl__SystemUnderTest == SystemUnderTest::GGSN) // from GGSN
99 {
100 UpdatePDPContextRequestGGSN updatePDPContextRequestGGSN;
101 OCTETSTRING updatePDPContextRequestGGSN_string = OCTETSTRING(pl_udp_pdu_length-8,udp__pdu+8 );
102 buf.put_os(updatePDPContextRequestGGSN_string);
103 updatePDPContextRequestGGSN.decode(UpdatePDPContextRequestGGSN_descr_,buf,TTCN_EncDec::CT_RAW);
104 pdu.gtpc__pdu().updatePDPContextRequest().updatePDPContextRequestGGSN() = updatePDPContextRequestGGSN;
105 }
106 else // from CGW
107 {
108 UpdatePDPContextRequestCGW updatePDPContextRequestCGW;
109 OCTETSTRING updatePDPContextRequestCGW_string = OCTETSTRING(pl_udp_pdu_length-8,udp__pdu+8 );
110 buf.put_os(updatePDPContextRequestCGW_string);
111 updatePDPContextRequestCGW.decode(UpdatePDPContextRequestCGW_descr_,buf,TTCN_EncDec::CT_RAW);
112 pdu.gtpc__pdu().updatePDPContextRequest().updatePDPContextRequestCGW() = updatePDPContextRequestCGW;
113 }
114 }
115 else //updatePDPContextResponse
116 {
117 if(pl__SystemUnderTest == SystemUnderTest::GGSN) // from GGSN
118 {
119 UpdatePDPContextResponseGGSN updatePDPContextResponseGGSN;
120 OCTETSTRING updatePDPContextResponseGGSN_string = OCTETSTRING(pl_udp_pdu_length-8,udp__pdu+8 );
121 buf.put_os(updatePDPContextResponseGGSN_string);
122 updatePDPContextResponseGGSN.decode(UpdatePDPContextResponseGGSN_descr_,buf,TTCN_EncDec::CT_RAW);
123 pdu.gtpc__pdu().updatePDPContextResponse().updatePDPContextResponseGGSN() = updatePDPContextResponseGGSN;
124 }
125 else // from CGW
126 {
127 UpdatePDPContextResponseCGW updatePDPContextResponseCGW;
128 OCTETSTRING updatePDPContextResponseCGW_string = OCTETSTRING(pl_udp_pdu_length-8,udp__pdu+8 );
129 buf.put_os(updatePDPContextResponseCGW_string);
130 updatePDPContextResponseCGW.decode(UpdatePDPContextResponseCGW_descr_,buf,TTCN_EncDec::CT_RAW);
131 pdu.gtpc__pdu().updatePDPContextResponse().updatePDPContextResponseCGW() = updatePDPContextResponseCGW;
132 }
133 }
134
135 buf.clear();
136 return;
137 }
138 else // if message not equal to updatePDPContextRequest or updatePDPContextResponse is received from GGSN or C-GW
139 {
140 buf.put_s(pl_udp_pdu_length,udp__pdu);
141 pdu.decode(PDU__GTPC_descr_, buf, TTCN_EncDec::CT_RAW);
142 buf.clear();
143 return;
144 }
145 }
146 else //pl__SystemUnderTest is SGSN or MME (this is default)
147 {
148 buf.put_s(pl_udp_pdu_length,udp__pdu);
149 pdu.decode(PDU__GTPC_descr_, buf, TTCN_EncDec::CT_RAW);
150 buf.clear();
151 return;
152 }
153}
154
155//////////////////////////////////
156// Decoding function for GTPC__DialoguePDU
157//////////////////////////////////
158
159PDU__GTPC dec__PDU__GTPC(const OCTETSTRING& udp__pdu,const SystemUnderTest& pl__SystemUnderTest)
160{
161 PDU__GTPC pdu;
162
163 const unsigned char *gtpc_message = (const unsigned char *) udp__pdu;
164
165 int opt_part_length = 0;
166 if ( gtpc_message[0] & 0x07 ) // opt_part is present
167 {
168 GTPC__Header__optional__part OPT_PART;
169
170 // find the length of the optional part and decode optional part into OPT_PART
171 opt_part_length = find_optpart_length(gtpc_message+8,OPT_PART);
172 if( ((gtpc_message[2] << 8) + gtpc_message[3] - opt_part_length) < 0 )
173 {TTCN_error("Decoding error, lengthf field is shorter that decoded length of opt_part");}
174
175 // build PDU without optional part
176 unsigned int gtpc_IEs_length = (gtpc_message[2] << 8) + gtpc_message[3] - opt_part_length;
177 unsigned char gtpcBuf[8 + gtpc_IEs_length];
178 memcpy(gtpcBuf,gtpc_message,8);
179 memcpy(gtpcBuf+8,gtpc_message+8+opt_part_length,gtpc_IEs_length);
180
181 // substitute dummy bits (indicating there is no optional part)
182 gtpcBuf[0] = gtpcBuf[0] & 0xf8;
183
184 // substitute dummy length (not including optional part)
185 gtpcBuf[2] = (gtpc_IEs_length & 0xff00) >> 8;
186 gtpcBuf[3] = gtpc_IEs_length & 0xff;
187
188 // call decoding function
189 dec__PDU__GTPC_no_optional_part(gtpcBuf,udp__pdu.lengthof() - opt_part_length,pl__SystemUnderTest,pdu);
190
191 // put back the original values
192 unsigned char pn = gtpc_message[0] & 0x01;
193 pdu.pn__bit() = BITSTRING(1,&pn);
194
195 unsigned char s = (gtpc_message[0] & 0x02) >> 1;
196 pdu.s__bit() = BITSTRING(1,&s);
197
198 unsigned char e = (gtpc_message[0] & 0x04) >> 2;
199 pdu.e__bit() = BITSTRING(1,&e);
200
201 pdu.lengthf() = (gtpc_message[2] << 8) + gtpc_message[3];
202
203 pdu.opt__part() = OPT_PART;
204
205 return pdu;
206 }
207 else // opt_part is not present
208 {
209 dec__PDU__GTPC_no_optional_part(gtpc_message,udp__pdu.lengthof(),pl__SystemUnderTest,pdu);
210 return pdu;
211 }
212} // end of function
213
214
215
216}//namespace