blob: 99a86ffc1dc0d7670b5aad2efb1d80af481e84ae [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
41/*! \brief generate RANAP DIRECT TRANSFER message */
42struct msgb *ranap_new_msg_dt(uint8_t sapi, const uint8_t *nas, unsigned int nas_len)
43{
44 RANAP_DirectTransferIEs_t ies;
45 RANAP_DirectTransfer_t dt;
46 struct msgb *msg;
47 int rc;
48
49 memset(&ies, 0, sizeof(ies));
50 memset(&dt, 0, sizeof(dt));
51
52 /* only SAPI optional field shall be present for CN->RNC */
53 ies.presenceMask = DIRECTTRANSFERIES_RANAP_SAPI_PRESENT;
54
55 if (sapi == 3)
56 ies.sapi = RANAP_SAPI_sapi_3;
57 else
58 ies.sapi = RANAP_SAPI_sapi_0;
59
60 ies.nas_pdu.buf = (uint8_t *) nas;
61 ies.nas_pdu.size = nas_len;
62
63 /* ies -> dt */
64 rc = ranap_encode_directtransferies(&dt, &ies);
65
66 /* dt -> msg */
67 msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_DirectTransfer,
68 RANAP_Criticality_reject,
69 &asn_DEF_RANAP_DirectTransfer,
70 &dt);
71
72 /* release dynamic allocations attached to dt */
73 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_DirectTransfer, &dt);
74
75 return msg;
76}
77
78static const enum RANAP_IntegrityProtectionAlgorithm ip_alg[2] = {
79 RANAP_IntegrityProtectionAlgorithm_standard_UMTS_integrity_algorithm_UIA1,
80 RANAP_IntegrityProtectionAlgorithm_standard_UMTS_integrity_algorithm_UIA2,
81};
82
83static const RANAP_EncryptionAlgorithm_t enc_alg[2] = {
84 RANAP_EncryptionAlgorithm_standard_UMTS_encryption_algorith_UEA1,
85 RANAP_EncryptionAlgorithm_standard_UMTS_encryption_algorithm_UEA2,
86};
87
88/*! \brief generate RANAP SECURITY MODE COMMAND message */
89struct msgb *ranap_new_msg_sec_mod_cmd(const uint8_t *ik, const uint8_t *ck)
90{
91 RANAP_SecurityModeCommandIEs_t ies;
92 RANAP_SecurityModeCommand_t out;
93 struct msgb *msg;
94 int i, rc;
95
96 memset(&ies, 0, sizeof(ies));
97 memset(&out, 0, sizeof(out));
98
99 ies.presenceMask = SECURITYMODECOMMANDIES_RANAP_ENCRYPTIONINFORMATION_PRESENT;
100
101 for (i = 0; i < ARRAY_SIZE(ip_alg); i++) {
102 /* needs to be dynamically allocated, as
103 * SET_OF_free() will call FREEMEM() on it */
104 RANAP_IntegrityProtectionAlgorithm_t *alg = CALLOC(1, sizeof(*alg));
105 *alg = ip_alg[i];
106 ASN_SEQUENCE_ADD(&ies.integrityProtectionInformation.permittedAlgorithms, alg);
107 }
108
109 BIT_STRING_fromBuf(&ies.integrityProtectionInformation.key, ik, 16*8);
110
111 if (ck) {
112 for (i = 0; i < ARRAY_SIZE(ip_alg); i++) {
113 /* needs to be dynamically allocated, as
114 * SET_OF_free() will call FREEMEM() on it */
115 RANAP_EncryptionAlgorithm_t *alg = CALLOC(1, sizeof(*alg));
116 *alg = enc_alg[i];
117 ASN_SEQUENCE_ADD(&ies.encryptionInformation.permittedAlgorithms, alg);
118 }
119 BIT_STRING_fromBuf(&ies.encryptionInformation.key, ck, 16*8);
120 }
121
122 ies.keyStatus = RANAP_KeyStatus_new; /* FIXME */
123
124 /* ies -> out */
125 rc = ranap_encode_securitymodecommandies(&out, &ies);
126
127 /* release dynamic allocations attached to ies */
128 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_IntegrityProtectionInformation, &ies.integrityProtectionInformation);
129 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_EncryptionInformation, &ies.encryptionInformation);
130
131 /* out -> msg */
132 msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_SecurityModeControl,
133 RANAP_Criticality_reject,
134 &asn_DEF_RANAP_SecurityModeCommand,
135 &out);
136
137 /* release dynamic allocations attached to out */
138 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_SecurityModeCommand, &out);
139
140 return msg;
141}
142
143/*! \brief generate RANAP COMMON ID message */
144struct msgb *ranap_new_msg_common_id(const char *imsi)
145{
146 RANAP_CommonID_IEs_t ies;
147 RANAP_CommonID_t out;
148 struct msgb *msg;
149 int rc;
150
151 memset(&ies, 0, sizeof(ies));
152 memset(&out, 0, sizeof(out));
153
154 if (imsi) {
155 uint8_t *imsi_buf = CALLOC(1, 16);
156 rc = encode_iu_imsi(imsi_buf, 16, imsi);
157 ies.permanentNAS_UE_ID.present = RANAP_PermanentNAS_UE_ID_PR_iMSI;
158 ies.permanentNAS_UE_ID.choice.iMSI.buf = imsi_buf;
159 ies.permanentNAS_UE_ID.choice.iMSI.size = rc;
160 } else
161 ies.permanentNAS_UE_ID.present = RANAP_PermanentNAS_UE_ID_PR_NOTHING;
162
163 /* ies -> out */
164 rc = ranap_encode_commonid_ies(&out, &ies);
165 /* release dynamic allocations attached to ies */
166 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_PermanentNAS_UE_ID, &ies.permanentNAS_UE_ID);
167 if (rc < 0)
168 return NULL;
169
170 /* out -> msg */
171 msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_CommonID,
172 RANAP_Criticality_ignore,
173 &asn_DEF_RANAP_CommonID,
174 &out);
175
176 /* release dynamic allocations attached to out */
177 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_CommonID, &out);
178
179 return msg;
180}
181
182/*! \brief generate RANAP IU RELEASE COMMAND message */
183struct msgb *ranap_new_msg_iu_rel_cmd(const RANAP_Cause_t *cause_in)
184{
185 RANAP_Iu_ReleaseCommandIEs_t ies;
186 RANAP_Iu_ReleaseCommand_t out;
187 struct msgb *msg;
188 int rc;
189
190 memset(&ies, 0, sizeof(ies));
191 memset(&out, 0, sizeof(out));
192
193 memcpy(&ies.cause, cause_in, sizeof(ies.cause));
194
195 /* ies -> out */
196 rc = ranap_encode_iu_releasecommandies(&out, &ies);
197 if (rc < 0)
198 return NULL;
199
200 /* out -> msg */
201 msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_Iu_Release,
202 RANAP_Criticality_reject,
203 &asn_DEF_RANAP_Iu_ReleaseCommand,
204 &out);
205
206 /* release dynamic allocations attached to out */
207 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_Iu_ReleaseCommand, &out);
208
209 return msg;
210}
211
212/*! \brief generate RANAP PAGING COMMAND message */
213struct msgb *ranap_new_msg_paging_cmd(const char *imsi, const uint32_t *tmsi, int is_ps, uint32_t cause)
214{
215 RANAP_PagingIEs_t ies;
216 RANAP_Paging_t out;
217 struct msgb *msg;
218 uint8_t *imsi_buf = CALLOC(1, 16);
219 int rc;
220
221 memset(&ies, 0, sizeof(ies));
222 memset(&out, 0, sizeof(out));
223
224 /* put together the 'ies' */
225 if (is_ps)
226 ies.cN_DomainIndicator = RANAP_CN_DomainIndicator_ps_domain;
227 else
228 ies.cN_DomainIndicator = RANAP_CN_DomainIndicator_cs_domain;
229
230 rc = encode_iu_imsi(imsi_buf, 16, imsi);
231 ies.permanentNAS_UE_ID.present = RANAP_PermanentNAS_UE_ID_PR_iMSI;
232 ies.permanentNAS_UE_ID.choice.iMSI.buf = imsi_buf;
233 ies.permanentNAS_UE_ID.choice.iMSI.size = rc;
234
235 if (tmsi) {
236 uint32_t *tmsi_buf = CALLOC(1, sizeof(*tmsi_buf));
237 *tmsi_buf = *tmsi;
238 ies.presenceMask |= PAGINGIES_RANAP_TEMPORARYUE_ID_PRESENT;
239 if (is_ps) {
240 ies.temporaryUE_ID.present = RANAP_TemporaryUE_ID_PR_p_TMSI;
241 ies.temporaryUE_ID.choice.tMSI.buf = tmsi_buf;
242 ies.temporaryUE_ID.choice.tMSI.size = sizeof(*tmsi_buf);
243 } else {
244 ies.temporaryUE_ID.present = RANAP_TemporaryUE_ID_PR_tMSI;
245 ies.temporaryUE_ID.choice.p_TMSI.buf = tmsi_buf;
246 ies.temporaryUE_ID.choice.p_TMSI.size = sizeof(*tmsi_buf);
247 }
248 }
249
250 if (cause) {
251 ies.presenceMask |= PAGINGIES_RANAP_PAGINGCAUSE_PRESENT;
252 ies.pagingCause = cause;
253 }
254
255 /* ies -> out */
256 rc = ranap_encode_pagingies(&out, &ies);
257 /* release dynamic allocation attached to ies */
258 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_PermanentNAS_UE_ID, &ies.permanentNAS_UE_ID);
259 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_TemporaryUE_ID, &ies.temporaryUE_ID);
260 if (rc < 0)
261 return NULL;
262
263 /* out -> msg */
264 msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_Paging,
265 RANAP_Criticality_reject,
266 &asn_DEF_RANAP_Paging,
267 &out);
268
269 /* release dynamic allocations attached to out */
270 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_Paging, &out);
271
272 return msg;
273}
274
275static RANAP_SDU_ErrorRatio_t *new_sdu_error_ratio(long mantissa, long exponent)
276{
277 RANAP_SDU_ErrorRatio_t *err = CALLOC(1, sizeof(*err));
278
279 err->mantissa = mantissa;
280 err->exponent = exponent;
281
282 return err;
283}
284
285
286static RANAP_SDU_FormatInformationParameterItem_t *
287new_format_info_pars(long sdu_size)
288{
289 RANAP_SDU_FormatInformationParameterItem_t *fmti = CALLOC(1, sizeof(*fmti));
290 fmti->subflowSDU_Size = new_long(sdu_size);
291 return fmti;
292}
293
294enum sdu_par_profile {
295 SDUPAR_P_VOICE0,
296 SDUPAR_P_VOICE1,
297 SDUPAR_P_VOICE2,
298 SDUPAR_P_DATA,
299};
300
301/* See Chapter 5 of TS 26.102 */
302static RANAP_SDU_ParameterItem_t *new_sdu_par_item(enum sdu_par_profile profile)
303{
304 RANAP_SDU_ParameterItem_t *sdui = CALLOC(1, sizeof(*sdui));
305 RANAP_SDU_FormatInformationParameters_t *fmtip = CALLOC(1, sizeof(*fmtip));
306 RANAP_SDU_FormatInformationParameterItem_t *fmti;
307
308 switch (profile) {
309 case SDUPAR_P_VOICE0:
310 sdui->sDU_ErrorRatio = new_sdu_error_ratio(1, 5);
311 sdui->residualBitErrorRatio.mantissa = 1;
312 sdui->residualBitErrorRatio.exponent = 6;
313 sdui->deliveryOfErroneousSDU = RANAP_DeliveryOfErroneousSDU_yes;
314 sdui->sDU_FormatInformationParameters = fmtip;
315 fmti = new_format_info_pars(81);
316 ASN_SEQUENCE_ADD(fmtip, fmti);
317 fmti = new_format_info_pars(39);
318 ASN_SEQUENCE_ADD(fmtip, fmti);
319 /* FIXME: could be 10 SDU descriptors for AMR! */
320 break;
321 case SDUPAR_P_VOICE1:
322 sdui->residualBitErrorRatio.mantissa = 1;
323 sdui->residualBitErrorRatio.exponent = 3;
324 sdui->deliveryOfErroneousSDU = RANAP_DeliveryOfErroneousSDU_no_error_detection_consideration;
325 sdui->sDU_FormatInformationParameters = fmtip;
326 fmti = new_format_info_pars(103);
327 ASN_SEQUENCE_ADD(fmtip, fmti);
328 fmti = new_format_info_pars(0);
329 ASN_SEQUENCE_ADD(fmtip, fmti);
330 /* FIXME: could be 10 SDU descriptors for AMR! */
331 break;
332 case SDUPAR_P_VOICE2:
333 sdui->residualBitErrorRatio.mantissa = 5;
334 sdui->residualBitErrorRatio.exponent = 3;
335 sdui->deliveryOfErroneousSDU = RANAP_DeliveryOfErroneousSDU_no_error_detection_consideration;
336 sdui->sDU_FormatInformationParameters = fmtip;
337 fmti = new_format_info_pars(60);
338 ASN_SEQUENCE_ADD(fmtip, fmti);
339 fmti = new_format_info_pars(0);
340 ASN_SEQUENCE_ADD(fmtip, fmti);
341 /* FIXME: could be 10 SDU descriptors for AMR! */
342 break;
343 case SDUPAR_P_DATA:
344 sdui->sDU_ErrorRatio = new_sdu_error_ratio(1, 4);
345 sdui->residualBitErrorRatio.mantissa = 1;
346 sdui->residualBitErrorRatio.exponent = 5;
347 sdui->deliveryOfErroneousSDU = RANAP_DeliveryOfErroneousSDU_no;
348 FREEMEM(fmtip);
349 break;
350 }
351
352 return sdui;
353}
354
355static RANAP_AllocationOrRetentionPriority_t *
356new_alloc_ret_prio(RANAP_PriorityLevel_t level, int capability, int vulnerability,
357 int queueing_allowed)
358{
359 RANAP_AllocationOrRetentionPriority_t *arp = CALLOC(1, sizeof(*arp));
360
361 arp->priorityLevel = level;
362
363 if (capability)
364 arp->pre_emptionCapability = RANAP_Pre_emptionCapability_may_trigger_pre_emption;
365 else
366 arp->pre_emptionCapability = RANAP_Pre_emptionCapability_shall_not_trigger_pre_emption;
367
368 if (vulnerability)
369 arp->pre_emptionVulnerability = RANAP_Pre_emptionVulnerability_pre_emptable;
370 else
371 arp->pre_emptionVulnerability = RANAP_Pre_emptionVulnerability_not_pre_emptable;
372
373 if (queueing_allowed)
374 arp->queuingAllowed = RANAP_QueuingAllowed_queueing_allowed;
375 else
376 arp->queuingAllowed = RANAP_QueuingAllowed_queueing_not_allowed;
377
378 return arp;
379}
380
381/* See Chapter 5 of TS 26.102 */
382static RANAP_RAB_Parameters_t *new_rab_par_voice(void)
383{
384 RANAP_RAB_Parameters_t *rab = CALLOC(1, sizeof(*rab));
385 RANAP_SDU_ParameterItem_t *sdui;
386
387 rab->trafficClass = RANAP_TrafficClass_conversational;
388 rab->rAB_AsymmetryIndicator = RANAP_RAB_AsymmetryIndicator_symmetric_bidirectional;
389
390 ASN_SEQUENCE_ADD(&rab->maxBitrate.list, new_long(12200));
391 rab->guaranteedBitRate = CALLOC(1, sizeof(*rab->guaranteedBitRate));
392 ASN_SEQUENCE_ADD(rab->guaranteedBitRate, new_long(12200));
393 rab->deliveryOrder = RANAP_DeliveryOrder_delivery_order_requested;
394 rab->maxSDU_Size = 244;
395
396 sdui = new_sdu_par_item(SDUPAR_P_VOICE0);
397 ASN_SEQUENCE_ADD(&rab->sDU_Parameters, sdui);
398 sdui = new_sdu_par_item(SDUPAR_P_VOICE1);
399 ASN_SEQUENCE_ADD(&rab->sDU_Parameters, sdui);
400 sdui = new_sdu_par_item(SDUPAR_P_VOICE2);
401 ASN_SEQUENCE_ADD(&rab->sDU_Parameters, sdui);
402
403 rab->transferDelay = new_long(80);
404 rab->allocationOrRetentionPriority = new_alloc_ret_prio(RANAP_PriorityLevel_no_priority, 0, 1, 0);
405
406 rab->sourceStatisticsDescriptor = new_long(RANAP_SourceStatisticsDescriptor_speech);
407
408 return rab;
409}
410
411static RANAP_RAB_Parameters_t *new_rab_par_data(void)
412{
413 RANAP_RAB_Parameters_t *rab = CALLOC(1, sizeof(*rab));
414 RANAP_SDU_ParameterItem_t *sdui;
415
416 rab->trafficClass = RANAP_TrafficClass_background;
417 rab->rAB_AsymmetryIndicator = RANAP_RAB_AsymmetryIndicator_asymmetric_bidirectional;
418
419 ASN_SEQUENCE_ADD(&rab->maxBitrate.list, new_long(16000000));
420 ASN_SEQUENCE_ADD(&rab->maxBitrate.list, new_long(8000000));
421 rab->deliveryOrder = RANAP_DeliveryOrder_delivery_order_requested;
422 rab->maxSDU_Size = 8000;
423
424 sdui = new_sdu_par_item(SDUPAR_P_DATA);
425 ASN_SEQUENCE_ADD(&rab->sDU_Parameters, sdui);
426
427 rab->allocationOrRetentionPriority = new_alloc_ret_prio(RANAP_PriorityLevel_no_priority, 0, 0, 0);
428
429 /* FIXME: RAB-Parameter-ExtendedMaxBitrateList for 42Mbps? */
430
431 return rab;
432}
433
434static RANAP_TransportLayerInformation_t *new_transp_info_rtp(uint32_t ip, uint16_t port)
435{
436 RANAP_TransportLayerInformation_t *tli = CALLOC(1, sizeof(*tli));
437 uint32_t *ipbuf = CALLOC(1, sizeof(*ipbuf));
438 uint8_t binding_id[4];
439
440 binding_id[0] = port >> 8;
441 binding_id[1] = port & 0xff;
442 binding_id[2] = binding_id[3] = 0;
443
Harald Welte94a62d52015-12-19 02:37:48 +0100444 asn1_u32_to_bitstring(&tli->transportLayerAddress, ipbuf, ip);
Harald Weltef8db61b2015-12-18 17:29:59 +0100445 tli->iuTransportAssociation.present = RANAP_IuTransportAssociation_PR_bindingID;
446 OCTET_STRING_fromBuf(&tli->iuTransportAssociation.choice.bindingID,
447 (const char *) binding_id, sizeof(binding_id));
448
449 return tli;
450}
451
452static RANAP_TransportLayerInformation_t *new_transp_info_gtp(uint32_t ip, uint32_t tei)
453{
454 RANAP_TransportLayerInformation_t *tli = CALLOC(1, sizeof(*tli));
455 uint32_t *ipbuf = CALLOC(1, sizeof(*ipbuf));
Harald Welte94a62d52015-12-19 02:37:48 +0100456 uint32_t binding_buf = tei;
Harald Weltef8db61b2015-12-18 17:29:59 +0100457
Harald Welte94a62d52015-12-19 02:37:48 +0100458 asn1_u32_to_bitstring(&tli->transportLayerAddress, ipbuf, ip);
Harald Weltef8db61b2015-12-18 17:29:59 +0100459 tli->iuTransportAssociation.present = RANAP_IuTransportAssociation_PR_gTP_TEI;
460 OCTET_STRING_fromBuf(&tli->iuTransportAssociation.choice.bindingID,
461 (const char *) &binding_buf, sizeof(binding_buf));
462
463 return tli;
464}
465
466static RANAP_UserPlaneInformation_t *new_upi(long mode, uint8_t mode_versions)
467{
468 RANAP_UserPlaneInformation_t *upi = CALLOC(1, sizeof(*upi));
469 uint16_t *buf = CALLOC(1, sizeof(*buf));
470
471 *buf = mode_versions;
472
473 upi->userPlaneMode = mode;
474 upi->uP_ModeVersions.buf = buf;
475 upi->uP_ModeVersions.size = sizeof(*buf);
476 upi->uP_ModeVersions.bits_unused = 0;
477
478 return upi;
479}
480
481
482static void assign_new_ra_id(RANAP_RAB_ID_t *id, uint8_t rab_id)
483{
484 uint8_t *buf = CALLOC(1, sizeof(*buf));
Harald Welte0a3eafe2015-12-19 02:38:09 +0100485 *buf = rab_id;
Harald Weltef8db61b2015-12-18 17:29:59 +0100486
487 id->buf = buf;
488 id->size = 1;
489 id->bits_unused = 0;
490}
491
492/*! \brief generate RANAP RAB ASSIGNMENT REQUEST message for CS (voice) */
493struct msgb *ranap_new_msg_rab_assign_voice(uint8_t rab_id, uint32_t rtp_ip, uint16_t rtp_port)
494{
495 RANAP_ProtocolIE_FieldPair_t *pair;
496 RANAP_RAB_AssignmentRequestIEs_t ies;
497 RANAP_RAB_AssignmentRequest_t out;
498 struct msgb *msg;
499 int rc;
500
501 memset(&ies, 0, sizeof(ies));
502 memset(&out, 0, sizeof(out));
503
504 /* only assingnment is present, no release */
505 ies.presenceMask = RAB_ASSIGNMENTREQUESTIES_RANAP_RAB_SETUPORMODIFYLIST_PRESENT;
506
507 /* put together the 'First' part */
508 RANAP_RAB_SetupOrModifyItemFirst_t first;
509 memset(&first, 0, sizeof(first));
510 assign_new_ra_id(&first.rAB_ID, rab_id);
511 //first.nAS_SynchronisationIndicator = FIXME;
512 first.rAB_Parameters = new_rab_par_voice();
513 first.userPlaneInformation = new_upi(RANAP_UserPlaneMode_support_mode_for_predefined_SDU_sizes, 1); /* 2? */
514 first.transportLayerInformation = new_transp_info_rtp(rtp_ip, rtp_port);
515
516 /* put together the 'Second' part */
517 RANAP_RAB_SetupOrModifyItemSecond_t second;
518 memset(&second, 0, sizeof(second));
519
520 /* Build an IE Pair out of first and second part:
521 * (first, second) -> pair */
522 pair = ranap_new_ie_pair(RANAP_ProtocolIE_ID_id_RAB_SetupOrModifyItem,
523 RANAP_Criticality_reject,
524 &asn_DEF_RANAP_RAB_SetupOrModifyItemFirst, &first,
525 RANAP_Criticality_ignore,
526 &asn_DEF_RANAP_RAB_SetupOrModifyItemSecond, &second);
527
528 /* the pair has been made, we can release any of its elements */
529 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_SetupOrModifyItemFirst, &first);
530 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_SetupOrModifyItemSecond, &second);
531
Harald Welteb7f67c42015-12-19 02:36:52 +0100532 RANAP_ProtocolIE_ContainerPair_t *container_pair = CALLOC(1, sizeof(*container_pair));
Harald Weltef8db61b2015-12-18 17:29:59 +0100533 /* Add the pair to the list of IEs of the RAB ass.req */
Harald Welteb7f67c42015-12-19 02:36:52 +0100534 ASN_SEQUENCE_ADD(container_pair, pair);
535 ASN_SEQUENCE_ADD(&ies.raB_SetupOrModifyList.list, container_pair);
Harald Weltef8db61b2015-12-18 17:29:59 +0100536
537 /* encode the IEs into the actual assignment request:
538 * ies -> out */
539 rc = ranap_encode_rab_assignmentrequesties(&out, &ies);
540 /* 'out' has been generated, we can now release the input */
541 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_SetupOrModifyList,
542 &ies.raB_SetupOrModifyList);
543 if (rc < 0)
544 return NULL;
545
546 /* generate an Initiating Mesasage: out -> msg */
547 msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_RAB_Assignment,
548 RANAP_Criticality_reject,
549 &asn_DEF_RANAP_RAB_AssignmentRequest, &out);
550
551 /* 'msg' has been generated, we cann now release the input 'out' */
552 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_AssignmentRequest, &out);
553
554 return msg;
555}
556
557/*! \brief generate RANAP RAB ASSIGNMENT REQUEST message for PS (data) */
558struct msgb *ranap_new_msg_rab_assign_data(uint8_t rab_id, uint32_t gtp_ip, uint32_t gtp_tei)
559{
560 RANAP_ProtocolIE_FieldPair_t *pair;
561 RANAP_RAB_AssignmentRequestIEs_t ies;
562 RANAP_RAB_AssignmentRequest_t out;
563 RANAP_DataVolumeReportingIndication_t *dat_vol_ind;
564 struct msgb *msg;
565 int rc;
566
567 memset(&ies, 0, sizeof(ies));
568 memset(&out, 0, sizeof(out));
569
570 /* only assingnment is present, no release */
571 ies.presenceMask = RAB_ASSIGNMENTREQUESTIES_RANAP_RAB_SETUPORMODIFYLIST_PRESENT;
572
573 /* put together the 'First' part */
574 RANAP_RAB_SetupOrModifyItemFirst_t first;
575 memset(&first, 0, sizeof(first));
576 assign_new_ra_id(&first.rAB_ID, rab_id);
577 //first.nAS_SynchronisationIndicator = FIXME;
578 first.rAB_Parameters = new_rab_par_data();
579 first.userPlaneInformation = new_upi(RANAP_UserPlaneMode_transparent_mode, 1);
580 first.transportLayerInformation = new_transp_info_rtp(gtp_ip, gtp_tei);
581
582 /* put together the 'Second' part */
583 RANAP_RAB_SetupOrModifyItemSecond_t second;
584 memset(&second, 0, sizeof(second));
585 second.pDP_TypeInformation = CALLOC(1, sizeof(*second.pDP_TypeInformation));
586 ASN_SEQUENCE_ADD(second.pDP_TypeInformation, new_long(RANAP_PDP_Type_ipv4));
587 dat_vol_ind = CALLOC(1, sizeof(*dat_vol_ind));
588 *dat_vol_ind = RANAP_DataVolumeReportingIndication_do_not_report;
589 second.dataVolumeReportingIndication = dat_vol_ind;
590 second.dl_GTP_PDU_SequenceNumber = new_long(0);
591 second.ul_GTP_PDU_SequenceNumber = new_long(0);
592
593 /* Build an IE Pair out of first and second part:
594 * (first, second) -> pair */
595 pair = ranap_new_ie_pair(RANAP_ProtocolIE_ID_id_RAB_SetupOrModifyItem,
596 RANAP_Criticality_reject,
597 &asn_DEF_RANAP_RAB_SetupOrModifyItemFirst,
598 &first, RANAP_Criticality_ignore,
599 &asn_DEF_RANAP_RAB_SetupOrModifyItemSecond,
600 &second);
601
602 /* the pair has been made, we can release any of its elements */
603 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_SetupOrModifyItemFirst, &first);
604 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_SetupOrModifyItemSecond, &second);
605
Harald Welteb7f67c42015-12-19 02:36:52 +0100606 RANAP_ProtocolIE_ContainerPair_t *container_pair = CALLOC(1, sizeof(*container_pair));
Harald Weltef8db61b2015-12-18 17:29:59 +0100607 /* Add the pair to the list of IEs of the RAB ass.req */
Harald Welteb7f67c42015-12-19 02:36:52 +0100608 ASN_SEQUENCE_ADD(container_pair, pair);
609 /* Add the pair to the list of IEs of the RAB ass.req */
610 ASN_SEQUENCE_ADD(&ies.raB_SetupOrModifyList.list, container_pair);
Harald Weltef8db61b2015-12-18 17:29:59 +0100611
612 /* encode the IEs into the actual assignment request:
613 * ies -> out */
614 rc = ranap_encode_rab_assignmentrequesties(&out, &ies);
615 /* 'out' has been generated, we can now release the input */
616 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_SetupOrModifyList,
617 &ies.raB_SetupOrModifyList);
618 if (rc < 0)
619 return NULL;
620
621 /* generate an Initiating Mesasage: out -> msg */
622 msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_RAB_Assignment,
623 RANAP_Criticality_reject,
624 &asn_DEF_RANAP_RAB_AssignmentRequest, &out);
625
626 /* 'msg' has been generated, we cann now release the input 'out' */
627 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_AssignmentRequest, &out);
628
629 return msg;
630}