blob: bb091b7ee12eb112ad67458c77b708217d9ef62f [file] [log] [blame]
Harald Welted328c1a2015-12-16 23:04:21 +01001
Harald Welte091039d2015-12-17 20:37:40 +01002#include "asn1helpers.h"
3#include "iu_helpers.h"
4
5#include "ranap_common.h"
6#include "ranap_ies_defs.h"
Harald Welted328c1a2015-12-16 23:04:21 +01007
8/* This is just some non-compiling work in progress code to generate the
9 * minimum set of RANAP messages that the core network side needs to send
10 * towards the RNC */
11
12int ranap_tx_dt(uint8_t sapi, const uint8_t *nas, unsigned int nas_len)
13{
14 RANAP_DirectTransferIEs_t ies;
15 RANAP_DirectTransfer_t dt;
16 struct msgb *msg;
17 int rc;
18
19 memset(&ies, 0, sizeof(ies));
20
21 /* only SAPI optional field shall be present for CN->RNC */
22 ies.presenceMask = DIRECTTRANSFERIES_RANAP_SAPI_PRESENT;
23
24 if (sapi == 3)
25 ies.sapi = RANAP_SAPI_sapi_3;
26 else
27 ies.sapi = RANAP_SAPI_sapi_0;
28
29 ies.nas_pdu.buf = nas;
30 ies.nas_pdu.size = nas_len;
31
32 rc = ranap_encode_directtransferies(&dt, &ies);
33
34 msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_DirectTransfer,
35 RANAP_Criticality_reject,
36 &asn_DEF_RANAP_DirectTransfer,
37 &dt);
38 /* FIXME: Hand that to RUA or SCCP */
39}
40
41static const enum RANAP_IntegrityProtectionAlgorithm ip_alg[2] = {
42 RANAP_IntegrityProtectionAlgorithm_standard_UMTS_integrity_algorithm_UIA1,
43 RANAP_IntegrityProtectionAlgorithm_standard_UMTS_integrity_algorithm_UIA2,
44};
45
Harald Welte091039d2015-12-17 20:37:40 +010046static const RANAP_EncryptionAlgorithm_t enc_alg[2] = {
47 RANAP_EncryptionAlgorithm_standard_UMTS_encryption_algorith_UEA1,
Harald Welted328c1a2015-12-16 23:04:21 +010048 RANAP_EncryptionAlgorithm_standard_UMTS_encryption_algorithm_UEA2,
49};
50
51int ranap_tx_sec_mod_cmd(void)
52{
53 RANAP_SecurityModeCommandIEs_t ies;
54 RANAP_SecurityModeCommand_t out;
55 struct msgb *msg;
Harald Welte091039d2015-12-17 20:37:40 +010056 int i, rc;
Harald Welted328c1a2015-12-16 23:04:21 +010057
58 memset(&ies, 0, sizeof(ies));
59
60 ies.presenceMask = SECURITYMODECOMMANDIES_RANAP_ENCRYPTIONINFORMATION_PRESENT;
61
Harald Welte091039d2015-12-17 20:37:40 +010062 for (i = 0; i < ARRAY_SIZE(ip_alg); i++) {
63 /* needs to be dynamically allocated, as
64 * SET_OF_free() will call FREEMEM() on it */
65 RANAP_IntegrityProtectionAlgorithm_t *alg = MALLOC(*alg);
66 *alg = ip_alg[i];
67 ASN_SEQUENCE_ADD(&ies.integrityProtectionInformation.permittedAlgorithms, alg);
68 }
Harald Welted328c1a2015-12-16 23:04:21 +010069
70 ies.integrityProtectionInformation.key; /* FIXME */
71 if (0) {
Harald Welte091039d2015-12-17 20:37:40 +010072 for (i = 0; i < ARRAY_SIZE(ip_alg); i++) {
73 /* needs to be dynamically allocated, as
74 * SET_OF_free() will call FREEMEM() on it */
75 RANAP_EncryptionAlgorithm_t *alg = MALLOC(*alg);
76 *alg = enc_alg[i];
77 ASN_SEQUENCE_ADD(&ies.encryptionInformation.permittedAlgorithms, alg);
78 }
Harald Welted328c1a2015-12-16 23:04:21 +010079 ies.encryptionInformation.key; /* FIXME */
80 }
Harald Welte091039d2015-12-17 20:37:40 +010081
Harald Welted328c1a2015-12-16 23:04:21 +010082 ies.keyStatus = RANAP_KeyStatus_new; /* FIXME */
83
84 rc = ranap_encode_securitymodecommandies(&out, &ies);
85
86 asn_sequence_empty(&ies.integrityProtectionInformation.permittedAlgorithms);
87 asn_sequence_empty(&ies.encryptionInformation.permittedAlgorithms);
88
89 msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_SecurityModeControl,
90 RANAP_Criticality_reject,
91 &asn_DEF_RANAP_SecurityModeCommand,
92 &out);
93}
94
95int ranap_tx_common_id(const char *imsi)
96{
97 RANAP_CommonID_IEs_t ies;
98 RANAP_CommonID_t out;
99 struct msgb *msg;
100 int rc;
101
102 memset(&ies, 0, sizeof(ies));
103
104 if (imsi) {
105 ies.permanentNAS_UE_ID.present = RANAP_PermanentNAS_UE_ID_PR_iMSI;
106 ies.permanentNAS_UE_ID.choice.iMSI; /* FIXME */
107 } else
108 ies.permanentNAS_UE_ID.present = RANAP_PermanentNAS_UE_ID_PR_NOTHING;
109
110 rc = ranap_encode_commonidies(&out, &ies);
111
112 msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_CommonID,
113 RANAP_Criticality_ignore,
114 &asn_DEF_RANAP_CommonID,
115 &out);
116}
117
118int ranap_tx_iu_rel_cmd(RANAP_Cause_t cause)
119{
120 RANAP_Iu_ReleaseCommandIEs_t ies;
121 RANAP_Iu_ReleaseCommand_t out;
122 struct msgb *msg;
123 int rc;
124
125 memset(&ies, 0, sizeof(ies));
126
127 ies.cause = cause;
128
129 rc = ranap_encode_iu_releasecommandies(&out, &ies);
130
131 msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_Iu_Release,
132 RANAP_Criticality_reject,
Harald Welte091039d2015-12-17 20:37:40 +0100133 &asn_DEF_RANAP_Iu_ReleaseCommand,
Harald Welted328c1a2015-12-16 23:04:21 +0100134 &out);
135}
136
Harald Welte091039d2015-12-17 20:37:40 +0100137int ranap_tx_paging_cmd(const char *imsi, uint32_t *tmsi, int is_ps, uint32_t cause)
Harald Welted328c1a2015-12-16 23:04:21 +0100138{
Harald Welte091039d2015-12-17 20:37:40 +0100139 RANAP_PagingIEs_t ies;
Harald Welted328c1a2015-12-16 23:04:21 +0100140 RANAP_Paging_t out;
Harald Welte091039d2015-12-17 20:37:40 +0100141 struct msgb *msg;
142 uint8_t *imsi_buf = CALLOC(1, 16);
143 int rc;
Harald Welted328c1a2015-12-16 23:04:21 +0100144
145 memset(&ies, 0, sizeof(ies));
146
147 if (is_ps)
148 ies.cN_DomainIndicator = RANAP_CN_DomainIndicator_ps_domain;
149 else
150 ies.cN_DomainIndicator = RANAP_CN_DomainIndicator_cs_domain;
151
Harald Welte091039d2015-12-17 20:37:40 +0100152 rc = encode_iu_imsi(imsi_buf, 16, imsi);
153 ies.permanentNAS_UE_ID.present = RANAP_PermanentNAS_UE_ID_PR_iMSI;
154 ies.permanentNAS_UE_ID.choice.iMSI.buf = imsi_buf;
155 ies.permanentNAS_UE_ID.choice.iMSI.size = rc;
Harald Welted328c1a2015-12-16 23:04:21 +0100156
157 if (tmsi) {
158 ies.presenceMask |= PAGINGIES_RANAP_TEMPORARYUE_ID_PRESENT;
159 if (is_ps) {
160 ies.temporaryUE_ID.present = RANAP_TemporaryUE_ID_PR_p_TMSI;
161 ies.temporaryUE_ID.choice.tMSI;
162 } else {
163 ies.temporaryUE_ID.present = RANAP_TemporaryUE_ID_PR_tMSI;
164 ies.temporaryUE_ID.choice.p_TMSI;
165 }
166 }
167
168 if (cause) {
169 ies.presenceMask |= PAGINGIES_RANAP_PAGINGCAUSE_PRESENT;
170 ies.pagingCause = cause;
171 }
172
173 rc = ranap_encode_iu_pagingies(&out, &ies);
174
Harald Welte091039d2015-12-17 20:37:40 +0100175 msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_Paging,
Harald Welted328c1a2015-12-16 23:04:21 +0100176 RANAP_Criticality_reject,
177 &asn_DEF_RANAP_Paging,
178 &out);
179}
180
Harald Welte091039d2015-12-17 20:37:40 +0100181static RANAP_SDU_ErrorRatio_t *new_sdu_error_ratio(long mantissa, long exponent)
182{
183 RANAP_SDU_ErrorRatio_t *err = CALLOC(1, sizeof(*err));
184
185 err->mantissa = mantissa;
186 err->exponent = exponent;
187
188 return err;
189}
Harald Welted328c1a2015-12-16 23:04:21 +0100190
191
Harald Welte091039d2015-12-17 20:37:40 +0100192static RANAP_SDU_FormatInformationParameters_t *
193new_format_info_pars(long sdu_size)
194{
195 RANAP_SDU_FormatInformationParameters_t *fmti = CALLOC(1, sizeof(*fmti));
196 fmti->subflowSDU_Size = new_long(sdu_size);
197 return fmti;
198}
199
200enum sdu_par_profile {
201 SDUPAR_P_VOICE0,
202 SDUPAR_P_VOICE1,
203 SDUPAR_P_VOICE2,
204 SDUPAR_P_DATA,
Harald Welted328c1a2015-12-16 23:04:21 +0100205};
206
Harald Welte091039d2015-12-17 20:37:40 +0100207static RANAP_SDU_Parameters_t *new_sdu_pars(enum sdu_par_profile profile)
208{
209 RANAP_SDU_Parameters_t *sdup = MALLOC(sizeof(*sdup));
210 RANAP_SDU_FormatInformationParameters_t *fmti;
Harald Welted328c1a2015-12-16 23:04:21 +0100211
Harald Welte091039d2015-12-17 20:37:40 +0100212 memset(&sdup, 0, sizeof(sdup));
213
214 switch (profile) {
215 case SDUPAR_P_VOICE0:
216 sdup->sDU_ErrorRatio = new_sdu_error_ratio(1, 5);
217 sdup->residualBitErrorRatio.mantissa = 1;
218 sdup->residualBitErrorRatio.exponent = 6;
219 sdup->deliveryOfErroneousSDU = RANAP_DeliveryOfErroneousSDU_yes;
220 fmti = new_format_info_pars(81);
221 ASN_SEQUENCE_ADD(&sdup->sDU_FormatInformationParameters, fmti);
222 fmti = new_format_info_pars(39);
223 ASN_SEQUENCE_ADD(&sdup->sDU_FormatInformationParameters, fmti);
224 /* FIXME: could be 10 SDU descriptors for AMR! */
225 break;
226 case SDUPAR_P_VOICE1:
227 sdup->residualBitErrorRatio.mantissa = 1;
228 sdup->residualBitErrorRatio.exponent = 3;
229 sudp->deliveryOfErroneousSDU = RANAP_DeliveryOfErroneousSDU_no_error_detection_consideration;
230 fmti = new_format_info_pars(103);
231 ASN_SEQUENCE_ADD(&sdup->sDU_FormatInformationParameters, fmti);
232 fmti = new_format_info_pars(0);
233 ASN_SEQUENCE_ADD(&sdup->sDU_FormatInformationParameters, fmti);
234 /* FIXME: could be 10 SDU descriptors for AMR! */
235 break;
236 case SDUPAR_P_VOICE2:
237 sdup->residualBitErrorRatio.mantissa = 5;
238 sdup->residualBitErrorRatio.exponent = 3;
239 sudp->deliveryOfErroneousSDU = RANAP_DeliveryOfErroneousSDU_no_error_detection_consideration;
240 fmti = new_format_info_pars(60);
241 ASN_SEQUENCE_ADD(&sdup->sDU_FormatInformationParameters, fmti);
242 fmti = new_format_info_pars(0);
243 ASN_SEQUENCE_ADD(&sdup->sDU_FormatInformationParameters, fmti);
244 /* FIXME: could be 10 SDU descriptors for AMR! */
245 break;
246 case SDUPAR_P_DATA:
247 sdup->sDU_ErrorRatio = new_sdu_error_ratio(1, 4);
248 sdup->residualBitErrorRatio.mantissa = 1;
249 sdup->residualBitErrorRatio.exponent = 5;
250 sdup->deliveryOfErroneousSDU = RANAP_DeliveryOfErroneousSDU_no;
251 break;
252 }
253
254 return sdup;
255}
256
257static long *new_long(long in)
258{
259 long *out = MALLOC(sizeof(long));
260 *out = in;
261 return out;
262}
263
264static RANAP_AllocationOrRetentionPriority_t *
265new_alloc_ret_prio(RANAP_PriorityLevel_t level, bool capability, bool vulnerability,
266 bool qeueing_allowed)
267{
268 RANAP_AllocationOrRetentionPriority_t *arp = MALLOC(sizeof(*arp));
269
270 arp->priorityLevel = level;
271
272 if (capability)
273 arp->pre_emptionCapability = RANAP_Pre_emptionCapability_may_trigger_pre_emption;
274 else
275 arp->pre_emptionCapability = RANAP_Pre_emptionCapability_shall_not_trigger_pre_emption;
276
277 if (vulnerability)
278 arp->pre_emptionVulnerability = RANAP_Pre_emptionVulnerability_pre_emptable;
279 else
280 arp->pre_emptionVulnerability = RANAP_Pre_emptionVulnerability_not_pre_emptable;
281
282 if (queueing_allowed)
283 arp->queuingAllowed = RANAP_QueuingAllowed_queueing_allowed;
284 else
285 arp->queuingAllowed = RANAP_QueuingAllowed_queueing_not_allowed;
286
287 return arp;
288}
289
290static RANAP_RAB_Parameters_t *new_rab_par_voice(void)
291{
292 RANAP_RAB_Parameters_t *rab = CALLOC(1, sizeof(*rab));
293
294 rab->trafficClass = RANAP_TrafficClass_conversational;
295 rab->rAB_AsymmetryIndicator = RANAP_RAB_AsymmetryIndicator_symmetric_bidirectional;
296
297 ASN_SEQUENCE_ADD(&rab->maxBitrate, new_long(12200));
298 rab->guaranteedBitrate = MALLOC(sizeof(*rab->guaranteedBitrate));
299 ASN_SEQUENCE_ADD(&rab->guaranteedBitrate, new_long(12200));
300 rab->deliveryOrder = RANAP_DeliveryOrder_delivery_order_requested;
301 rab->maxSDU_Size = 244;
302
303 sdup = new_sdu_pars(SDUPAR_P_VOICE0);
304 ASN_SEQUENCE_ADD(&rab->sDU_Parameters, sdup);
305 sdup = new_sdu_pars(SDUPAR_P_VOICE1);
306 ASN_SEQUENCE_ADD(&rab->sDU_Parameters, sdup);
307 sdup = new_sdu_pars(SDUPAR_P_VOICE2);
308 ASN_SEQUENCE_ADD(&rab->sDU_Parameters, sdup);
309
310 rab->transferDelay = new_long(80);
311 rab->allocationOrRetentionPriority = new_alloc_ret_prio(RANAP_PriorityLevel_no_priority, 0, 1, 0);
312
313 rab->sourceStatisticsDescriptor = new_long(RANAP_SourceStatisticsDescriptor_speech);
314
315 return rab;
316}
317
318static RANAP_RAB_Parameters_t *new_rab_par_data(void)
319{
320 RANAP_RAB_Parameters_t *rab = CALLOC(1, sizeof(*rab));
321
322 rab->trafficClass = RANAP_TrafficClass_background;
323 rab->rAB_AsymmetryIndicator = RANAP_RAB_AsymmetryIndicator_asymmetric_bidirectional;
324
325 ASN_SEQUENCE_ADD(&rab->maxBitrate, new_long(16000000));
326 ASN_SEQUENCE_ADD(&rab->maxBitrate, new_long(8000000));
327 rab->deliveryOrder = RANAP_DeliveryOrder_delivery_order_requested;
328 rab->maxSDU_Size = 8000;
329
330 sdup = new_sdu_pars(SDUPAR_P_DATA);
331 ASN_SEQUENCE_ADD(&rab->sDU_Parameters, sdup);
332
333 rab->allocationOrRetentionPriority = new_alloc_ret_prio(RANAP_PriorityLevel_no_priority, 0, 0, 0);
334
335 /* FIXME: RAB-Parameter-ExtendedMaxBitrateList for 42Mbps? */
336
337 return rab;
338}
339
340static RANAP_TransportLayerInformation_t *new_transp_info_rtp(uint32_t ip, uint16_t port)
341{
342 RANAP_TransportLayerInformation_t *tli = CALLOC(1, sizeof(*tli));
343 uint32_t *ipbuf = CALLOC(1, sizeof(*ipbuf));
344 uint8_t binding_id[4];
345
346 binding_id[0] = port >> 8;
347 binding_id[1] = port & 0xff;
348 binding_id[2] = binding_id[3] = 0;
349
350 asn1_u32_to_bitstring(&tli->transportLayerAddress, ipbuf, htonl(ip));
351 tli->iuTransportAssociation.present = RANAP_IuTransportAssociation_PR_bindingID;
352 OCTET_STRING_fromBuf(tli->iuTransportAssociation.choice.bindingID.buf,
353 (const char *) binding_id, sizeof(binding_id));
354
355 return tli;
356}
357
358static RANAP_TransportLayerInformation_t *new_transp_info_gtp(uint32_t ip, uint32_t tei)
359{
360 RANAP_TransportLayerInformation_t *tli = CALLOC(1, sizeof(*tli));
361 uint32_t *ipbuf = CALLOC(1, sizeof(*ipbuf));
362 uint32_t binding_buf = htonl(tei);
363
364 asn1_u32_to_bitstring(&tli->transportLayerAddress, ipbuf, htonl(ip));
365 tli->iuTransportAssociation.present = RANAP_IuTransportAssociation_PR_gTP_TEI;
366 OCTET_STRING_fromBuf(&tli->iuTransportAssociation.choice.bindingID,
367 (const char *) binding_buf, sizeof(binding_buf));
368
369 return tli;
370}
371
372static RANAP_UserPlaneInformation_t *new_upi(long mode, uint8_t mode_versions)
373{
374 RANAP_UserPlaneInformation_t *upi = CALLOC(1, sizeof(*upi));
375 uint8_t *buf = CALLOC(1, sizeof(*buf));
376
377 *buf = mode_versions;
378
379 upi->userPlaneMode = mode;
380 upi->uP_ModeVersions.buf = buf;
381 upi->uP_ModeVersions.size = 1;
382 upi->uP_ModeVersions.bits_unused = 0;
383
384 return upi;
385}
386
387int ranap_tx_rab_assign_voice(uint8_t rab_id)
Harald Welted328c1a2015-12-16 23:04:21 +0100388{
389 RANAP_ProtocolIE_FieldPair_t *pair;
390 RANAP_RAB_AssignmentRequestIEs_t ies;
391 RANAP_RAB_AssignmentRequest_t out;
392
Harald Welted328c1a2015-12-16 23:04:21 +0100393 memset(&ies, 0, sizeof(ies));
394
395 ies.presenceMask = RAB_ASSIGNMENTREQUESTIES_RANAP_RAB_SETUPORMODIFYLIST_PRESENT;
396 /* RANAP_RAB_IE_ContainerPairList_t */
397
398 RANAP_RAB_SetupOrModifyItemFirst_t first;
399
Harald Welte091039d2015-12-17 20:37:40 +0100400 first.rAB_ID = rab_id;
Harald Welted328c1a2015-12-16 23:04:21 +0100401 first.nAS_SynchronisationIndicator = FIXME;
Harald Welte091039d2015-12-17 20:37:40 +0100402 first.rAB_Parameters = new_rab_par_voice();
403 first.userPlaneInformation = new_upi(RANAP_UserPlaneMode_support_mode_for_predefined_SDU_sizes, 1); /* 2? */
404 first.transportLayerInformation = new_transp_info_rtp(ip, port);
Harald Welted328c1a2015-12-16 23:04:21 +0100405
406 RANAP_RAB_SetupOrModifyItemSecond_t second;
Harald Welte091039d2015-12-17 20:37:40 +0100407 memset(&second, 0, sizeof(second));
Harald Welted328c1a2015-12-16 23:04:21 +0100408
409 pair = ranap_new_ie_pair(RANAP_ProtocolIE_ID_id_RAB_SetupOrModifyItem,
410 RANAP_Criticality_reject,
Harald Welte091039d2015-12-17 20:37:40 +0100411 &asn_DEF_RANAP_RAB_SetupOrModifyItemFirst, &first,
Harald Welted328c1a2015-12-16 23:04:21 +0100412 RANAP_Criticality_ignore,
Harald Welte091039d2015-12-17 20:37:40 +0100413 &asn_DEF_RANAP_RAB_SetupOrModifyItemSecond, &second);
414
415 ASN_SEQUENCE_ADD(&ies.raB_SetupOrModifyList.list, pair);
416
417 rc = ranap_encode_rab_assignmentrequesties(&out, &ies);
418}
419
420int ranap_tx_rab_assign_data(uint8_t rab_id, uint32_t gtp_ip, uint16_t gtp_port)
421{
422 RANAP_ProtocolIE_FieldPair_t *pair;
423 RANAP_RAB_AssignmentRequestIEs_t ies;
424 RANAP_RAB_AssignmentRequest_t out;
425 RANAP_DataVolumeReportingIndication_t *dat_vol_ind = CALLOC(1, sizeof(*dat_vol_ind));
426 int rc;
427
428 memset(&ies, 0, sizeof(ies));
429
430 ies.presenceMask = RAB_ASSIGNMENTREQUESTIES_RANAP_RAB_SETUPORMODIFYLIST_PRESENT;
431 /* RANAP_RAB_IE_ContainerPairList_t */
432
433 RANAP_RAB_SetupOrModifyItemFirst_t first;
434
435 first.rAB_ID = rab_id;
436 first.nAS_SynchronisationIndicator = FIXME;
437 first.rAB_Parameters = new_rab_par_data();
438 first.userPlaneInformation = new_upi(RANAP_UserPlaneMode_transparent_mode, 1);
439 first.transportLayerInformation = new_transp_info_rtp(gtp_ip, gtp_port);
440
441 RANAP_RAB_SetupOrModifyItemSecond_t second;
442 memset(&second, 0, sizeof(second));
443 second.pDP_TypeInformation = CALLOC(1, sizeof(*second.pDP_TypeInformation));
444 ASN_SEQUENCE_ADD(&second.pDP_TypeInformation, new_long(RANAP_PDP_Type_ipv4));
445 *dat_vol_ind = RANAP_DataVolumeReportingIndication_do_not_report;
446 second.dataVolumeReportingIndication = dat_vol_ind;
447 second.dl_GTP_PDU_SequenceNumber = new_long(0);
448 second.ul_GTP_PDU_SequenceNumber = new_long(0);
449
450 pair = ranap_new_ie_pair(RANAP_ProtocolIE_ID_id_RAB_SetupOrModifyItem,
451 RANAP_Criticality_reject,
452 &asn_DEF_RANAP_RAB_SetupOrModifyItemFirst, &first,
453 RANAP_Criticality_ignore,
454 &asn_DEF_RANAP_RAB_SetupOrModifyItemSecond, &second);
Harald Welted328c1a2015-12-16 23:04:21 +0100455
456 ASN_SEQUENCE_ADD(&ies.raB_SetupOrModifyList.list, pair);
457
458 rc = ranap_encode_rab_assignmentrequesties(&out, &ies);
459}