blob: 15efb856644b823a23f5c78eccb6675aec75fc59 [file] [log] [blame]
Harald Welte77847ad2015-10-06 22:07:04 +02001/* hnb-gw specific code for RANAP */
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
22
Harald Welte350814a2015-09-10 22:32:15 +020023#include <osmocom/core/msgb.h>
24#include <osmocom/core/utils.h>
Harald Welte80401ad2015-09-11 19:48:06 +020025#include <osmocom/gsm/gsm48.h>
Harald Welte350814a2015-09-10 22:32:15 +020026
27#include <unistd.h>
28#include <errno.h>
29#include <string.h>
30
31#include "asn1helpers.h"
32
33#include "hnbgw.h"
Harald Weltee2e5d4d2015-09-10 23:49:45 +020034#include "hnbgw_rua.h"
Harald Welte350814a2015-09-10 22:32:15 +020035//#include "ranap_common.h"
36
37#include "ranap/RANAP_RANAP-PDU.h"
38#include "ranap/RANAP_ResetAcknowledge.h"
39#include "ranap/RANAP_Reset.h"
40#include "ranap/RANAP_ProtocolIE-ID.h"
41#include "ranap/RANAP_Cause.h"
42#include "ranap/RANAP_CN-DomainIndicator.h"
43#include "ranap/RANAP_GlobalRNC-ID.h"
44#include "ranap/RANAP_CriticalityDiagnostics.h"
45
Harald Welte350814a2015-09-10 22:32:15 +020046/***********************************************************************
47 * BEGIN auto-generated copy+pasted
48 ***********************************************************************/
49
50/* this is copy+pasted from the asn1tostruct generated code that doesn't
51 * compile as a whole */
52
53#define RANAP_DEBUG(x, args ...) DEBUGP(0, x, ## args)
54
55extern int asn1_xer_print;
56
57struct msgb *ranap_generate_successful_outcome(
58 e_RANAP_ProcedureCode procedureCode,
59 RANAP_Criticality_t criticality,
60 asn_TYPE_descriptor_t * td,
61 void *sptr);
62
63RANAP_IE_t *ranap_new_ie(RANAP_ProtocolIE_ID_t id, RANAP_Criticality_t criticality,
64 asn_TYPE_descriptor_t *type, void *sptr);
65
66#define RESETIES_RANAP_GLOBALRNC_ID_PRESENT (1 << 0)
67
68typedef struct RANAP_ResetIEs_s {
69 uint16_t presenceMask;
70 RANAP_Cause_t cause;
71 RANAP_CN_DomainIndicator_t cN_DomainIndicator;
72 RANAP_GlobalRNC_ID_t globalRNC_ID; ///< Optional field
73} RANAP_ResetIEs_t;
74
75#define RESETACKNOWLEDGEIES_RANAP_CRITICALITYDIAGNOSTICS_PRESENT (1 << 0)
76#define RESETACKNOWLEDGEIES_RANAP_GLOBALRNC_ID_PRESENT (1 << 1)
77
78typedef struct RANAP_ResetAcknowledgeIEs_s {
79 uint16_t presenceMask;
80 RANAP_CN_DomainIndicator_t cN_DomainIndicator;
81 RANAP_CriticalityDiagnostics_t criticalityDiagnostics; ///< Optional field
82 RANAP_GlobalRNC_ID_t globalRNC_ID; ///< Optional field
83} RANAP_ResetAcknowledgeIEs_t;
84
85int ranap_decode_reseties(
86 RANAP_ResetIEs_t *resetIEs,
87 ANY_t *any_p) {
88
89 RANAP_Reset_t reset;
90 RANAP_Reset_t *reset_p = &reset;
91 int i, decoded = 0;
92 int tempDecoded = 0;
93 assert(any_p != NULL);
94 assert(resetIEs != NULL);
95
96 RANAP_DEBUG("Decoding message RANAP_ResetIEs (%s:%d)\n", __FILE__, __LINE__);
97
98 ANY_to_type_aper(any_p, &asn_DEF_RANAP_Reset, (void**)&reset_p);
99
100 for (i = 0; i < reset_p->reset_ies.list.count; i++) {
101 RANAP_IE_t *ie_p;
102 ie_p = reset_p->reset_ies.list.array[i];
103 switch(ie_p->id) {
104 case RANAP_ProtocolIE_ID_id_Cause:
105 {
106 RANAP_Cause_t ranaP_Cause;
107 RANAP_Cause_t *ranaP_Cause_p = &ranaP_Cause;
108 tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_RANAP_Cause, (void**)&ranaP_Cause_p);
109 if (tempDecoded < 0) {
110 RANAP_DEBUG("Decoding of IE cause failed\n");
111 return -1;
112 }
113 decoded += tempDecoded;
114 if (asn1_xer_print)
115 xer_fprint(stdout, &asn_DEF_RANAP_Cause, ranaP_Cause_p);
116 memcpy(&resetIEs->cause, ranaP_Cause_p, sizeof(RANAP_Cause_t));
117 } break;
118 case RANAP_ProtocolIE_ID_id_CN_DomainIndicator:
119 {
120 RANAP_CN_DomainIndicator_t ranaP_CNDomainIndicator;
121 RANAP_CN_DomainIndicator_t *ranaP_CNDomainIndicator_p = &ranaP_CNDomainIndicator;
122 tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_RANAP_CN_DomainIndicator, (void**)&ranaP_CNDomainIndicator_p);
123 if (tempDecoded < 0) {
124 RANAP_DEBUG("Decoding of IE cN_DomainIndicator failed\n");
125 return -1;
126 }
127 decoded += tempDecoded;
128 if (asn1_xer_print)
129 xer_fprint(stdout, &asn_DEF_RANAP_CN_DomainIndicator, ranaP_CNDomainIndicator_p);
130 memcpy(&resetIEs->cN_DomainIndicator, ranaP_CNDomainIndicator_p, sizeof(RANAP_CN_DomainIndicator_t));
131 } break;
132 /* Optional field */
133 case RANAP_ProtocolIE_ID_id_GlobalRNC_ID:
134 {
135#if 0
136 RANAP_GlobalRNC_ID_t ranaP_GlobalRNCID;
137 RANAP_GlobalRNC_ID_t *ranaP_GlobalRNCID_p = &ranaP_GlobalRNCID;
138 resetIEs->presenceMask |= RESETIES_RANAP_GLOBALRNC_ID_PRESENT;
139 tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_RANAP_GlobalRNC_ID, (void**)&ranaP_GlobalRNCID_p);
140 if (tempDecoded < 0) {
141 RANAP_DEBUG("Decoding of IE globalRNC_ID failed\n");
142 return -1;
143 }
144 decoded += tempDecoded;
145 if (asn1_xer_print)
146 xer_fprint(stdout, &asn_DEF_RANAP_GlobalRNC_ID, ranaP_GlobalRNCID_p);
147 memcpy(&resetIEs->globalRNC_ID, ranaP_GlobalRNCID_p, sizeof(RANAP_GlobalRNC_ID_t));
148#endif
149 } break;
150 default:
151 RANAP_DEBUG("Unknown protocol IE id (%d) for message reseties\n", (int)ie_p->id);
152 return -1;
153 }
154 }
155 return decoded;
156}
157
158int ranap_encode_resetacknowledgeies(
159 RANAP_ResetAcknowledge_t *resetAcknowledge,
160 RANAP_ResetAcknowledgeIEs_t *resetAcknowledgeIEs) {
161
162 RANAP_IE_t *ie;
163
164 if ((ie = ranap_new_ie(RANAP_ProtocolIE_ID_id_CN_DomainIndicator,
165 RANAP_Criticality_reject,
166 &asn_DEF_RANAP_CN_DomainIndicator,
167 &resetAcknowledgeIEs->cN_DomainIndicator)) == NULL) {
168 return -1;
169 }
170 ASN_SEQUENCE_ADD(&resetAcknowledge->resetAcknowledge_ies.list, ie);
171
172 /* Optional field */
173 if ((resetAcknowledgeIEs->presenceMask & RESETACKNOWLEDGEIES_RANAP_CRITICALITYDIAGNOSTICS_PRESENT)
174 == RESETACKNOWLEDGEIES_RANAP_CRITICALITYDIAGNOSTICS_PRESENT) {
175 if ((ie = ranap_new_ie(RANAP_ProtocolIE_ID_id_CriticalityDiagnostics,
176 RANAP_Criticality_ignore,
177 &asn_DEF_RANAP_CriticalityDiagnostics,
178 &resetAcknowledgeIEs->criticalityDiagnostics)) == NULL) {
179 return -1;
180 }
181 ASN_SEQUENCE_ADD(&resetAcknowledge->resetAcknowledge_ies.list, ie);
182 }
183
184 /* Optional field */
185 if ((resetAcknowledgeIEs->presenceMask & RESETACKNOWLEDGEIES_RANAP_GLOBALRNC_ID_PRESENT)
186 == RESETACKNOWLEDGEIES_RANAP_GLOBALRNC_ID_PRESENT) {
187 if ((ie = ranap_new_ie(RANAP_ProtocolIE_ID_id_GlobalRNC_ID,
188 RANAP_Criticality_ignore,
189 &asn_DEF_RANAP_GlobalRNC_ID,
190 &resetAcknowledgeIEs->globalRNC_ID)) == NULL) {
191 return -1;
192 }
193 ASN_SEQUENCE_ADD(&resetAcknowledge->resetAcknowledge_ies.list, ie);
194 }
195
196 return 0;
197}
198
Harald Weltecc27beb2015-09-11 18:45:39 +0200199#include "ranap/RANAP_InitialUE-Message.h"
200#include "ranap/RANAP_CN-DomainIndicator.h"
201#include "ranap/RANAP_LAI.h"
202#include "ranap/RANAP_SAI.h"
203#include "ranap/RANAP_NAS-PDU.h"
204#include "ranap/RANAP_IuSignallingConnectionIdentifier.h"
205#include "ranap/RANAP_GlobalCN-ID.h"
206
207typedef struct RANAP_InitialUE_MessageIEs_s {
208 RANAP_CN_DomainIndicator_t cN_DomainIndicator;
209 RANAP_LAI_t lai;
210 RANAP_SAI_t sai;
211 RANAP_NAS_PDU_t nas_pdu;
212 RANAP_IuSignallingConnectionIdentifier_t iuSigConId;
213 RANAP_GlobalRNC_ID_t globalRNC_ID;
214} RANAP_InitialUE_MessageIEs_t;
215
216int ranap_decode_initialue_messageies(
217 RANAP_InitialUE_MessageIEs_t *initialUE_MessageIEs,
218 ANY_t *any_p) {
219
220 RANAP_InitialUE_Message_t initialUE_Message;
221 RANAP_InitialUE_Message_t *initialUE_Message_p = &initialUE_Message;
222 int i, decoded = 0;
223 int tempDecoded = 0;
224 assert(any_p != NULL);
225 assert(initialUE_MessageIEs != NULL);
226
227 RANAP_DEBUG("Decoding message RANAP_InitialUE_MessageIEs (%s:%d)\n", __FILE__, __LINE__);
228
229 ANY_to_type_aper(any_p, &asn_DEF_RANAP_InitialUE_Message, (void**)&initialUE_Message_p);
230
231 for (i = 0; i < initialUE_Message_p->initialUE_Message_ies.list.count; i++) {
232 RANAP_IE_t *ie_p;
233 ie_p = initialUE_Message_p->initialUE_Message_ies.list.array[i];
234 switch(ie_p->id) {
235 case RANAP_ProtocolIE_ID_id_CN_DomainIndicator:
236 {
237 RANAP_CN_DomainIndicator_t ranaP_CNDomainIndicator;
238 RANAP_CN_DomainIndicator_t *ranaP_CNDomainIndicator_p = &ranaP_CNDomainIndicator;
239 tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_RANAP_CN_DomainIndicator, (void**)&ranaP_CNDomainIndicator_p);
240 if (tempDecoded < 0) {
241 RANAP_DEBUG("Decoding of IE cN_DomainIndicator failed\n");
242 return -1;
243 }
244 decoded += tempDecoded;
245 if (asn1_xer_print)
246 xer_fprint(stdout, &asn_DEF_RANAP_CN_DomainIndicator, ranaP_CNDomainIndicator_p);
247 memcpy(&initialUE_MessageIEs->cN_DomainIndicator, ranaP_CNDomainIndicator_p, sizeof(RANAP_CN_DomainIndicator_t));
248 } break;
249 case RANAP_ProtocolIE_ID_id_LAI:
250 {
251 RANAP_LAI_t ranap_lai;
252 RANAP_LAI_t *ranap_lai_p = &ranap_lai;
253 tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_RANAP_LAI, (void**)&ranap_lai_p);
254 if (tempDecoded < 0) {
255 RANAP_DEBUG("Decoding of IE lai failed\n");
256 return -1;
257 }
258 decoded += tempDecoded;
259 if (asn1_xer_print)
260 xer_fprint(stdout, &asn_DEF_RANAP_LAI, ranap_lai_p);
261 memcpy(&initialUE_MessageIEs->lai, ranap_lai_p, sizeof(RANAP_LAI_t));
262 } break;
263 case RANAP_ProtocolIE_ID_id_SAI:
264 {
265 RANAP_SAI_t ranap_sai;
266 RANAP_SAI_t *ranap_sai_p = &ranap_sai;
267 tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_RANAP_SAI, (void**)&ranap_sai_p);
268 if (tempDecoded < 0) {
269 RANAP_DEBUG("Decoding of IE sai failed\n");
270 return -1;
271 }
272 decoded += tempDecoded;
273 if (asn1_xer_print)
274 xer_fprint(stdout, &asn_DEF_RANAP_SAI, ranap_sai_p);
275 memcpy(&initialUE_MessageIEs->sai, ranap_sai_p, sizeof(RANAP_SAI_t));
276 } break;
277 case RANAP_ProtocolIE_ID_id_NAS_PDU:
278 {
279 RANAP_NAS_PDU_t ranap_naspdu;
280 RANAP_NAS_PDU_t *ranap_naspdu_p = &ranap_naspdu;
281 tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_RANAP_NAS_PDU, (void**)&ranap_naspdu_p);
282 if (tempDecoded < 0) {
283 RANAP_DEBUG("Decoding of IE nas_pdu failed\n");
284 return -1;
285 }
286 decoded += tempDecoded;
287 if (asn1_xer_print)
288 xer_fprint(stdout, &asn_DEF_RANAP_NAS_PDU, ranap_naspdu_p);
289 memcpy(&initialUE_MessageIEs->nas_pdu, ranap_naspdu_p, sizeof(RANAP_NAS_PDU_t));
290 } break;
291 case RANAP_ProtocolIE_ID_id_IuSigConId:
292 {
293 RANAP_IuSignallingConnectionIdentifier_t ranaP_IuSignallingConnectionIdentifier;
294 RANAP_IuSignallingConnectionIdentifier_t *ranaP_IuSignallingConnectionIdentifier_p = &ranaP_IuSignallingConnectionIdentifier;
295 tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_RANAP_IuSignallingConnectionIdentifier, (void**)&ranaP_IuSignallingConnectionIdentifier_p);
296 if (tempDecoded < 0) {
297 RANAP_DEBUG("Decoding of IE iuSigConId failed\n");
298 return -1;
299 }
300 decoded += tempDecoded;
301 if (asn1_xer_print)
302 xer_fprint(stdout, &asn_DEF_RANAP_IuSignallingConnectionIdentifier, ranaP_IuSignallingConnectionIdentifier_p);
303 memcpy(&initialUE_MessageIEs->iuSigConId, ranaP_IuSignallingConnectionIdentifier_p, sizeof(RANAP_IuSignallingConnectionIdentifier_t));
304 } break;
305 case RANAP_ProtocolIE_ID_id_GlobalRNC_ID:
306 {
307 RANAP_GlobalRNC_ID_t ranaP_GlobalRNCID;
308 RANAP_GlobalRNC_ID_t *ranaP_GlobalRNCID_p = &ranaP_GlobalRNCID;
309 tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_RANAP_GlobalRNC_ID, (void**)&ranaP_GlobalRNCID_p);
310 if (tempDecoded < 0) {
311 RANAP_DEBUG("Decoding of IE globalRNC_ID failed\n");
312 return -1;
313 }
314 decoded += tempDecoded;
315 if (asn1_xer_print)
316 xer_fprint(stdout, &asn_DEF_RANAP_GlobalRNC_ID, ranaP_GlobalRNCID_p);
317 memcpy(&initialUE_MessageIEs->globalRNC_ID, ranaP_GlobalRNCID_p, sizeof(RANAP_GlobalRNC_ID_t));
318 } break;
319 default:
320 RANAP_DEBUG("Unknown protocol IE id (%d) for message initialue_messageies\n", (int)ie_p->id);
321 return -1;
322 }
323 }
324 return decoded;
325}
326
Harald Welte1c2ada02015-09-11 20:10:17 +0200327#include "ranap/RANAP_DirectTransfer.h"
328#include "ranap/RANAP_SAPI.h"
329#include "ranap/RANAP_RAC.h"
330
331#define DIRECTTRANSFERIES_RANAP_LAI_PRESENT (1 << 0)
332#define DIRECTTRANSFERIES_RANAP_RAC_PRESENT (1 << 1)
333#define DIRECTTRANSFERIES_RANAP_SAI_PRESENT (1 << 2)
334#define DIRECTTRANSFERIES_RANAP_SAPI_PRESENT (1 << 3)
335
336typedef struct RANAP_DirectTransferIEs_s {
337 uint16_t presenceMask;
338 RANAP_NAS_PDU_t nas_pdu;
339 RANAP_LAI_t lai; ///< Optional field
340 RANAP_RAC_t rac; ///< Optional field
341 RANAP_SAI_t sai; ///< Optional field
342 RANAP_SAPI_t sapi; ///< Optional field
343} RANAP_DirectTransferIEs_t;
344
345int ranap_decode_directtransferies(
346 RANAP_DirectTransferIEs_t *directTransferIEs,
347 ANY_t *any_p) {
348
349 RANAP_DirectTransfer_t directTransfer;
350 RANAP_DirectTransfer_t *directTransfer_p = &directTransfer;
351 int i, decoded = 0;
352 int tempDecoded = 0;
353 assert(any_p != NULL);
354 assert(directTransferIEs != NULL);
355
356 RANAP_DEBUG("Decoding message RANAP_DirectTransferIEs (%s:%d)\n", __FILE__, __LINE__);
357
358 ANY_to_type_aper(any_p, &asn_DEF_RANAP_DirectTransfer, (void**)&directTransfer_p);
359
360 for (i = 0; i < directTransfer_p->directTransfer_ies.list.count; i++) {
361 RANAP_IE_t *ie_p;
362 ie_p = directTransfer_p->directTransfer_ies.list.array[i];
363 switch(ie_p->id) {
364 case RANAP_ProtocolIE_ID_id_NAS_PDU:
365 {
366 RANAP_NAS_PDU_t ranap_naspdu;
367 RANAP_NAS_PDU_t *ranap_naspdu_p = &ranap_naspdu;
368 tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_RANAP_NAS_PDU, (void**)&ranap_naspdu_p);
369 if (tempDecoded < 0) {
370 RANAP_DEBUG("Decoding of IE nas_pdu failed\n");
371 return -1;
372 }
373 decoded += tempDecoded;
374 if (asn1_xer_print)
375 xer_fprint(stdout, &asn_DEF_RANAP_NAS_PDU, ranap_naspdu_p);
376 memcpy(&directTransferIEs->nas_pdu, ranap_naspdu_p, sizeof(RANAP_NAS_PDU_t));
377 } break;
378 /* Optional field */
379 case RANAP_ProtocolIE_ID_id_LAI:
380 {
381 RANAP_LAI_t ranap_lai;
382 RANAP_LAI_t *ranap_lai_p = &ranap_lai;
383 directTransferIEs->presenceMask |= DIRECTTRANSFERIES_RANAP_LAI_PRESENT;
384 tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_RANAP_LAI, (void**)&ranap_lai_p);
385 if (tempDecoded < 0) {
386 RANAP_DEBUG("Decoding of IE lai failed\n");
387 return -1;
388 }
389 decoded += tempDecoded;
390 if (asn1_xer_print)
391 xer_fprint(stdout, &asn_DEF_RANAP_LAI, ranap_lai_p);
392 memcpy(&directTransferIEs->lai, ranap_lai_p, sizeof(RANAP_LAI_t));
393 } break;
394 /* Optional field */
395 case RANAP_ProtocolIE_ID_id_RAC:
396 {
397 RANAP_RAC_t ranap_rac;
398 RANAP_RAC_t *ranap_rac_p = &ranap_rac;
399 directTransferIEs->presenceMask |= DIRECTTRANSFERIES_RANAP_RAC_PRESENT;
400 tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_RANAP_RAC, (void**)&ranap_rac_p);
401 if (tempDecoded < 0) {
402 RANAP_DEBUG("Decoding of IE rac failed\n");
403 return -1;
404 }
405 decoded += tempDecoded;
406 if (asn1_xer_print)
407 xer_fprint(stdout, &asn_DEF_RANAP_RAC, ranap_rac_p);
408 memcpy(&directTransferIEs->rac, ranap_rac_p, sizeof(RANAP_RAC_t));
409 } break;
410 /* Optional field */
411 case RANAP_ProtocolIE_ID_id_SAI:
412 {
413 RANAP_SAI_t ranap_sai;
414 RANAP_SAI_t *ranap_sai_p = &ranap_sai;
415 directTransferIEs->presenceMask |= DIRECTTRANSFERIES_RANAP_SAI_PRESENT;
416 tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_RANAP_SAI, (void**)&ranap_sai_p);
417 if (tempDecoded < 0) {
418 RANAP_DEBUG("Decoding of IE sai failed\n");
419 return -1;
420 }
421 decoded += tempDecoded;
422 if (asn1_xer_print)
423 xer_fprint(stdout, &asn_DEF_RANAP_SAI, ranap_sai_p);
424 memcpy(&directTransferIEs->sai, ranap_sai_p, sizeof(RANAP_SAI_t));
425 } break;
426 /* Optional field */
427 case RANAP_ProtocolIE_ID_id_SAPI:
428 {
429 RANAP_SAPI_t ranap_sapi;
430 RANAP_SAPI_t *ranap_sapi_p = &ranap_sapi;
431 directTransferIEs->presenceMask |= DIRECTTRANSFERIES_RANAP_SAPI_PRESENT;
432 tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_RANAP_SAPI, (void**)&ranap_sapi_p);
433 if (tempDecoded < 0) {
434 RANAP_DEBUG("Decoding of IE sapi failed\n");
435 return -1;
436 }
437 decoded += tempDecoded;
438 if (asn1_xer_print)
439 xer_fprint(stdout, &asn_DEF_RANAP_SAPI, ranap_sapi_p);
440 memcpy(&directTransferIEs->sapi, ranap_sapi_p, sizeof(RANAP_SAPI_t));
441 } break;
442 default:
443 RANAP_DEBUG("Unknown protocol IE id (%d) for message directtransferies\n", (int)ie_p->id);
444 return -1;
445 }
446 }
447 return decoded;
448}
449
450int ranap_encode_directtransferies(
451 RANAP_DirectTransfer_t *directTransfer,
452 RANAP_DirectTransferIEs_t *directTransferIEs) {
453
454 RANAP_IE_t *ie;
455
456 if ((ie = ranap_new_ie(RANAP_ProtocolIE_ID_id_NAS_PDU,
457 RANAP_Criticality_ignore,
458 &asn_DEF_RANAP_NAS_PDU,
459 &directTransferIEs->nas_pdu)) == NULL) {
460 return -1;
461 }
462 ASN_SEQUENCE_ADD(&directTransfer->directTransfer_ies.list, ie);
463
464 /* Optional field */
465 if ((directTransferIEs->presenceMask & DIRECTTRANSFERIES_RANAP_LAI_PRESENT)
466 == DIRECTTRANSFERIES_RANAP_LAI_PRESENT) {
467 if ((ie = ranap_new_ie(RANAP_ProtocolIE_ID_id_LAI,
468 RANAP_Criticality_ignore,
469 &asn_DEF_RANAP_LAI,
470 &directTransferIEs->lai)) == NULL) {
471 return -1;
472 }
473 ASN_SEQUENCE_ADD(&directTransfer->directTransfer_ies.list, ie);
474 }
475
476 /* Optional field */
477 if ((directTransferIEs->presenceMask & DIRECTTRANSFERIES_RANAP_RAC_PRESENT)
478 == DIRECTTRANSFERIES_RANAP_RAC_PRESENT) {
479 if ((ie = ranap_new_ie(RANAP_ProtocolIE_ID_id_RAC,
480 RANAP_Criticality_ignore,
481 &asn_DEF_RANAP_RAC,
482 &directTransferIEs->rac)) == NULL) {
483 return -1;
484 }
485 ASN_SEQUENCE_ADD(&directTransfer->directTransfer_ies.list, ie);
486 }
487
488 /* Optional field */
489 if ((directTransferIEs->presenceMask & DIRECTTRANSFERIES_RANAP_SAI_PRESENT)
490 == DIRECTTRANSFERIES_RANAP_SAI_PRESENT) {
491 if ((ie = ranap_new_ie(RANAP_ProtocolIE_ID_id_SAI,
492 RANAP_Criticality_ignore,
493 &asn_DEF_RANAP_SAI,
494 &directTransferIEs->sai)) == NULL) {
495 return -1;
496 }
497 ASN_SEQUENCE_ADD(&directTransfer->directTransfer_ies.list, ie);
498 }
499
500 /* Optional field */
501 if ((directTransferIEs->presenceMask & DIRECTTRANSFERIES_RANAP_SAPI_PRESENT)
502 == DIRECTTRANSFERIES_RANAP_SAPI_PRESENT) {
503 if ((ie = ranap_new_ie(RANAP_ProtocolIE_ID_id_SAPI,
504 RANAP_Criticality_ignore,
505 &asn_DEF_RANAP_SAPI,
506 &directTransferIEs->sapi)) == NULL) {
507 return -1;
508 }
509 ASN_SEQUENCE_ADD(&directTransfer->directTransfer_ies.list, ie);
510 }
511
512 return 0;
513}
514
515
516
Harald Weltecc27beb2015-09-11 18:45:39 +0200517
Harald Welte350814a2015-09-10 22:32:15 +0200518/***********************************************************************
519 * END auto-generated copy+pasted
520 ***********************************************************************/
521
Harald Weltee2e5d4d2015-09-10 23:49:45 +0200522static int ranap_tx_reset_ack(struct hnb_context *hnb,
523 RANAP_CN_DomainIndicator_t domain)
Harald Welte350814a2015-09-10 22:32:15 +0200524{
Harald Weltee2e5d4d2015-09-10 23:49:45 +0200525 RANAP_ResetAcknowledge_t out;
526 RANAP_ResetAcknowledgeIEs_t ies;
527 struct msgb *msg;
528 int rc;
Harald Welte350814a2015-09-10 22:32:15 +0200529
530 memset(&ies, 0, sizeof(ies));
Harald Weltee2e5d4d2015-09-10 23:49:45 +0200531 ies.cN_DomainIndicator = domain;
Harald Welte350814a2015-09-10 22:32:15 +0200532
Harald Weltee2e5d4d2015-09-10 23:49:45 +0200533 memset(&out, 0, sizeof(out));
534 rc = ranap_encode_resetacknowledgeies(&out, &ies);
535 if (rc < 0) {
536 LOGP(DMAIN, LOGL_ERROR, "error encoding reset ack IEs: %d\n", rc);
537 return rc;
538 }
539
540 msg = ranap_generate_successful_outcome(RANAP_ProcedureCode_id_Reset,
541 RANAP_Criticality_reject,
542 &asn_DEF_RANAP_ResetAcknowledge,
543 &out);
544 if (!msg)
545 return -1;
546
547 msg->dst = hnb;
548
549 rc = rua_tx_udt(msg);
550
551 return rc;
Harald Welte350814a2015-09-10 22:32:15 +0200552}
Harald Welte350814a2015-09-10 22:32:15 +0200553
554static int ranap_rx_init_reset(struct hnb_context *hnb, ANY_t *in)
555{
556 RANAP_ResetIEs_t ies;
557 int rc;
558
559 rc = ranap_decode_reseties(&ies, in);
560 if (rc < 0)
561 return rc;
562
563 DEBUGP(DMAIN, "RESET.req\n");
564
Harald Welte80401ad2015-09-11 19:48:06 +0200565 /* FIXME: Actually we have to wait for some guard time? */
566 /* FIXME: Reset all resources related to this HNB/RNC */
Harald Weltee2e5d4d2015-09-10 23:49:45 +0200567 ranap_tx_reset_ack(hnb, ies.cN_DomainIndicator);
568
Harald Welte350814a2015-09-10 22:32:15 +0200569 return 0;
570}
571
Harald Welte80401ad2015-09-11 19:48:06 +0200572int ranap_parse_lai(struct gprs_ra_id *ra_id, const RANAP_LAI_t *lai)
573{
574 uint8_t *ptr = lai->pLMNidentity.buf;
575
576 /* TS 25.413 9.2.3.55 */
577 if (lai->pLMNidentity.size != 3)
578 return -1;
579
580 ra_id->mcc = (ptr[0] & 0xF) * 100 +
581 (ptr[0] >> 4) * 10 +
582 (ptr[1] & 0xF);
583 ra_id->mnc = (ptr[2] & 0xF) +
584 (ptr[2] >> 4) * 10;
585 if ((ptr[1] >> 4) != 0xF)
586 ra_id->mnc += (ptr[1] >> 4) * 100;
587
588 ra_id->lac = asn1str_to_u16(&lai->lAC);
589
590 /* TS 25.413 9.2.3.6 */
591 if (ra_id->lac == 0 || ra_id->lac == 0xfffe)
592 return -1;
593
594 return 0;
595}
596
597static int ranap_rx_init_ue_msg(struct hnb_context *hnb, ANY_t *in)
598{
599 RANAP_InitialUE_MessageIEs_t ies;
600 struct gprs_ra_id ra_id;
601 int rc;
602
603 rc = ranap_decode_initialue_messageies(&ies, in);
604 if (rc < 0)
605 return rc;
606
607 /* location area ID of the serving cell */
608 ranap_parse_lai(&ra_id, &ies.lai);
609
610 DEBUGP(DMAIN, "%u-%u-%u: InitialUE: %s\n", ra_id.mcc, ra_id.mnc,
611 ra_id.lac, osmo_hexdump(ies.nas_pdu.buf, ies.nas_pdu.size));
612 /* FIXME: hand NAS PDU into MSC */
613
614 return 0;
615}
616
Harald Welte1c2ada02015-09-11 20:10:17 +0200617static int ranap_rx_dt(struct hnb_context *hnb, ANY_t *in)
618{
619 RANAP_DirectTransferIEs_t ies;
620 int sapi = 0;
621 int rc;
622
623 rc = ranap_decode_directtransferies(&ies, in);
624 if (rc < 0)
625 return rc;
626
627 if (ies.presenceMask & DIRECTTRANSFERIES_RANAP_SAPI_PRESENT)
628 sapi = ies.sapi;
629
630 if (ies.presenceMask & DIRECTTRANSFERIES_RANAP_LAI_PRESENT) {
631 /* FIXME: Update LAI associated with UE */
632 }
633
634 if (ies.presenceMask & DIRECTTRANSFERIES_RANAP_RAC_PRESENT) {
635 /* FIXME: Update RAC associated with UE */
636 }
637
638 DEBUGP(DMAIN, "DirectTransfer: %s\n",
639 osmo_hexdump(ies.nas_pdu.buf, ies.nas_pdu.size));
640 /* FIXME: hand NAS PDU into MSC */
641}
642
Harald Welte350814a2015-09-10 22:32:15 +0200643static int ranap_rx_initiating_msg(struct hnb_context *hnb, RANAP_InitiatingMessage_t *imsg)
644{
645 int rc;
646
647 switch (imsg->procedureCode) {
648 case RANAP_ProcedureCode_id_Reset:
649 rc = ranap_rx_init_reset(hnb, &imsg->value);
650 break;
Harald Welte80401ad2015-09-11 19:48:06 +0200651 case RANAP_ProcedureCode_id_InitialUE_Message:
652 rc = ranap_rx_init_ue_msg(hnb, &imsg->value);
653 break;
Harald Welte1c2ada02015-09-11 20:10:17 +0200654 case RANAP_ProcedureCode_id_DirectTransfer:
655 rc = ranap_rx_dt(hnb, &imsg->value);
656 break;
Harald Welte350814a2015-09-10 22:32:15 +0200657 }
658}
659
660static int _hnbgw_ranap_rx(struct hnb_context *hnb, RANAP_RANAP_PDU_t *pdu)
661{
662 int rc;
663
664 switch (pdu->present) {
665 case RANAP_RANAP_PDU_PR_initiatingMessage:
666 rc = ranap_rx_initiating_msg(hnb, &pdu->choice.initiatingMessage);
667 break;
668 case RANAP_RANAP_PDU_PR_successfulOutcome:
669 break;
670 case RANAP_RANAP_PDU_PR_unsuccessfulOutcome:
671 break;
672 default:
673 break;
674 }
675}
676
677
678int hnbgw_ranap_rx(struct msgb *msg, uint8_t *data, size_t len)
679{
680 RANAP_RANAP_PDU_t _pdu, *pdu = &_pdu;
681 asn_dec_rval_t dec_ret;
682 int rc;
683
684 memset(pdu, 0, sizeof(*pdu));
685 dec_ret = aper_decode(NULL,&asn_DEF_RANAP_RANAP_PDU, (void **) &pdu,
686 data, len, 0, 0);
687 if (dec_ret.code != RC_OK) {
688 LOGP(DMAIN, LOGL_ERROR, "Error in RANAP ASN.1 decode\n");
689 return rc;
690 }
691
692 rc = _hnbgw_ranap_rx(msg->dst, pdu);
693
694 return rc;
695}
696
697int hnbgw_ranap_init(void)
698{
699
700}