blob: 41c4fbee8529922f7d12767f2e6df56c0a1a1a0b [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"
25#include "iu_helpers.h"
26
27#include "ranap_common.h"
28#include "ranap_ies_defs.h"
29#include "ranap_msg_factory.h"
30
31#include "hnbgw.h"
32
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,
43 RANAP_Cause_t *cause)
44{
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 Welteea98b6f2015-12-24 15:09:06 +010089 OCTET_STRING_fromBuf(&ies.globalRNC_ID.pLMNidentity,
90 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
133 OCTET_STRING_fromBuf(&ies.lai.pLMNidentity, rnc_id->pLMNidentity.buf, rnc_id->pLMNidentity.size);
Harald Weltef9c9aa52015-12-24 15:39:00 +0100134 OCTET_STRING_fromBuf(&ies.lai.lAC, (uint8_t *)&buf0, sizeof(buf0));
Harald Welteea98b6f2015-12-24 15:09:06 +0100135
136 OCTET_STRING_fromBuf(&ies.sai.pLMNidentity, rnc_id->pLMNidentity.buf, rnc_id->pLMNidentity.size);
Harald Weltef9c9aa52015-12-24 15:39:00 +0100137 OCTET_STRING_fromBuf(&ies.sai.lAC, (uint8_t *)&buf0, sizeof(buf0));
138 OCTET_STRING_fromBuf(&ies.sai.sAC, (uint8_t *)&buf0, sizeof(buf0));
Harald Welteea98b6f2015-12-24 15:09:06 +0100139
140 OCTET_STRING_fromBuf(&ies.nas_pdu, nas_pdu, nas_len);
141 asn1_u24_to_bitstring(&ies.iuSigConId, &ctxidbuf, conn_id);
142 OCTET_STRING_fromBuf(&ies.globalRNC_ID.pLMNidentity, rnc_id->pLMNidentity.buf, rnc_id->pLMNidentity.size);
143 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,
153 RANAP_Criticality_reject,
154 &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 Welte57d87332015-12-24 15:33:21 +0100183 OCTET_STRING_fromBuf(&ies.nas_pdu, nas, nas_len);
Harald Weltef8db61b2015-12-18 17:29:59 +0100184
185 /* ies -> dt */
186 rc = ranap_encode_directtransferies(&dt, &ies);
187
188 /* dt -> msg */
189 msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_DirectTransfer,
190 RANAP_Criticality_reject,
191 &asn_DEF_RANAP_DirectTransfer,
192 &dt);
193
194 /* release dynamic allocations attached to dt */
195 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_DirectTransfer, &dt);
196
197 return msg;
198}
199
200static const enum RANAP_IntegrityProtectionAlgorithm ip_alg[2] = {
201 RANAP_IntegrityProtectionAlgorithm_standard_UMTS_integrity_algorithm_UIA1,
202 RANAP_IntegrityProtectionAlgorithm_standard_UMTS_integrity_algorithm_UIA2,
203};
204
205static const RANAP_EncryptionAlgorithm_t enc_alg[2] = {
206 RANAP_EncryptionAlgorithm_standard_UMTS_encryption_algorith_UEA1,
207 RANAP_EncryptionAlgorithm_standard_UMTS_encryption_algorithm_UEA2,
208};
209
210/*! \brief generate RANAP SECURITY MODE COMMAND message */
211struct msgb *ranap_new_msg_sec_mod_cmd(const uint8_t *ik, const uint8_t *ck)
212{
213 RANAP_SecurityModeCommandIEs_t ies;
214 RANAP_SecurityModeCommand_t out;
215 struct msgb *msg;
216 int i, rc;
217
218 memset(&ies, 0, sizeof(ies));
219 memset(&out, 0, sizeof(out));
220
221 ies.presenceMask = SECURITYMODECOMMANDIES_RANAP_ENCRYPTIONINFORMATION_PRESENT;
222
223 for (i = 0; i < ARRAY_SIZE(ip_alg); i++) {
224 /* needs to be dynamically allocated, as
225 * SET_OF_free() will call FREEMEM() on it */
226 RANAP_IntegrityProtectionAlgorithm_t *alg = CALLOC(1, sizeof(*alg));
227 *alg = ip_alg[i];
228 ASN_SEQUENCE_ADD(&ies.integrityProtectionInformation.permittedAlgorithms, alg);
229 }
230
231 BIT_STRING_fromBuf(&ies.integrityProtectionInformation.key, ik, 16*8);
232
233 if (ck) {
234 for (i = 0; i < ARRAY_SIZE(ip_alg); i++) {
235 /* needs to be dynamically allocated, as
236 * SET_OF_free() will call FREEMEM() on it */
237 RANAP_EncryptionAlgorithm_t *alg = CALLOC(1, sizeof(*alg));
238 *alg = enc_alg[i];
239 ASN_SEQUENCE_ADD(&ies.encryptionInformation.permittedAlgorithms, alg);
240 }
241 BIT_STRING_fromBuf(&ies.encryptionInformation.key, ck, 16*8);
242 }
243
244 ies.keyStatus = RANAP_KeyStatus_new; /* FIXME */
245
246 /* ies -> out */
247 rc = ranap_encode_securitymodecommandies(&out, &ies);
248
249 /* release dynamic allocations attached to ies */
250 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_IntegrityProtectionInformation, &ies.integrityProtectionInformation);
251 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_EncryptionInformation, &ies.encryptionInformation);
252
253 /* out -> msg */
254 msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_SecurityModeControl,
255 RANAP_Criticality_reject,
256 &asn_DEF_RANAP_SecurityModeCommand,
257 &out);
258
259 /* release dynamic allocations attached to out */
260 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_SecurityModeCommand, &out);
261
262 return msg;
263}
264
265/*! \brief generate RANAP COMMON ID message */
266struct msgb *ranap_new_msg_common_id(const char *imsi)
267{
268 RANAP_CommonID_IEs_t ies;
269 RANAP_CommonID_t out;
270 struct msgb *msg;
271 int rc;
272
273 memset(&ies, 0, sizeof(ies));
274 memset(&out, 0, sizeof(out));
275
276 if (imsi) {
277 uint8_t *imsi_buf = CALLOC(1, 16);
278 rc = encode_iu_imsi(imsi_buf, 16, imsi);
279 ies.permanentNAS_UE_ID.present = RANAP_PermanentNAS_UE_ID_PR_iMSI;
280 ies.permanentNAS_UE_ID.choice.iMSI.buf = imsi_buf;
281 ies.permanentNAS_UE_ID.choice.iMSI.size = rc;
282 } else
283 ies.permanentNAS_UE_ID.present = RANAP_PermanentNAS_UE_ID_PR_NOTHING;
284
285 /* ies -> out */
286 rc = ranap_encode_commonid_ies(&out, &ies);
287 /* release dynamic allocations attached to ies */
288 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_PermanentNAS_UE_ID, &ies.permanentNAS_UE_ID);
289 if (rc < 0)
290 return NULL;
291
292 /* out -> msg */
293 msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_CommonID,
294 RANAP_Criticality_ignore,
295 &asn_DEF_RANAP_CommonID,
296 &out);
297
298 /* release dynamic allocations attached to out */
299 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_CommonID, &out);
300
301 return msg;
302}
303
304/*! \brief generate RANAP IU RELEASE COMMAND message */
305struct msgb *ranap_new_msg_iu_rel_cmd(const RANAP_Cause_t *cause_in)
306{
307 RANAP_Iu_ReleaseCommandIEs_t ies;
308 RANAP_Iu_ReleaseCommand_t out;
309 struct msgb *msg;
310 int rc;
311
312 memset(&ies, 0, sizeof(ies));
313 memset(&out, 0, sizeof(out));
314
315 memcpy(&ies.cause, cause_in, sizeof(ies.cause));
316
317 /* ies -> out */
318 rc = ranap_encode_iu_releasecommandies(&out, &ies);
319 if (rc < 0)
320 return NULL;
321
322 /* out -> msg */
323 msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_Iu_Release,
324 RANAP_Criticality_reject,
325 &asn_DEF_RANAP_Iu_ReleaseCommand,
326 &out);
327
328 /* release dynamic allocations attached to out */
329 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_Iu_ReleaseCommand, &out);
330
331 return msg;
332}
333
334/*! \brief generate RANAP PAGING COMMAND message */
335struct msgb *ranap_new_msg_paging_cmd(const char *imsi, const uint32_t *tmsi, int is_ps, uint32_t cause)
336{
337 RANAP_PagingIEs_t ies;
338 RANAP_Paging_t out;
339 struct msgb *msg;
340 uint8_t *imsi_buf = CALLOC(1, 16);
341 int rc;
342
343 memset(&ies, 0, sizeof(ies));
344 memset(&out, 0, sizeof(out));
345
346 /* put together the 'ies' */
347 if (is_ps)
348 ies.cN_DomainIndicator = RANAP_CN_DomainIndicator_ps_domain;
349 else
350 ies.cN_DomainIndicator = RANAP_CN_DomainIndicator_cs_domain;
351
352 rc = encode_iu_imsi(imsi_buf, 16, imsi);
353 ies.permanentNAS_UE_ID.present = RANAP_PermanentNAS_UE_ID_PR_iMSI;
354 ies.permanentNAS_UE_ID.choice.iMSI.buf = imsi_buf;
355 ies.permanentNAS_UE_ID.choice.iMSI.size = rc;
356
357 if (tmsi) {
358 uint32_t *tmsi_buf = CALLOC(1, sizeof(*tmsi_buf));
359 *tmsi_buf = *tmsi;
360 ies.presenceMask |= PAGINGIES_RANAP_TEMPORARYUE_ID_PRESENT;
361 if (is_ps) {
362 ies.temporaryUE_ID.present = RANAP_TemporaryUE_ID_PR_p_TMSI;
Harald Weltef9c9aa52015-12-24 15:39:00 +0100363 ies.temporaryUE_ID.choice.tMSI.buf = (uint8_t *) tmsi_buf;
Harald Weltef8db61b2015-12-18 17:29:59 +0100364 ies.temporaryUE_ID.choice.tMSI.size = sizeof(*tmsi_buf);
365 } else {
366 ies.temporaryUE_ID.present = RANAP_TemporaryUE_ID_PR_tMSI;
Harald Weltef9c9aa52015-12-24 15:39:00 +0100367 ies.temporaryUE_ID.choice.p_TMSI.buf = (uint8_t *) tmsi_buf;
Harald Weltef8db61b2015-12-18 17:29:59 +0100368 ies.temporaryUE_ID.choice.p_TMSI.size = sizeof(*tmsi_buf);
369 }
370 }
371
372 if (cause) {
373 ies.presenceMask |= PAGINGIES_RANAP_PAGINGCAUSE_PRESENT;
374 ies.pagingCause = cause;
375 }
376
377 /* ies -> out */
378 rc = ranap_encode_pagingies(&out, &ies);
379 /* release dynamic allocation attached to ies */
380 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_PermanentNAS_UE_ID, &ies.permanentNAS_UE_ID);
381 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_TemporaryUE_ID, &ies.temporaryUE_ID);
382 if (rc < 0)
383 return NULL;
384
385 /* out -> msg */
386 msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_Paging,
387 RANAP_Criticality_reject,
388 &asn_DEF_RANAP_Paging,
389 &out);
390
391 /* release dynamic allocations attached to out */
392 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_Paging, &out);
393
394 return msg;
395}
396
397static RANAP_SDU_ErrorRatio_t *new_sdu_error_ratio(long mantissa, long exponent)
398{
399 RANAP_SDU_ErrorRatio_t *err = CALLOC(1, sizeof(*err));
400
401 err->mantissa = mantissa;
402 err->exponent = exponent;
403
404 return err;
405}
406
407
408static RANAP_SDU_FormatInformationParameterItem_t *
409new_format_info_pars(long sdu_size)
410{
411 RANAP_SDU_FormatInformationParameterItem_t *fmti = CALLOC(1, sizeof(*fmti));
412 fmti->subflowSDU_Size = new_long(sdu_size);
413 return fmti;
414}
415
416enum sdu_par_profile {
417 SDUPAR_P_VOICE0,
418 SDUPAR_P_VOICE1,
419 SDUPAR_P_VOICE2,
420 SDUPAR_P_DATA,
421};
422
423/* See Chapter 5 of TS 26.102 */
424static RANAP_SDU_ParameterItem_t *new_sdu_par_item(enum sdu_par_profile profile)
425{
426 RANAP_SDU_ParameterItem_t *sdui = CALLOC(1, sizeof(*sdui));
427 RANAP_SDU_FormatInformationParameters_t *fmtip = CALLOC(1, sizeof(*fmtip));
428 RANAP_SDU_FormatInformationParameterItem_t *fmti;
429
430 switch (profile) {
431 case SDUPAR_P_VOICE0:
432 sdui->sDU_ErrorRatio = new_sdu_error_ratio(1, 5);
433 sdui->residualBitErrorRatio.mantissa = 1;
434 sdui->residualBitErrorRatio.exponent = 6;
435 sdui->deliveryOfErroneousSDU = RANAP_DeliveryOfErroneousSDU_yes;
436 sdui->sDU_FormatInformationParameters = fmtip;
437 fmti = new_format_info_pars(81);
438 ASN_SEQUENCE_ADD(fmtip, fmti);
439 fmti = new_format_info_pars(39);
440 ASN_SEQUENCE_ADD(fmtip, fmti);
441 /* FIXME: could be 10 SDU descriptors for AMR! */
442 break;
443 case SDUPAR_P_VOICE1:
444 sdui->residualBitErrorRatio.mantissa = 1;
445 sdui->residualBitErrorRatio.exponent = 3;
446 sdui->deliveryOfErroneousSDU = RANAP_DeliveryOfErroneousSDU_no_error_detection_consideration;
447 sdui->sDU_FormatInformationParameters = fmtip;
448 fmti = new_format_info_pars(103);
449 ASN_SEQUENCE_ADD(fmtip, fmti);
450 fmti = new_format_info_pars(0);
451 ASN_SEQUENCE_ADD(fmtip, fmti);
452 /* FIXME: could be 10 SDU descriptors for AMR! */
453 break;
454 case SDUPAR_P_VOICE2:
455 sdui->residualBitErrorRatio.mantissa = 5;
456 sdui->residualBitErrorRatio.exponent = 3;
457 sdui->deliveryOfErroneousSDU = RANAP_DeliveryOfErroneousSDU_no_error_detection_consideration;
458 sdui->sDU_FormatInformationParameters = fmtip;
459 fmti = new_format_info_pars(60);
460 ASN_SEQUENCE_ADD(fmtip, fmti);
461 fmti = new_format_info_pars(0);
462 ASN_SEQUENCE_ADD(fmtip, fmti);
463 /* FIXME: could be 10 SDU descriptors for AMR! */
464 break;
465 case SDUPAR_P_DATA:
466 sdui->sDU_ErrorRatio = new_sdu_error_ratio(1, 4);
467 sdui->residualBitErrorRatio.mantissa = 1;
468 sdui->residualBitErrorRatio.exponent = 5;
469 sdui->deliveryOfErroneousSDU = RANAP_DeliveryOfErroneousSDU_no;
470 FREEMEM(fmtip);
471 break;
472 }
473
474 return sdui;
475}
476
477static RANAP_AllocationOrRetentionPriority_t *
478new_alloc_ret_prio(RANAP_PriorityLevel_t level, int capability, int vulnerability,
479 int queueing_allowed)
480{
481 RANAP_AllocationOrRetentionPriority_t *arp = CALLOC(1, sizeof(*arp));
482
483 arp->priorityLevel = level;
484
485 if (capability)
486 arp->pre_emptionCapability = RANAP_Pre_emptionCapability_may_trigger_pre_emption;
487 else
488 arp->pre_emptionCapability = RANAP_Pre_emptionCapability_shall_not_trigger_pre_emption;
489
490 if (vulnerability)
491 arp->pre_emptionVulnerability = RANAP_Pre_emptionVulnerability_pre_emptable;
492 else
493 arp->pre_emptionVulnerability = RANAP_Pre_emptionVulnerability_not_pre_emptable;
494
495 if (queueing_allowed)
496 arp->queuingAllowed = RANAP_QueuingAllowed_queueing_allowed;
497 else
498 arp->queuingAllowed = RANAP_QueuingAllowed_queueing_not_allowed;
499
500 return arp;
501}
502
503/* See Chapter 5 of TS 26.102 */
504static RANAP_RAB_Parameters_t *new_rab_par_voice(void)
505{
506 RANAP_RAB_Parameters_t *rab = CALLOC(1, sizeof(*rab));
507 RANAP_SDU_ParameterItem_t *sdui;
508
509 rab->trafficClass = RANAP_TrafficClass_conversational;
510 rab->rAB_AsymmetryIndicator = RANAP_RAB_AsymmetryIndicator_symmetric_bidirectional;
511
512 ASN_SEQUENCE_ADD(&rab->maxBitrate.list, new_long(12200));
513 rab->guaranteedBitRate = CALLOC(1, sizeof(*rab->guaranteedBitRate));
514 ASN_SEQUENCE_ADD(rab->guaranteedBitRate, new_long(12200));
515 rab->deliveryOrder = RANAP_DeliveryOrder_delivery_order_requested;
516 rab->maxSDU_Size = 244;
517
518 sdui = new_sdu_par_item(SDUPAR_P_VOICE0);
519 ASN_SEQUENCE_ADD(&rab->sDU_Parameters, sdui);
520 sdui = new_sdu_par_item(SDUPAR_P_VOICE1);
521 ASN_SEQUENCE_ADD(&rab->sDU_Parameters, sdui);
522 sdui = new_sdu_par_item(SDUPAR_P_VOICE2);
523 ASN_SEQUENCE_ADD(&rab->sDU_Parameters, sdui);
524
525 rab->transferDelay = new_long(80);
526 rab->allocationOrRetentionPriority = new_alloc_ret_prio(RANAP_PriorityLevel_no_priority, 0, 1, 0);
527
528 rab->sourceStatisticsDescriptor = new_long(RANAP_SourceStatisticsDescriptor_speech);
529
530 return rab;
531}
532
533static RANAP_RAB_Parameters_t *new_rab_par_data(void)
534{
535 RANAP_RAB_Parameters_t *rab = CALLOC(1, sizeof(*rab));
536 RANAP_SDU_ParameterItem_t *sdui;
537
538 rab->trafficClass = RANAP_TrafficClass_background;
539 rab->rAB_AsymmetryIndicator = RANAP_RAB_AsymmetryIndicator_asymmetric_bidirectional;
540
541 ASN_SEQUENCE_ADD(&rab->maxBitrate.list, new_long(16000000));
542 ASN_SEQUENCE_ADD(&rab->maxBitrate.list, new_long(8000000));
543 rab->deliveryOrder = RANAP_DeliveryOrder_delivery_order_requested;
544 rab->maxSDU_Size = 8000;
545
546 sdui = new_sdu_par_item(SDUPAR_P_DATA);
547 ASN_SEQUENCE_ADD(&rab->sDU_Parameters, sdui);
548
549 rab->allocationOrRetentionPriority = new_alloc_ret_prio(RANAP_PriorityLevel_no_priority, 0, 0, 0);
550
551 /* FIXME: RAB-Parameter-ExtendedMaxBitrateList for 42Mbps? */
552
553 return rab;
554}
555
556static RANAP_TransportLayerInformation_t *new_transp_info_rtp(uint32_t ip, uint16_t port)
557{
558 RANAP_TransportLayerInformation_t *tli = CALLOC(1, sizeof(*tli));
559 uint32_t *ipbuf = CALLOC(1, sizeof(*ipbuf));
560 uint8_t binding_id[4];
561
562 binding_id[0] = port >> 8;
563 binding_id[1] = port & 0xff;
564 binding_id[2] = binding_id[3] = 0;
565
Harald Welte94a62d52015-12-19 02:37:48 +0100566 asn1_u32_to_bitstring(&tli->transportLayerAddress, ipbuf, ip);
Harald Weltef8db61b2015-12-18 17:29:59 +0100567 tli->iuTransportAssociation.present = RANAP_IuTransportAssociation_PR_bindingID;
568 OCTET_STRING_fromBuf(&tli->iuTransportAssociation.choice.bindingID,
569 (const char *) binding_id, sizeof(binding_id));
570
571 return tli;
572}
573
574static RANAP_TransportLayerInformation_t *new_transp_info_gtp(uint32_t ip, uint32_t tei)
575{
576 RANAP_TransportLayerInformation_t *tli = CALLOC(1, sizeof(*tli));
577 uint32_t *ipbuf = CALLOC(1, sizeof(*ipbuf));
Harald Welte94a62d52015-12-19 02:37:48 +0100578 uint32_t binding_buf = tei;
Harald Weltef8db61b2015-12-18 17:29:59 +0100579
Harald Welte94a62d52015-12-19 02:37:48 +0100580 asn1_u32_to_bitstring(&tli->transportLayerAddress, ipbuf, ip);
Harald Weltef8db61b2015-12-18 17:29:59 +0100581 tli->iuTransportAssociation.present = RANAP_IuTransportAssociation_PR_gTP_TEI;
582 OCTET_STRING_fromBuf(&tli->iuTransportAssociation.choice.bindingID,
583 (const char *) &binding_buf, sizeof(binding_buf));
584
585 return tli;
586}
587
588static RANAP_UserPlaneInformation_t *new_upi(long mode, uint8_t mode_versions)
589{
590 RANAP_UserPlaneInformation_t *upi = CALLOC(1, sizeof(*upi));
591 uint16_t *buf = CALLOC(1, sizeof(*buf));
592
593 *buf = mode_versions;
594
595 upi->userPlaneMode = mode;
Harald Weltef9c9aa52015-12-24 15:39:00 +0100596 upi->uP_ModeVersions.buf = (uint8_t *) buf;
Harald Weltef8db61b2015-12-18 17:29:59 +0100597 upi->uP_ModeVersions.size = sizeof(*buf);
598 upi->uP_ModeVersions.bits_unused = 0;
599
600 return upi;
601}
602
603
604static void assign_new_ra_id(RANAP_RAB_ID_t *id, uint8_t rab_id)
605{
606 uint8_t *buf = CALLOC(1, sizeof(*buf));
Harald Welte0a3eafe2015-12-19 02:38:09 +0100607 *buf = rab_id;
Harald Weltef8db61b2015-12-18 17:29:59 +0100608
609 id->buf = buf;
610 id->size = 1;
611 id->bits_unused = 0;
612}
613
614/*! \brief generate RANAP RAB ASSIGNMENT REQUEST message for CS (voice) */
615struct msgb *ranap_new_msg_rab_assign_voice(uint8_t rab_id, uint32_t rtp_ip, uint16_t rtp_port)
616{
617 RANAP_ProtocolIE_FieldPair_t *pair;
618 RANAP_RAB_AssignmentRequestIEs_t ies;
619 RANAP_RAB_AssignmentRequest_t out;
620 struct msgb *msg;
621 int rc;
622
623 memset(&ies, 0, sizeof(ies));
624 memset(&out, 0, sizeof(out));
625
626 /* only assingnment is present, no release */
627 ies.presenceMask = RAB_ASSIGNMENTREQUESTIES_RANAP_RAB_SETUPORMODIFYLIST_PRESENT;
628
629 /* put together the 'First' part */
630 RANAP_RAB_SetupOrModifyItemFirst_t first;
631 memset(&first, 0, sizeof(first));
632 assign_new_ra_id(&first.rAB_ID, rab_id);
633 //first.nAS_SynchronisationIndicator = FIXME;
634 first.rAB_Parameters = new_rab_par_voice();
635 first.userPlaneInformation = new_upi(RANAP_UserPlaneMode_support_mode_for_predefined_SDU_sizes, 1); /* 2? */
636 first.transportLayerInformation = new_transp_info_rtp(rtp_ip, rtp_port);
637
638 /* put together the 'Second' part */
639 RANAP_RAB_SetupOrModifyItemSecond_t second;
640 memset(&second, 0, sizeof(second));
641
642 /* Build an IE Pair out of first and second part:
643 * (first, second) -> pair */
644 pair = ranap_new_ie_pair(RANAP_ProtocolIE_ID_id_RAB_SetupOrModifyItem,
645 RANAP_Criticality_reject,
646 &asn_DEF_RANAP_RAB_SetupOrModifyItemFirst, &first,
647 RANAP_Criticality_ignore,
648 &asn_DEF_RANAP_RAB_SetupOrModifyItemSecond, &second);
649
650 /* the pair has been made, we can release any of its elements */
651 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_SetupOrModifyItemFirst, &first);
652 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_SetupOrModifyItemSecond, &second);
653
Harald Welteb7f67c42015-12-19 02:36:52 +0100654 RANAP_ProtocolIE_ContainerPair_t *container_pair = CALLOC(1, sizeof(*container_pair));
Harald Weltef8db61b2015-12-18 17:29:59 +0100655 /* Add the pair to the list of IEs of the RAB ass.req */
Harald Welteb7f67c42015-12-19 02:36:52 +0100656 ASN_SEQUENCE_ADD(container_pair, pair);
657 ASN_SEQUENCE_ADD(&ies.raB_SetupOrModifyList.list, container_pair);
Harald Weltef8db61b2015-12-18 17:29:59 +0100658
659 /* encode the IEs into the actual assignment request:
660 * ies -> out */
661 rc = ranap_encode_rab_assignmentrequesties(&out, &ies);
662 /* 'out' has been generated, we can now release the input */
663 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_SetupOrModifyList,
664 &ies.raB_SetupOrModifyList);
665 if (rc < 0)
666 return NULL;
667
668 /* generate an Initiating Mesasage: out -> msg */
669 msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_RAB_Assignment,
670 RANAP_Criticality_reject,
671 &asn_DEF_RANAP_RAB_AssignmentRequest, &out);
672
673 /* 'msg' has been generated, we cann now release the input 'out' */
674 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_AssignmentRequest, &out);
675
676 return msg;
677}
678
679/*! \brief generate RANAP RAB ASSIGNMENT REQUEST message for PS (data) */
680struct msgb *ranap_new_msg_rab_assign_data(uint8_t rab_id, uint32_t gtp_ip, uint32_t gtp_tei)
681{
682 RANAP_ProtocolIE_FieldPair_t *pair;
683 RANAP_RAB_AssignmentRequestIEs_t ies;
684 RANAP_RAB_AssignmentRequest_t out;
685 RANAP_DataVolumeReportingIndication_t *dat_vol_ind;
686 struct msgb *msg;
687 int rc;
688
689 memset(&ies, 0, sizeof(ies));
690 memset(&out, 0, sizeof(out));
691
692 /* only assingnment is present, no release */
693 ies.presenceMask = RAB_ASSIGNMENTREQUESTIES_RANAP_RAB_SETUPORMODIFYLIST_PRESENT;
694
695 /* put together the 'First' part */
696 RANAP_RAB_SetupOrModifyItemFirst_t first;
697 memset(&first, 0, sizeof(first));
698 assign_new_ra_id(&first.rAB_ID, rab_id);
699 //first.nAS_SynchronisationIndicator = FIXME;
700 first.rAB_Parameters = new_rab_par_data();
701 first.userPlaneInformation = new_upi(RANAP_UserPlaneMode_transparent_mode, 1);
702 first.transportLayerInformation = new_transp_info_rtp(gtp_ip, gtp_tei);
703
704 /* put together the 'Second' part */
705 RANAP_RAB_SetupOrModifyItemSecond_t second;
706 memset(&second, 0, sizeof(second));
707 second.pDP_TypeInformation = CALLOC(1, sizeof(*second.pDP_TypeInformation));
708 ASN_SEQUENCE_ADD(second.pDP_TypeInformation, new_long(RANAP_PDP_Type_ipv4));
709 dat_vol_ind = CALLOC(1, sizeof(*dat_vol_ind));
710 *dat_vol_ind = RANAP_DataVolumeReportingIndication_do_not_report;
711 second.dataVolumeReportingIndication = dat_vol_ind;
712 second.dl_GTP_PDU_SequenceNumber = new_long(0);
713 second.ul_GTP_PDU_SequenceNumber = new_long(0);
714
715 /* Build an IE Pair out of first and second part:
716 * (first, second) -> pair */
717 pair = ranap_new_ie_pair(RANAP_ProtocolIE_ID_id_RAB_SetupOrModifyItem,
718 RANAP_Criticality_reject,
719 &asn_DEF_RANAP_RAB_SetupOrModifyItemFirst,
720 &first, RANAP_Criticality_ignore,
721 &asn_DEF_RANAP_RAB_SetupOrModifyItemSecond,
722 &second);
723
724 /* the pair has been made, we can release any of its elements */
725 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_SetupOrModifyItemFirst, &first);
726 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_SetupOrModifyItemSecond, &second);
727
Harald Welteb7f67c42015-12-19 02:36:52 +0100728 RANAP_ProtocolIE_ContainerPair_t *container_pair = CALLOC(1, sizeof(*container_pair));
Harald Weltef8db61b2015-12-18 17:29:59 +0100729 /* Add the pair to the list of IEs of the RAB ass.req */
Harald Welteb7f67c42015-12-19 02:36:52 +0100730 ASN_SEQUENCE_ADD(container_pair, pair);
731 /* Add the pair to the list of IEs of the RAB ass.req */
732 ASN_SEQUENCE_ADD(&ies.raB_SetupOrModifyList.list, container_pair);
Harald Weltef8db61b2015-12-18 17:29:59 +0100733
734 /* encode the IEs into the actual assignment request:
735 * ies -> out */
736 rc = ranap_encode_rab_assignmentrequesties(&out, &ies);
737 /* 'out' has been generated, we can now release the input */
738 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_SetupOrModifyList,
739 &ies.raB_SetupOrModifyList);
740 if (rc < 0)
741 return NULL;
742
743 /* generate an Initiating Mesasage: out -> msg */
744 msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_RAB_Assignment,
745 RANAP_Criticality_reject,
746 &asn_DEF_RANAP_RAB_AssignmentRequest, &out);
747
748 /* 'msg' has been generated, we cann now release the input 'out' */
749 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_AssignmentRequest, &out);
750
751 return msg;
752}