blob: f93a2ab8016b1b233da854db84ca0d38031276d1 [file] [log] [blame]
Harald Weltef8db61b2015-12-18 17:29:59 +01001/* high-level RANAP messsage generation code */
2
3/* (C) 2015 by Harald Welte <laforge@gnumonks.org>
4 * All Rights Reserved
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Affero General Public License for more details.
15 *
16 * You should have received a copy of the GNU Affero General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
21#include <osmocom/core/utils.h>
22#include <osmocom/core/msgb.h>
23
24#include "asn1helpers.h"
Neels Hofmeyr96979af2016-01-05 15:19:44 +010025#include <osmocom/ranap/iu_helpers.h>
Harald Weltef8db61b2015-12-18 17:29:59 +010026
Neels Hofmeyr96979af2016-01-05 15:19:44 +010027#include <osmocom/ranap/ranap_common.h>
28#include <osmocom/ranap/ranap_ies_defs.h>
29#include <osmocom/ranap/ranap_msg_factory.h>
Harald Weltef8db61b2015-12-18 17:29:59 +010030
Harald Weltebdf3fd12016-01-03 17:04:09 +010031#define DRANAP _ranap_DRANAP
Harald Weltef8db61b2015-12-18 17:29:59 +010032
33/*! \brief allocate a new long and assing a value to it */
34static long *new_long(long in)
35{
36 long *out = CALLOC(1, sizeof(long));
37 *out = in;
38 return out;
39}
40
Harald Weltec4338de2015-12-24 00:40:52 +010041/*! \brief generate RANAP RESET message */
42struct msgb *ranap_new_msg_reset(RANAP_CN_DomainIndicator_t domain,
Harald Welte1cdb81d2016-01-01 16:21:05 +010043 const RANAP_Cause_t *cause)
Harald Weltec4338de2015-12-24 00:40:52 +010044{
45 RANAP_ResetIEs_t ies;
46 RANAP_Reset_t out;
47 struct msgb *msg;
48 int rc;
49
50 memset(&ies, 0, sizeof(ies));
51 ies.cN_DomainIndicator = domain;
52 if (cause)
53 memcpy(&ies.cause, cause, sizeof(ies.cause));
54
55 memset(&out, 0, sizeof(out));
56 rc = ranap_encode_reseties(&out, &ies);
57 if (rc < 0) {
58 LOGP(DRANAP, LOGL_ERROR, "error encoding reset IEs: %d\n", rc);
59 return NULL;
60 }
61
62 msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_Reset,
63 RANAP_Criticality_reject,
64 &asn_DEF_RANAP_Reset,
65 &out);
66
67 /* release dynamic allocations attached to dt */
68 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_Reset, &out);
69
70 return msg;
71}
72
73/*! \brief generate RANAP RESET ACK message */
74struct msgb *ranap_new_msg_reset_ack(RANAP_CN_DomainIndicator_t domain,
75 RANAP_GlobalRNC_ID_t *rnc_id)
76{
77 RANAP_ResetAcknowledgeIEs_t ies;
78 RANAP_ResetAcknowledge_t out;
79 struct msgb *msg;
80 int rc;
81
82 memset(&ies, 0, sizeof(ies));
83 ies.cN_DomainIndicator = domain;
84
85 /* The RNC shall include the globalRNC_ID in the RESET
86 * ACKNOWLEDGE message to the CN */
87 if (rnc_id) {
88 ies.presenceMask = RESETACKNOWLEDGEIES_RANAP_GLOBALRNC_ID_PRESENT;
Harald Welte74157f62016-01-01 16:43:59 +010089 OCTET_STRING_noalloc(&ies.globalRNC_ID.pLMNidentity,
Harald Welteea98b6f2015-12-24 15:09:06 +010090 rnc_id->pLMNidentity.buf,
91 rnc_id->pLMNidentity.size);
Harald Weltec4338de2015-12-24 00:40:52 +010092 ies.globalRNC_ID.rNC_ID = rnc_id->rNC_ID;
93 }
94
95 /* FIXME: Do we need criticalityDiagnostics */
96
97 memset(&out, 0, sizeof(out));
98 rc = ranap_encode_resetacknowledgeies(&out, &ies);
99 if (rc < 0) {
100 LOGP(DRANAP, LOGL_ERROR, "error encoding reset ack IEs: %d\n", rc);
101 return NULL;
102 }
103
104 msg = ranap_generate_successful_outcome(RANAP_ProcedureCode_id_Reset,
105 RANAP_Criticality_reject,
106 &asn_DEF_RANAP_ResetAcknowledge,
107 &out);
108
109 /* release dynamic allocations attached to dt */
110 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_ResetAcknowledge, &out);
111
112 return msg;
113}
114
Harald Welteea98b6f2015-12-24 15:09:06 +0100115/*! \brief generate RANAP INITIAL UE message */
116struct msgb *ranap_new_msg_initial_ue(uint32_t conn_id, int is_ps,
117 RANAP_GlobalRNC_ID_t *rnc_id,
118 uint8_t *nas_pdu, unsigned int nas_len)
119{
120 RANAP_InitialUE_MessageIEs_t ies;
121 RANAP_InitialUE_Message_t out;
122 struct msgb *msg;
123 uint32_t ctxidbuf;
124 int rc;
125 uint16_t buf0 = 0x2342;
126
127 memset(&ies, 0, sizeof(ies));
128 if (is_ps)
129 ies.cN_DomainIndicator = RANAP_CN_DomainIndicator_ps_domain;
130 else
131 ies.cN_DomainIndicator = RANAP_CN_DomainIndicator_cs_domain;
132
Harald Welte74157f62016-01-01 16:43:59 +0100133 OCTET_STRING_noalloc(&ies.lai.pLMNidentity, rnc_id->pLMNidentity.buf, rnc_id->pLMNidentity.size);
134 OCTET_STRING_noalloc(&ies.lai.lAC, (uint8_t *)&buf0, sizeof(buf0));
Harald Welteea98b6f2015-12-24 15:09:06 +0100135
Harald Welte74157f62016-01-01 16:43:59 +0100136 OCTET_STRING_noalloc(&ies.sai.pLMNidentity, rnc_id->pLMNidentity.buf, rnc_id->pLMNidentity.size);
137 OCTET_STRING_noalloc(&ies.sai.lAC, (uint8_t *)&buf0, sizeof(buf0));
138 OCTET_STRING_noalloc(&ies.sai.sAC, (uint8_t *)&buf0, sizeof(buf0));
Harald Welteea98b6f2015-12-24 15:09:06 +0100139
Harald Welte74157f62016-01-01 16:43:59 +0100140 OCTET_STRING_noalloc(&ies.nas_pdu, nas_pdu, nas_len);
Harald Welteea98b6f2015-12-24 15:09:06 +0100141 asn1_u24_to_bitstring(&ies.iuSigConId, &ctxidbuf, conn_id);
Harald Welte74157f62016-01-01 16:43:59 +0100142 OCTET_STRING_noalloc(&ies.globalRNC_ID.pLMNidentity, rnc_id->pLMNidentity.buf, rnc_id->pLMNidentity.size);
Harald Welteea98b6f2015-12-24 15:09:06 +0100143 ies.globalRNC_ID.rNC_ID = rnc_id->rNC_ID;
144
145 memset(&out, 0, sizeof(out));
146 rc = ranap_encode_initialue_messageies(&out, &ies);
147 if (rc < 0) {
148 LOGP(DRANAP, LOGL_ERROR, "error encoding initial UE IEs: %d\n", rc);
149 return NULL;
150 }
151
152 msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_InitialUE_Message,
Harald Welte11b1dde2019-04-20 22:37:14 +0200153 RANAP_Criticality_ignore,
Harald Welteea98b6f2015-12-24 15:09:06 +0100154 &asn_DEF_RANAP_InitialUE_Message,
155 &out);
156
157 /* release dynamic allocations attached to dt */
158 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_InitialUE_Message, &out);
159
160 return msg;
161}
162
163
Harald Weltef8db61b2015-12-18 17:29:59 +0100164/*! \brief generate RANAP DIRECT TRANSFER message */
165struct msgb *ranap_new_msg_dt(uint8_t sapi, const uint8_t *nas, unsigned int nas_len)
166{
167 RANAP_DirectTransferIEs_t ies;
168 RANAP_DirectTransfer_t dt;
169 struct msgb *msg;
170 int rc;
171
172 memset(&ies, 0, sizeof(ies));
173 memset(&dt, 0, sizeof(dt));
174
175 /* only SAPI optional field shall be present for CN->RNC */
176 ies.presenceMask = DIRECTTRANSFERIES_RANAP_SAPI_PRESENT;
177
178 if (sapi == 3)
179 ies.sapi = RANAP_SAPI_sapi_3;
180 else
181 ies.sapi = RANAP_SAPI_sapi_0;
182
Harald Welte74157f62016-01-01 16:43:59 +0100183 /* Avoid copying + later freeing of OCTET STRING */
184 OCTET_STRING_noalloc(&ies.nas_pdu, nas, nas_len);
Harald Weltef8db61b2015-12-18 17:29:59 +0100185
186 /* ies -> dt */
187 rc = ranap_encode_directtransferies(&dt, &ies);
Philipp Maier1eb19cf2017-12-19 17:46:36 +0100188 if (rc < 0) {
189 LOGP(DRANAP, LOGL_ERROR, "error encoding direct transfer IEs: %d\n", rc);
190 return NULL;
191 }
Harald Weltef8db61b2015-12-18 17:29:59 +0100192
193 /* dt -> msg */
194 msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_DirectTransfer,
Harald Welte11b1dde2019-04-20 22:37:14 +0200195 RANAP_Criticality_ignore,
Harald Weltef8db61b2015-12-18 17:29:59 +0100196 &asn_DEF_RANAP_DirectTransfer,
197 &dt);
198
199 /* release dynamic allocations attached to dt */
200 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_DirectTransfer, &dt);
201
202 return msg;
203}
204
Harald Weltee3f707b2021-02-06 15:55:48 +0100205/*! \brief generate RANAP SECURITY MODE COMMAND message.
206 * \param[in] ik 128bit integrity protection key (mandatory)
207 * \param[in] ck 128bit ciphering key (optional)
208 * \param[in] status key status
209 * \param[in] uia_bitmask bit-mask of UIA algorithms; Bit0 = UIA0 .. Bit2 = UIA2
210 * \param[in] uea_bitmask bit-mask of UEA algorithms; Bit0 = UEA0 .. Bit2 = UEA2; ck required
211 * \returns message buffer with encoded command message */
212struct msgb *ranap_new_msg_sec_mod_cmd2(const uint8_t *ik, const uint8_t *ck, enum RANAP_KeyStatus status,
213 uint8_t uia_bitmask, uint8_t uea_bitmask)
Harald Weltef8db61b2015-12-18 17:29:59 +0100214{
215 RANAP_SecurityModeCommandIEs_t ies;
216 RANAP_SecurityModeCommand_t out;
217 struct msgb *msg;
218 int i, rc;
219
220 memset(&ies, 0, sizeof(ies));
221 memset(&out, 0, sizeof(out));
222
Harald Weltee3f707b2021-02-06 15:55:48 +0100223 for (i = 0; i < 8; i++) {
224 RANAP_IntegrityProtectionAlgorithm_t ialg;
225 if (!(uia_bitmask & (1 << i)))
226 continue;
227 switch (i) {
228 case 1:
229 ialg = RANAP_IntegrityProtectionAlgorithm_standard_UMTS_integrity_algorithm_UIA1;
230 break;
231 case 2:
232 ialg = RANAP_IntegrityProtectionAlgorithm_standard_UMTS_integrity_algorithm_UIA2;
233 break;
234 default:
Harald Weltee8299eb2021-02-11 10:14:57 +0100235 LOGP(DRANAP, LOGL_ERROR, "Unsupported UIA algorithm UIA%d specified\n", i);
Harald Weltee3f707b2021-02-06 15:55:48 +0100236 return NULL;
237 }
238
Harald Weltef8db61b2015-12-18 17:29:59 +0100239 /* needs to be dynamically allocated, as
240 * SET_OF_free() will call FREEMEM() on it */
241 RANAP_IntegrityProtectionAlgorithm_t *alg = CALLOC(1, sizeof(*alg));
Harald Weltee3f707b2021-02-06 15:55:48 +0100242 *alg = ialg;
Harald Weltef8db61b2015-12-18 17:29:59 +0100243 ASN_SEQUENCE_ADD(&ies.integrityProtectionInformation.permittedAlgorithms, alg);
244 }
245
246 BIT_STRING_fromBuf(&ies.integrityProtectionInformation.key, ik, 16*8);
247
248 if (ck) {
Harald Welte2cf0d8f2015-12-28 13:13:47 +0100249 ies.presenceMask = SECURITYMODECOMMANDIES_RANAP_ENCRYPTIONINFORMATION_PRESENT;
Harald Weltee3f707b2021-02-06 15:55:48 +0100250 for (i = 0; i < 8; i++) {
251 RANAP_EncryptionAlgorithm_t ealg;
252 if (!(uea_bitmask & (1 << i)))
253 continue;
254 switch (i) {
255 case 1:
256 ealg = RANAP_EncryptionAlgorithm_standard_UMTS_encryption_algorith_UEA1;
257 break;
258 case 2:
259 ealg = RANAP_EncryptionAlgorithm_standard_UMTS_encryption_algorithm_UEA2;
260 break;
261 default:
Harald Weltee8299eb2021-02-11 10:14:57 +0100262 LOGP(DRANAP, LOGL_ERROR, "Unsupported UEA algorithm UEA%d specified\n", i);
Harald Weltee3f707b2021-02-06 15:55:48 +0100263 asn_set_empty(&ies.integrityProtectionInformation.permittedAlgorithms);
264 return NULL;
265 }
266
Harald Weltef8db61b2015-12-18 17:29:59 +0100267 /* needs to be dynamically allocated, as
268 * SET_OF_free() will call FREEMEM() on it */
269 RANAP_EncryptionAlgorithm_t *alg = CALLOC(1, sizeof(*alg));
Harald Weltee3f707b2021-02-06 15:55:48 +0100270 *alg = ealg;
Harald Weltef8db61b2015-12-18 17:29:59 +0100271 ASN_SEQUENCE_ADD(&ies.encryptionInformation.permittedAlgorithms, alg);
272 }
273 BIT_STRING_fromBuf(&ies.encryptionInformation.key, ck, 16*8);
274 }
275
Daniel Willmannf44d12c2016-04-20 10:16:37 +0200276 ies.keyStatus = status;
Harald Weltef8db61b2015-12-18 17:29:59 +0100277
278 /* ies -> out */
279 rc = ranap_encode_securitymodecommandies(&out, &ies);
280
281 /* release dynamic allocations attached to ies */
282 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_IntegrityProtectionInformation, &ies.integrityProtectionInformation);
Harald Welte2cf0d8f2015-12-28 13:13:47 +0100283 if (ck)
284 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_EncryptionInformation, &ies.encryptionInformation);
Harald Weltef8db61b2015-12-18 17:29:59 +0100285
Philipp Maier1eb19cf2017-12-19 17:46:36 +0100286 if (rc < 0) {
287 LOGP(DRANAP, LOGL_ERROR, "error encoding security mode command IEs: %d\n", rc);
288 return NULL;
289 }
290
Harald Weltef8db61b2015-12-18 17:29:59 +0100291 /* out -> msg */
292 msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_SecurityModeControl,
293 RANAP_Criticality_reject,
294 &asn_DEF_RANAP_SecurityModeCommand,
295 &out);
296
297 /* release dynamic allocations attached to out */
298 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_SecurityModeCommand, &out);
299
300 return msg;
301}
Harald Weltee3f707b2021-02-06 15:55:48 +0100302struct msgb *ranap_new_msg_sec_mod_cmd(const uint8_t *ik, const uint8_t *ck, enum RANAP_KeyStatus status)
303{
304 return ranap_new_msg_sec_mod_cmd2(ik, ck, status, 0x06, 0x06);
305}
Harald Weltef8db61b2015-12-18 17:29:59 +0100306
Neels Hofmeyr7e760acc2016-04-19 01:41:17 +0200307/*! \brief generate RANAP SECURITY MODE COMPLETE message */
Neels Hofmeyra9f55662016-04-19 01:21:41 +0200308struct msgb *ranap_new_msg_sec_mod_compl(
309 RANAP_ChosenIntegrityProtectionAlgorithm_t chosen_ip_alg,
310 RANAP_ChosenEncryptionAlgorithm_t chosen_enc_alg)
311{
312 RANAP_SecurityModeCompleteIEs_t ies;
313 RANAP_SecurityModeComplete_t out;
314 struct msgb *msg;
Philipp Maieraa8d48c2017-12-19 17:48:38 +0100315 int rc;
Neels Hofmeyra9f55662016-04-19 01:21:41 +0200316
317 memset(&ies, 0, sizeof(ies));
318 memset(&out, 0, sizeof(out));
319
320 ies.presenceMask = SECURITYMODECOMPLETEIES_RANAP_CHOSENENCRYPTIONALGORITHM_PRESENT;
321 ies.chosenIntegrityProtectionAlgorithm = chosen_ip_alg;
322 ies.chosenEncryptionAlgorithm = chosen_enc_alg;
323
324 /* ies -> out */
325 rc = ranap_encode_securitymodecompleteies(&out, &ies);
Philipp Maier1eb19cf2017-12-19 17:46:36 +0100326 if (rc < 0) {
327 LOGP(DRANAP, LOGL_ERROR, "error encoding security mode complete IEs: %d\n", rc);
328 return NULL;
329 }
Neels Hofmeyra9f55662016-04-19 01:21:41 +0200330
331 /* out -> msg */
332 msg = ranap_generate_successful_outcome(RANAP_ProcedureCode_id_SecurityModeControl,
333 RANAP_Criticality_reject,
334 &asn_DEF_RANAP_SecurityModeComplete,
335 &out);
336
337 /* release dynamic allocations attached to out */
338 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_SecurityModeComplete, &out);
339
340 return msg;
341}
342
Harald Weltef8db61b2015-12-18 17:29:59 +0100343/*! \brief generate RANAP COMMON ID message */
344struct msgb *ranap_new_msg_common_id(const char *imsi)
345{
346 RANAP_CommonID_IEs_t ies;
347 RANAP_CommonID_t out;
348 struct msgb *msg;
349 int rc;
350
351 memset(&ies, 0, sizeof(ies));
352 memset(&out, 0, sizeof(out));
353
354 if (imsi) {
355 uint8_t *imsi_buf = CALLOC(1, 16);
Harald Welte056984f2016-01-03 16:31:31 +0100356 rc = ranap_imsi_encode(imsi_buf, 16, imsi);
Harald Weltef8db61b2015-12-18 17:29:59 +0100357 ies.permanentNAS_UE_ID.present = RANAP_PermanentNAS_UE_ID_PR_iMSI;
358 ies.permanentNAS_UE_ID.choice.iMSI.buf = imsi_buf;
359 ies.permanentNAS_UE_ID.choice.iMSI.size = rc;
360 } else
361 ies.permanentNAS_UE_ID.present = RANAP_PermanentNAS_UE_ID_PR_NOTHING;
362
363 /* ies -> out */
364 rc = ranap_encode_commonid_ies(&out, &ies);
Philipp Maier1eb19cf2017-12-19 17:46:36 +0100365
Harald Weltef8db61b2015-12-18 17:29:59 +0100366 /* release dynamic allocations attached to ies */
367 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_PermanentNAS_UE_ID, &ies.permanentNAS_UE_ID);
Philipp Maier1eb19cf2017-12-19 17:46:36 +0100368
369 if (rc < 0) {
370 LOGP(DRANAP, LOGL_ERROR, "error encoding common id IEs: %d\n", rc);
Harald Weltef8db61b2015-12-18 17:29:59 +0100371 return NULL;
Philipp Maier1eb19cf2017-12-19 17:46:36 +0100372 }
Harald Weltef8db61b2015-12-18 17:29:59 +0100373
374 /* out -> msg */
375 msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_CommonID,
376 RANAP_Criticality_ignore,
377 &asn_DEF_RANAP_CommonID,
378 &out);
379
380 /* release dynamic allocations attached to out */
381 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_CommonID, &out);
382
383 return msg;
384}
385
386/*! \brief generate RANAP IU RELEASE COMMAND message */
387struct msgb *ranap_new_msg_iu_rel_cmd(const RANAP_Cause_t *cause_in)
388{
389 RANAP_Iu_ReleaseCommandIEs_t ies;
390 RANAP_Iu_ReleaseCommand_t out;
391 struct msgb *msg;
392 int rc;
393
394 memset(&ies, 0, sizeof(ies));
395 memset(&out, 0, sizeof(out));
396
397 memcpy(&ies.cause, cause_in, sizeof(ies.cause));
398
399 /* ies -> out */
400 rc = ranap_encode_iu_releasecommandies(&out, &ies);
Philipp Maier1eb19cf2017-12-19 17:46:36 +0100401 if (rc < 0) {
402 LOGP(DRANAP, LOGL_ERROR, "error encoding release command IEs: %d\n", rc);
Harald Weltef8db61b2015-12-18 17:29:59 +0100403 return NULL;
Philipp Maier1eb19cf2017-12-19 17:46:36 +0100404 }
Harald Weltef8db61b2015-12-18 17:29:59 +0100405
406 /* out -> msg */
407 msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_Iu_Release,
408 RANAP_Criticality_reject,
409 &asn_DEF_RANAP_Iu_ReleaseCommand,
410 &out);
411
412 /* release dynamic allocations attached to out */
413 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_Iu_ReleaseCommand, &out);
414
415 return msg;
416}
417
Neels Hofmeyrf6e16b72016-04-19 02:32:05 +0200418/*! \brief generate RAPAP IU RELEASE COMPLETE message */
419struct msgb *ranap_new_msg_iu_rel_compl(void)
420{
421 RANAP_Iu_ReleaseCompleteIEs_t ies;
422 RANAP_Iu_ReleaseComplete_t out;
423 struct msgb *msg;
424 int rc;
425
426 memset(&ies, 0, sizeof(ies));
427 memset(&out, 0, sizeof(out));
428
429 /* ies -> out */
430 rc = ranap_encode_iu_releasecompleteies(&out, &ies);
Philipp Maier1eb19cf2017-12-19 17:46:36 +0100431 if (rc < 0) {
432 LOGP(DRANAP, LOGL_ERROR, "error encoding release complete IEs: %d\n", rc);
Neels Hofmeyrf6e16b72016-04-19 02:32:05 +0200433 return NULL;
Philipp Maier1eb19cf2017-12-19 17:46:36 +0100434 }
Neels Hofmeyrf6e16b72016-04-19 02:32:05 +0200435
436 /* out -> msg */
437 msg = ranap_generate_successful_outcome(RANAP_ProcedureCode_id_Iu_Release,
438 RANAP_Criticality_reject,
439 &asn_DEF_RANAP_Iu_ReleaseComplete,
440 &out);
441
442 /* release dynamic allocations attached to out */
443 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_Iu_ReleaseComplete, &out);
444
445 return msg;
446}
447
Harald Weltef8db61b2015-12-18 17:29:59 +0100448/*! \brief generate RANAP PAGING COMMAND message */
449struct msgb *ranap_new_msg_paging_cmd(const char *imsi, const uint32_t *tmsi, int is_ps, uint32_t cause)
450{
451 RANAP_PagingIEs_t ies;
452 RANAP_Paging_t out;
453 struct msgb *msg;
454 uint8_t *imsi_buf = CALLOC(1, 16);
455 int rc;
456
457 memset(&ies, 0, sizeof(ies));
458 memset(&out, 0, sizeof(out));
459
460 /* put together the 'ies' */
461 if (is_ps)
462 ies.cN_DomainIndicator = RANAP_CN_DomainIndicator_ps_domain;
463 else
464 ies.cN_DomainIndicator = RANAP_CN_DomainIndicator_cs_domain;
465
Harald Welte056984f2016-01-03 16:31:31 +0100466 rc = ranap_imsi_encode(imsi_buf, 16, imsi);
Harald Weltef8db61b2015-12-18 17:29:59 +0100467 ies.permanentNAS_UE_ID.present = RANAP_PermanentNAS_UE_ID_PR_iMSI;
468 ies.permanentNAS_UE_ID.choice.iMSI.buf = imsi_buf;
469 ies.permanentNAS_UE_ID.choice.iMSI.size = rc;
470
471 if (tmsi) {
472 uint32_t *tmsi_buf = CALLOC(1, sizeof(*tmsi_buf));
Harald Weltef8db61b2015-12-18 17:29:59 +0100473 ies.presenceMask |= PAGINGIES_RANAP_TEMPORARYUE_ID_PRESENT;
474 if (is_ps) {
475 ies.temporaryUE_ID.present = RANAP_TemporaryUE_ID_PR_p_TMSI;
Daniel Willmanna9cf70f2016-05-04 13:50:43 +0200476 asn1_u32_to_str(&ies.temporaryUE_ID.choice.tMSI, tmsi_buf, *tmsi);
Harald Weltef8db61b2015-12-18 17:29:59 +0100477 } else {
478 ies.temporaryUE_ID.present = RANAP_TemporaryUE_ID_PR_tMSI;
Daniel Willmanna9cf70f2016-05-04 13:50:43 +0200479 asn1_u32_to_str(&ies.temporaryUE_ID.choice.p_TMSI, tmsi_buf, *tmsi);
Harald Weltef8db61b2015-12-18 17:29:59 +0100480 }
481 }
482
483 if (cause) {
484 ies.presenceMask |= PAGINGIES_RANAP_PAGINGCAUSE_PRESENT;
485 ies.pagingCause = cause;
486 }
487
488 /* ies -> out */
489 rc = ranap_encode_pagingies(&out, &ies);
Philipp Maier1eb19cf2017-12-19 17:46:36 +0100490
Harald Weltef8db61b2015-12-18 17:29:59 +0100491 /* release dynamic allocation attached to ies */
492 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_PermanentNAS_UE_ID, &ies.permanentNAS_UE_ID);
493 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_TemporaryUE_ID, &ies.temporaryUE_ID);
Philipp Maier1eb19cf2017-12-19 17:46:36 +0100494
495 if (rc < 0) {
496 LOGP(DRANAP, LOGL_ERROR, "error encoding paging IEs: %d\n", rc);
Harald Weltef8db61b2015-12-18 17:29:59 +0100497 return NULL;
Philipp Maier1eb19cf2017-12-19 17:46:36 +0100498 }
Harald Weltef8db61b2015-12-18 17:29:59 +0100499
500 /* out -> msg */
501 msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_Paging,
Harald Welte11b1dde2019-04-20 22:37:14 +0200502 RANAP_Criticality_ignore,
Harald Weltef8db61b2015-12-18 17:29:59 +0100503 &asn_DEF_RANAP_Paging,
504 &out);
505
506 /* release dynamic allocations attached to out */
507 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_Paging, &out);
508
509 return msg;
510}
511
512static RANAP_SDU_ErrorRatio_t *new_sdu_error_ratio(long mantissa, long exponent)
513{
514 RANAP_SDU_ErrorRatio_t *err = CALLOC(1, sizeof(*err));
515
516 err->mantissa = mantissa;
517 err->exponent = exponent;
518
519 return err;
520}
521
522
523static RANAP_SDU_FormatInformationParameterItem_t *
524new_format_info_pars(long sdu_size)
525{
526 RANAP_SDU_FormatInformationParameterItem_t *fmti = CALLOC(1, sizeof(*fmti));
527 fmti->subflowSDU_Size = new_long(sdu_size);
528 return fmti;
529}
530
531enum sdu_par_profile {
532 SDUPAR_P_VOICE0,
533 SDUPAR_P_VOICE1,
534 SDUPAR_P_VOICE2,
535 SDUPAR_P_DATA,
536};
537
538/* See Chapter 5 of TS 26.102 */
539static RANAP_SDU_ParameterItem_t *new_sdu_par_item(enum sdu_par_profile profile)
540{
541 RANAP_SDU_ParameterItem_t *sdui = CALLOC(1, sizeof(*sdui));
542 RANAP_SDU_FormatInformationParameters_t *fmtip = CALLOC(1, sizeof(*fmtip));
543 RANAP_SDU_FormatInformationParameterItem_t *fmti;
544
545 switch (profile) {
546 case SDUPAR_P_VOICE0:
547 sdui->sDU_ErrorRatio = new_sdu_error_ratio(1, 5);
548 sdui->residualBitErrorRatio.mantissa = 1;
549 sdui->residualBitErrorRatio.exponent = 6;
550 sdui->deliveryOfErroneousSDU = RANAP_DeliveryOfErroneousSDU_yes;
551 sdui->sDU_FormatInformationParameters = fmtip;
552 fmti = new_format_info_pars(81);
553 ASN_SEQUENCE_ADD(fmtip, fmti);
554 fmti = new_format_info_pars(39);
555 ASN_SEQUENCE_ADD(fmtip, fmti);
556 /* FIXME: could be 10 SDU descriptors for AMR! */
557 break;
558 case SDUPAR_P_VOICE1:
559 sdui->residualBitErrorRatio.mantissa = 1;
560 sdui->residualBitErrorRatio.exponent = 3;
561 sdui->deliveryOfErroneousSDU = RANAP_DeliveryOfErroneousSDU_no_error_detection_consideration;
562 sdui->sDU_FormatInformationParameters = fmtip;
563 fmti = new_format_info_pars(103);
564 ASN_SEQUENCE_ADD(fmtip, fmti);
565 fmti = new_format_info_pars(0);
566 ASN_SEQUENCE_ADD(fmtip, fmti);
567 /* FIXME: could be 10 SDU descriptors for AMR! */
568 break;
569 case SDUPAR_P_VOICE2:
570 sdui->residualBitErrorRatio.mantissa = 5;
571 sdui->residualBitErrorRatio.exponent = 3;
572 sdui->deliveryOfErroneousSDU = RANAP_DeliveryOfErroneousSDU_no_error_detection_consideration;
573 sdui->sDU_FormatInformationParameters = fmtip;
574 fmti = new_format_info_pars(60);
575 ASN_SEQUENCE_ADD(fmtip, fmti);
576 fmti = new_format_info_pars(0);
577 ASN_SEQUENCE_ADD(fmtip, fmti);
578 /* FIXME: could be 10 SDU descriptors for AMR! */
579 break;
580 case SDUPAR_P_DATA:
581 sdui->sDU_ErrorRatio = new_sdu_error_ratio(1, 4);
582 sdui->residualBitErrorRatio.mantissa = 1;
583 sdui->residualBitErrorRatio.exponent = 5;
584 sdui->deliveryOfErroneousSDU = RANAP_DeliveryOfErroneousSDU_no;
585 FREEMEM(fmtip);
586 break;
587 }
588
589 return sdui;
590}
591
592static RANAP_AllocationOrRetentionPriority_t *
593new_alloc_ret_prio(RANAP_PriorityLevel_t level, int capability, int vulnerability,
594 int queueing_allowed)
595{
596 RANAP_AllocationOrRetentionPriority_t *arp = CALLOC(1, sizeof(*arp));
597
598 arp->priorityLevel = level;
599
600 if (capability)
601 arp->pre_emptionCapability = RANAP_Pre_emptionCapability_may_trigger_pre_emption;
602 else
603 arp->pre_emptionCapability = RANAP_Pre_emptionCapability_shall_not_trigger_pre_emption;
604
605 if (vulnerability)
606 arp->pre_emptionVulnerability = RANAP_Pre_emptionVulnerability_pre_emptable;
607 else
608 arp->pre_emptionVulnerability = RANAP_Pre_emptionVulnerability_not_pre_emptable;
609
610 if (queueing_allowed)
611 arp->queuingAllowed = RANAP_QueuingAllowed_queueing_allowed;
612 else
613 arp->queuingAllowed = RANAP_QueuingAllowed_queueing_not_allowed;
614
615 return arp;
616}
617
618/* See Chapter 5 of TS 26.102 */
Neels Hofmeyr8e29b232017-01-23 16:36:11 +0100619static RANAP_RAB_Parameters_t *new_rab_par_voice(long bitrate_guaranteed,
620 long bitrate_max)
Harald Weltef8db61b2015-12-18 17:29:59 +0100621{
622 RANAP_RAB_Parameters_t *rab = CALLOC(1, sizeof(*rab));
623 RANAP_SDU_ParameterItem_t *sdui;
624
625 rab->trafficClass = RANAP_TrafficClass_conversational;
626 rab->rAB_AsymmetryIndicator = RANAP_RAB_AsymmetryIndicator_symmetric_bidirectional;
627
Neels Hofmeyr8e29b232017-01-23 16:36:11 +0100628 ASN_SEQUENCE_ADD(&rab->maxBitrate.list, new_long(bitrate_max));
Harald Weltef8db61b2015-12-18 17:29:59 +0100629 rab->guaranteedBitRate = CALLOC(1, sizeof(*rab->guaranteedBitRate));
Neels Hofmeyr8e29b232017-01-23 16:36:11 +0100630 ASN_SEQUENCE_ADD(rab->guaranteedBitRate, new_long(bitrate_guaranteed));
Harald Weltef8db61b2015-12-18 17:29:59 +0100631 rab->deliveryOrder = RANAP_DeliveryOrder_delivery_order_requested;
632 rab->maxSDU_Size = 244;
633
634 sdui = new_sdu_par_item(SDUPAR_P_VOICE0);
635 ASN_SEQUENCE_ADD(&rab->sDU_Parameters, sdui);
636 sdui = new_sdu_par_item(SDUPAR_P_VOICE1);
637 ASN_SEQUENCE_ADD(&rab->sDU_Parameters, sdui);
638 sdui = new_sdu_par_item(SDUPAR_P_VOICE2);
639 ASN_SEQUENCE_ADD(&rab->sDU_Parameters, sdui);
640
641 rab->transferDelay = new_long(80);
642 rab->allocationOrRetentionPriority = new_alloc_ret_prio(RANAP_PriorityLevel_no_priority, 0, 1, 0);
643
644 rab->sourceStatisticsDescriptor = new_long(RANAP_SourceStatisticsDescriptor_speech);
645
646 return rab;
647}
648
Neels Hofmeyrad14ff92017-01-23 15:06:40 +0100649static RANAP_NAS_SynchronisationIndicator_t *new_rab_nas_sync_ind(int val)
650{
651 uint8_t val_buf = (val / 10) << 4;
652 RANAP_NAS_SynchronisationIndicator_t *nsi = CALLOC(1, sizeof(*nsi));
653 BIT_STRING_fromBuf(nsi, &val_buf, 4);
654 return nsi;
655}
656
Harald Welte05ac6772015-12-29 19:09:52 +0100657static RANAP_RAB_Parameters_t *new_rab_par_data(uint32_t dl_max_bitrate, uint32_t ul_max_bitrate)
Harald Weltef8db61b2015-12-18 17:29:59 +0100658{
659 RANAP_RAB_Parameters_t *rab = CALLOC(1, sizeof(*rab));
660 RANAP_SDU_ParameterItem_t *sdui;
661
662 rab->trafficClass = RANAP_TrafficClass_background;
663 rab->rAB_AsymmetryIndicator = RANAP_RAB_AsymmetryIndicator_asymmetric_bidirectional;
664
Harald Welte05ac6772015-12-29 19:09:52 +0100665 ASN_SEQUENCE_ADD(&rab->maxBitrate.list, new_long(dl_max_bitrate));
666 ASN_SEQUENCE_ADD(&rab->maxBitrate.list, new_long(ul_max_bitrate));
Harald Weltef8db61b2015-12-18 17:29:59 +0100667 rab->deliveryOrder = RANAP_DeliveryOrder_delivery_order_requested;
668 rab->maxSDU_Size = 8000;
669
670 sdui = new_sdu_par_item(SDUPAR_P_DATA);
671 ASN_SEQUENCE_ADD(&rab->sDU_Parameters, sdui);
672
673 rab->allocationOrRetentionPriority = new_alloc_ret_prio(RANAP_PriorityLevel_no_priority, 0, 0, 0);
674
Harald Weltebb289e32016-05-01 15:20:56 +0200675 RANAP_ProtocolExtensionField_t *pxf = CALLOC(1, sizeof(*pxf));
676 pxf->id = RANAP_ProtocolIE_ID_id_RAB_Parameter_ExtendedMaxBitrateList;
677 pxf->criticality = RANAP_Criticality_ignore;
678
679 RANAP_RAB_Parameter_ExtendedMaxBitrateList_t *rab_mbrlist = CALLOC(1, sizeof(*rab_mbrlist));
680 RANAP_ExtendedMaxBitrate_t *xmbr = CALLOC(1, sizeof(*xmbr));
681 *xmbr = 42000000;
682 ASN_SEQUENCE_ADD(&rab_mbrlist->list, xmbr);
683
684 ANY_fromType_aper(&pxf->value, &asn_DEF_RANAP_RAB_Parameter_ExtendedMaxBitrateList, rab_mbrlist);
685
686 ASN_STRUCT_FREE(asn_DEF_RANAP_RAB_Parameter_ExtendedMaxBitrateList, rab_mbrlist);
687
688 rab->iE_Extensions = CALLOC(1, sizeof(*rab->iE_Extensions));
689 ASN_SEQUENCE_ADD(&rab->iE_Extensions->list, pxf);
Harald Weltef8db61b2015-12-18 17:29:59 +0100690
691 return rab;
692}
693
Neels Hofmeyredf13672016-04-23 13:50:46 +0200694static void new_transp_layer_addr(BIT_STRING_t *out, uint32_t ip, bool use_x213_nsap)
Harald Weltebfe49a22015-12-28 13:14:52 +0100695{
696 uint8_t *buf;
697 unsigned int len;
Neels Hofmeyr54df0a12017-11-18 21:00:41 +0100698 uint32_t ip_h = ntohl(ip);
Harald Weltebfe49a22015-12-28 13:14:52 +0100699
700 if (use_x213_nsap) {
Neels Hofmeyr135bc062017-01-23 16:49:20 +0100701 len = 160/8;
Harald Weltebfe49a22015-12-28 13:14:52 +0100702 buf = CALLOC(len, sizeof(uint8_t));
703 buf[0] = 0x35; /* AFI For IANA ICP */
704 buf[1] = 0x00; /* See A.5.2.1.2.7 of X.213 */
705 buf[2] = 0x01;
Neels Hofmeyr54df0a12017-11-18 21:00:41 +0100706 memcpy(&buf[3], &ip_h, sizeof(ip_h));
Harald Weltebfe49a22015-12-28 13:14:52 +0100707 } else {
Neels Hofmeyr54df0a12017-11-18 21:00:41 +0100708 len = sizeof(ip_h);
Harald Weltebfe49a22015-12-28 13:14:52 +0100709 buf = CALLOC(len, sizeof(uint8_t));
Neels Hofmeyr54df0a12017-11-18 21:00:41 +0100710 memcpy(buf, &ip_h, sizeof(ip_h));
Harald Weltebfe49a22015-12-28 13:14:52 +0100711 }
712 out->buf = buf;
713 out->size = len;
714 out->bits_unused = 0;
715}
716
Neels Hofmeyrf6673b72016-09-08 15:39:18 +0200717static RANAP_TransportLayerInformation_t *new_transp_info_rtp(uint32_t ip, uint16_t port,
718 bool use_x213_nsap)
Harald Weltef8db61b2015-12-18 17:29:59 +0100719{
720 RANAP_TransportLayerInformation_t *tli = CALLOC(1, sizeof(*tli));
Harald Weltef8db61b2015-12-18 17:29:59 +0100721 uint8_t binding_id[4];
722
723 binding_id[0] = port >> 8;
724 binding_id[1] = port & 0xff;
725 binding_id[2] = binding_id[3] = 0;
726
Neels Hofmeyrf6673b72016-09-08 15:39:18 +0200727 new_transp_layer_addr(&tli->transportLayerAddress, ip, use_x213_nsap);
Harald Weltef8db61b2015-12-18 17:29:59 +0100728 tli->iuTransportAssociation.present = RANAP_IuTransportAssociation_PR_bindingID;
729 OCTET_STRING_fromBuf(&tli->iuTransportAssociation.choice.bindingID,
730 (const char *) binding_id, sizeof(binding_id));
731
732 return tli;
733}
734
Neels Hofmeyredf13672016-04-23 13:50:46 +0200735static RANAP_TransportLayerInformation_t *new_transp_info_gtp(uint32_t ip, uint32_t tei,
736 bool use_x213_nsap)
Harald Weltef8db61b2015-12-18 17:29:59 +0100737{
738 RANAP_TransportLayerInformation_t *tli = CALLOC(1, sizeof(*tli));
Harald Welte01de8d72015-12-29 19:10:48 +0100739 uint32_t binding_buf = htonl(tei);
Harald Weltef8db61b2015-12-18 17:29:59 +0100740
Neels Hofmeyredf13672016-04-23 13:50:46 +0200741 new_transp_layer_addr(&tli->transportLayerAddress, ip, use_x213_nsap);
Harald Weltef8db61b2015-12-18 17:29:59 +0100742 tli->iuTransportAssociation.present = RANAP_IuTransportAssociation_PR_gTP_TEI;
Harald Welte01de8d72015-12-29 19:10:48 +0100743 OCTET_STRING_fromBuf(&tli->iuTransportAssociation.choice.gTP_TEI,
Harald Weltef8db61b2015-12-18 17:29:59 +0100744 (const char *) &binding_buf, sizeof(binding_buf));
745
746 return tli;
747}
748
749static RANAP_UserPlaneInformation_t *new_upi(long mode, uint8_t mode_versions)
750{
751 RANAP_UserPlaneInformation_t *upi = CALLOC(1, sizeof(*upi));
752 uint16_t *buf = CALLOC(1, sizeof(*buf));
753
Daniel Willmann49f99cd2016-01-26 09:37:22 +0100754 *buf = ntohs(mode_versions);
Harald Weltef8db61b2015-12-18 17:29:59 +0100755
756 upi->userPlaneMode = mode;
Harald Weltef9c9aa52015-12-24 15:39:00 +0100757 upi->uP_ModeVersions.buf = (uint8_t *) buf;
Harald Weltef8db61b2015-12-18 17:29:59 +0100758 upi->uP_ModeVersions.size = sizeof(*buf);
759 upi->uP_ModeVersions.bits_unused = 0;
760
761 return upi;
762}
763
764
765static void assign_new_ra_id(RANAP_RAB_ID_t *id, uint8_t rab_id)
766{
767 uint8_t *buf = CALLOC(1, sizeof(*buf));
Harald Welte0a3eafe2015-12-19 02:38:09 +0100768 *buf = rab_id;
Harald Weltef8db61b2015-12-18 17:29:59 +0100769
770 id->buf = buf;
771 id->size = 1;
772 id->bits_unused = 0;
773}
774
Neels Hofmeyr74b05652016-09-09 01:25:22 +0200775/*! \brief generate RANAP RAB ASSIGNMENT REQUEST message for CS (voice).
776 * See 3GPP TS 25.413 8.2.
Neels Hofmeyre90f13e2017-11-20 17:18:03 +0100777 * RAB ID: 3GPP TS 25.413 9.2.1.2.
778 * \param rtp_ip MGW's RTP IPv4 address in *network* byte order.
Neels Hofmeyr74b05652016-09-09 01:25:22 +0200779 */
Neels Hofmeyrf6673b72016-09-08 15:39:18 +0200780struct msgb *ranap_new_msg_rab_assign_voice(uint8_t rab_id, uint32_t rtp_ip,
781 uint16_t rtp_port,
782 bool use_x213_nsap)
Harald Weltef8db61b2015-12-18 17:29:59 +0100783{
784 RANAP_ProtocolIE_FieldPair_t *pair;
785 RANAP_RAB_AssignmentRequestIEs_t ies;
786 RANAP_RAB_AssignmentRequest_t out;
787 struct msgb *msg;
788 int rc;
789
790 memset(&ies, 0, sizeof(ies));
791 memset(&out, 0, sizeof(out));
792
793 /* only assingnment is present, no release */
794 ies.presenceMask = RAB_ASSIGNMENTREQUESTIES_RANAP_RAB_SETUPORMODIFYLIST_PRESENT;
795
796 /* put together the 'First' part */
797 RANAP_RAB_SetupOrModifyItemFirst_t first;
798 memset(&first, 0, sizeof(first));
799 assign_new_ra_id(&first.rAB_ID, rab_id);
Neels Hofmeyrad14ff92017-01-23 15:06:40 +0100800 first.nAS_SynchronisationIndicator = new_rab_nas_sync_ind(60);
Neels Hofmeyr8e29b232017-01-23 16:36:11 +0100801 first.rAB_Parameters = new_rab_par_voice(6700, 12200);
Harald Weltef8db61b2015-12-18 17:29:59 +0100802 first.userPlaneInformation = new_upi(RANAP_UserPlaneMode_support_mode_for_predefined_SDU_sizes, 1); /* 2? */
Neels Hofmeyrf6673b72016-09-08 15:39:18 +0200803 first.transportLayerInformation = new_transp_info_rtp(rtp_ip, rtp_port,
804 use_x213_nsap);
Harald Weltef8db61b2015-12-18 17:29:59 +0100805
806 /* put together the 'Second' part */
807 RANAP_RAB_SetupOrModifyItemSecond_t second;
808 memset(&second, 0, sizeof(second));
809
810 /* Build an IE Pair out of first and second part:
811 * (first, second) -> pair */
812 pair = ranap_new_ie_pair(RANAP_ProtocolIE_ID_id_RAB_SetupOrModifyItem,
813 RANAP_Criticality_reject,
814 &asn_DEF_RANAP_RAB_SetupOrModifyItemFirst, &first,
815 RANAP_Criticality_ignore,
816 &asn_DEF_RANAP_RAB_SetupOrModifyItemSecond, &second);
817
818 /* the pair has been made, we can release any of its elements */
819 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_SetupOrModifyItemFirst, &first);
820 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_SetupOrModifyItemSecond, &second);
821
Harald Welteb7f67c42015-12-19 02:36:52 +0100822 RANAP_ProtocolIE_ContainerPair_t *container_pair = CALLOC(1, sizeof(*container_pair));
Harald Weltef8db61b2015-12-18 17:29:59 +0100823 /* Add the pair to the list of IEs of the RAB ass.req */
Harald Welteb7f67c42015-12-19 02:36:52 +0100824 ASN_SEQUENCE_ADD(container_pair, pair);
825 ASN_SEQUENCE_ADD(&ies.raB_SetupOrModifyList.list, container_pair);
Harald Weltef8db61b2015-12-18 17:29:59 +0100826
827 /* encode the IEs into the actual assignment request:
828 * ies -> out */
829 rc = ranap_encode_rab_assignmentrequesties(&out, &ies);
830 /* 'out' has been generated, we can now release the input */
831 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_SetupOrModifyList,
832 &ies.raB_SetupOrModifyList);
833 if (rc < 0)
834 return NULL;
835
836 /* generate an Initiating Mesasage: out -> msg */
837 msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_RAB_Assignment,
838 RANAP_Criticality_reject,
839 &asn_DEF_RANAP_RAB_AssignmentRequest, &out);
840
841 /* 'msg' has been generated, we cann now release the input 'out' */
842 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_AssignmentRequest, &out);
843
844 return msg;
845}
846
Neels Hofmeyre90f13e2017-11-20 17:18:03 +0100847/*! \brief generate RANAP RAB ASSIGNMENT REQUEST message for PS (data)
848 * \param gtp_ip SGSN's GTP IPv4 address in *network* byte order. */
Neels Hofmeyredf13672016-04-23 13:50:46 +0200849struct msgb *ranap_new_msg_rab_assign_data(uint8_t rab_id, uint32_t gtp_ip,
850 uint32_t gtp_tei, bool use_x213_nsap)
Harald Weltef8db61b2015-12-18 17:29:59 +0100851{
852 RANAP_ProtocolIE_FieldPair_t *pair;
853 RANAP_RAB_AssignmentRequestIEs_t ies;
854 RANAP_RAB_AssignmentRequest_t out;
855 RANAP_DataVolumeReportingIndication_t *dat_vol_ind;
856 struct msgb *msg;
857 int rc;
858
859 memset(&ies, 0, sizeof(ies));
860 memset(&out, 0, sizeof(out));
861
862 /* only assingnment is present, no release */
863 ies.presenceMask = RAB_ASSIGNMENTREQUESTIES_RANAP_RAB_SETUPORMODIFYLIST_PRESENT;
864
865 /* put together the 'First' part */
866 RANAP_RAB_SetupOrModifyItemFirst_t first;
867 memset(&first, 0, sizeof(first));
868 assign_new_ra_id(&first.rAB_ID, rab_id);
869 //first.nAS_SynchronisationIndicator = FIXME;
Harald Welte05ac6772015-12-29 19:09:52 +0100870
871 first.rAB_Parameters = new_rab_par_data(1600000, 800000);
Harald Weltef8db61b2015-12-18 17:29:59 +0100872 first.userPlaneInformation = new_upi(RANAP_UserPlaneMode_transparent_mode, 1);
Neels Hofmeyredf13672016-04-23 13:50:46 +0200873 first.transportLayerInformation = new_transp_info_gtp(gtp_ip, gtp_tei,
874 use_x213_nsap);
Harald Weltef8db61b2015-12-18 17:29:59 +0100875
876 /* put together the 'Second' part */
877 RANAP_RAB_SetupOrModifyItemSecond_t second;
878 memset(&second, 0, sizeof(second));
879 second.pDP_TypeInformation = CALLOC(1, sizeof(*second.pDP_TypeInformation));
880 ASN_SEQUENCE_ADD(second.pDP_TypeInformation, new_long(RANAP_PDP_Type_ipv4));
881 dat_vol_ind = CALLOC(1, sizeof(*dat_vol_ind));
882 *dat_vol_ind = RANAP_DataVolumeReportingIndication_do_not_report;
883 second.dataVolumeReportingIndication = dat_vol_ind;
884 second.dl_GTP_PDU_SequenceNumber = new_long(0);
885 second.ul_GTP_PDU_SequenceNumber = new_long(0);
886
887 /* Build an IE Pair out of first and second part:
888 * (first, second) -> pair */
889 pair = ranap_new_ie_pair(RANAP_ProtocolIE_ID_id_RAB_SetupOrModifyItem,
890 RANAP_Criticality_reject,
891 &asn_DEF_RANAP_RAB_SetupOrModifyItemFirst,
892 &first, RANAP_Criticality_ignore,
893 &asn_DEF_RANAP_RAB_SetupOrModifyItemSecond,
894 &second);
895
896 /* the pair has been made, we can release any of its elements */
897 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_SetupOrModifyItemFirst, &first);
898 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_SetupOrModifyItemSecond, &second);
899
Harald Welteb7f67c42015-12-19 02:36:52 +0100900 RANAP_ProtocolIE_ContainerPair_t *container_pair = CALLOC(1, sizeof(*container_pair));
Harald Weltef8db61b2015-12-18 17:29:59 +0100901 /* Add the pair to the list of IEs of the RAB ass.req */
Neels Hofmeyr9246cc92016-04-25 14:47:26 +0200902 ASN_SEQUENCE_ADD(&container_pair->list, pair);
Harald Welteb7f67c42015-12-19 02:36:52 +0100903 /* Add the pair to the list of IEs of the RAB ass.req */
904 ASN_SEQUENCE_ADD(&ies.raB_SetupOrModifyList.list, container_pair);
Harald Weltef8db61b2015-12-18 17:29:59 +0100905
906 /* encode the IEs into the actual assignment request:
907 * ies -> out */
908 rc = ranap_encode_rab_assignmentrequesties(&out, &ies);
909 /* 'out' has been generated, we can now release the input */
910 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_SetupOrModifyList,
911 &ies.raB_SetupOrModifyList);
912 if (rc < 0)
913 return NULL;
914
915 /* generate an Initiating Mesasage: out -> msg */
916 msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_RAB_Assignment,
917 RANAP_Criticality_reject,
918 &asn_DEF_RANAP_RAB_AssignmentRequest, &out);
919
920 /* 'msg' has been generated, we cann now release the input 'out' */
921 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_AssignmentRequest, &out);
922
923 return msg;
924}
Harald Welte37223d82016-01-01 16:18:55 +0100925
926struct msgb *ranap_new_msg_iu_rel_req(const RANAP_Cause_t *cause)
927{
928 RANAP_Iu_ReleaseRequestIEs_t ies;
929 RANAP_Iu_ReleaseRequest_t out;
930 struct msgb *msg;
931 int rc;
932
933 memset(&ies, 0, sizeof(ies));
934 memset(&out, 0, sizeof(out));
935
936 memcpy(&ies.cause, cause, sizeof(ies.cause));
937
938 rc = ranap_encode_iu_releaserequesties(&out, &ies);
Philipp Maier1eb19cf2017-12-19 17:46:36 +0100939 if (rc < 0) {
940 LOGP(DRANAP, LOGL_ERROR, "error encoding release request IEs: %d\n", rc);
941 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_Iu_ReleaseRequest, &out);
Harald Welte37223d82016-01-01 16:18:55 +0100942 return NULL;
Philipp Maier1eb19cf2017-12-19 17:46:36 +0100943 }
Harald Welte37223d82016-01-01 16:18:55 +0100944
945 /* encode the output into the msgb */
946 msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_Iu_ReleaseRequest,
Harald Welte11b1dde2019-04-20 22:37:14 +0200947 RANAP_Criticality_ignore,
Harald Welte37223d82016-01-01 16:18:55 +0100948 &asn_DEF_RANAP_Iu_ReleaseRequest, &out);
Philipp Maier1eb19cf2017-12-19 17:46:36 +0100949
Harald Welte37223d82016-01-01 16:18:55 +0100950 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_Iu_ReleaseRequest, &out);
951
952 return msg;
953}
954
955struct msgb *ranap_new_msg_rab_rel_req(uint8_t rab_id, const RANAP_Cause_t *cause)
956{
957 RANAP_RAB_ReleaseItemIEs_t item_ies;
958 RANAP_RAB_ReleaseRequestIEs_t ies;
959 RANAP_RAB_ReleaseRequest_t out;
960 struct msgb *msg;
961 int rc;
962
963 memset(&item_ies, 0, sizeof(item_ies));
964 memset(&ies, 0, sizeof(ies));
965 memset(&out, 0, sizeof(out));
966
967 /* put together the ReleaseItem */
968 assign_new_ra_id(&item_ies.raB_ReleaseItem.rAB_ID, rab_id);
969 memcpy(&item_ies.raB_ReleaseItem.cause, cause, sizeof(item_ies.raB_ReleaseItem.cause));
970
971 /* add to the list */
972 rc = ranap_encode_rab_releaseitemies(&ies.raB_ReleaseList, &item_ies);
973 if (rc < 0)
974 return NULL;
975 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_ReleaseItem, &item_ies.raB_ReleaseItem);
976
977 /* encoe the list IEs into the output */
978 rc = ranap_encode_rab_releaserequesties(&out, &ies);
Philipp Maier1eb19cf2017-12-19 17:46:36 +0100979
Harald Welte37223d82016-01-01 16:18:55 +0100980 /* 'out' has been generated, we can release the input */
981 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_ReleaseList, &ies.raB_ReleaseList);
982
Philipp Maier1eb19cf2017-12-19 17:46:36 +0100983 if (rc < 0) {
984 LOGP(DRANAP, LOGL_ERROR, "error encoding release request IEs: %d\n", rc);
985 return NULL;
986 }
987
Harald Welte37223d82016-01-01 16:18:55 +0100988 /* encode the output into the msgb */
989 msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_RAB_ReleaseRequest,
Harald Welte11b1dde2019-04-20 22:37:14 +0200990 RANAP_Criticality_ignore,
Harald Welte37223d82016-01-01 16:18:55 +0100991 &asn_DEF_RANAP_RAB_ReleaseRequest, &out);
992
993 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_ReleaseRequest, &out);
994
995 return msg;
996}