blob: d2c875eb6477661aa73a1bdef83044af860b2b38 [file] [log] [blame]
Harald Welte3cfa4502015-12-25 15:33:41 +01001/* RANAP interface for a core-network node */
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 <unistd.h>
22#include <errno.h>
23#include <string.h>
24
25#include <osmocom/core/utils.h>
26#include <osmocom/core/logging.h>
27
Neels Hofmeyr96979af2016-01-05 15:19:44 +010028#include <osmocom/ranap/ranap_common.h>
Harald Welte5c6bd512016-01-05 15:05:03 +010029#include <osmocom/ranap/ranap_common_cn.h>
Neels Hofmeyr96979af2016-01-05 15:19:44 +010030#include <osmocom/ranap/ranap_ies_defs.h>
Harald Welte3cfa4502015-12-25 15:33:41 +010031
Neels Hofmeyrdf63de22016-08-18 13:13:55 +020032#include <osmocom/iuh/hnbgw.h>
Harald Welte3cfa4502015-12-25 15:33:41 +010033
34static int cn_ranap_rx_initiating_msg_co(void *ctx, RANAP_InitiatingMessage_t *imsg,
35 ranap_message *message)
36{
37 int rc = 0;
38
39 message->procedureCode = imsg->procedureCode;
40 message->criticality = imsg->criticality;
41
42 DEBUGP(DRANAP, "Rx CO IM (%s)\n",
43 get_value_string(ranap_procedure_code_vals, imsg->procedureCode));
44
45 switch (imsg->procedureCode) {
46 case RANAP_ProcedureCode_id_InitialUE_Message:
47 rc = ranap_decode_initialue_messageies(&message->msg.initialUE_MessageIEs, &imsg->value);
48 break;
49 case RANAP_ProcedureCode_id_DirectTransfer:
50 rc = ranap_decode_directtransferies(&message->msg.directTransferIEs, &imsg->value);
51 break;
52 case RANAP_ProcedureCode_id_RAB_ReleaseRequest:
53 /* RNC requests the release of RAB */
54 rc = ranap_decode_rab_releaserequesties(&message->msg.raB_ReleaseRequestIEs, &imsg->value);
55 break;
56 case RANAP_ProcedureCode_id_Iu_ReleaseRequest:
57 /* RNC requests the release of Iu */
58 rc = ranap_decode_iu_releaserequesties(&message->msg.iu_ReleaseRequestIEs, &imsg->value);
59 break;
60 case RANAP_ProcedureCode_id_ErrorIndication:
61 rc = ranap_decode_errorindicationies(&message->msg.errorIndicationIEs, &imsg->value);
62 break;
63 case RANAP_ProcedureCode_id_RAB_ModifyRequest:
64 rc = ranap_decode_rab_modifyrequesties(&message->msg.raB_ModifyRequestIEs, &imsg->value);
65 break;
Neels Hofmeyr68b7a472016-04-19 00:13:11 +020066 case RANAP_ProcedureCode_id_SecurityModeControl:
Neels Hofmeyr39fc8812016-04-19 02:37:04 +020067 /* FIXME this is not a message received by CN (used by hnb-test) */
Neels Hofmeyr68b7a472016-04-19 00:13:11 +020068 /* Only an RNC will receive a Security Mode Control as
69 * Initiating Message, in other words: only hnb-test. */
70 rc = ranap_decode_securitymodecommandies(&message->msg.securityModeCommandIEs, &imsg->value);
71 break;
Neels Hofmeyr39fc8812016-04-19 02:37:04 +020072 case RANAP_ProcedureCode_id_Iu_Release:
73 /* FIXME this is not a message received by CN (used by hnb-test) */
74 rc = ranap_decode_iu_releasecommandies(&message->msg.iu_ReleaseCommandIEs, &imsg->value);
75 break;
Harald Welte3cfa4502015-12-25 15:33:41 +010076 default:
77 LOGP(DRANAP, LOGL_NOTICE, "Received suspicious RANAP "
78 "Procedure %s (CO, IM) from RNC, ignoring\n",
79 get_value_string(ranap_procedure_code_vals, imsg->procedureCode));
80 rc = -1;
81 break;
82 }
83
84 return rc;
85}
86
Daniel Willmannc858fe92016-01-07 14:28:06 +010087static void cn_ranap_free_initiating_msg_co(ranap_message *message)
88{
89 switch (message->procedureCode) {
90 case RANAP_ProcedureCode_id_InitialUE_Message:
91 ranap_free_initialue_messageies(&message->msg.initialUE_MessageIEs);
92 break;
93 case RANAP_ProcedureCode_id_DirectTransfer:
94 ranap_free_directtransferies(&message->msg.directTransferIEs);
95 break;
96 case RANAP_ProcedureCode_id_RAB_ReleaseRequest:
97 /* RNC requests the release of RAB */
98 ranap_free_rab_releaserequesties(&message->msg.raB_ReleaseRequestIEs);
99 break;
100 case RANAP_ProcedureCode_id_Iu_ReleaseRequest:
101 /* RNC requests the release of Iu */
102 ranap_free_iu_releaserequesties(&message->msg.iu_ReleaseRequestIEs);
103 break;
104 case RANAP_ProcedureCode_id_ErrorIndication:
105 ranap_free_errorindicationies(&message->msg.errorIndicationIEs);
106 break;
107 case RANAP_ProcedureCode_id_RAB_ModifyRequest:
108 ranap_free_rab_modifyrequesties(&message->msg.raB_ModifyRequestIEs);
109 break;
Neels Hofmeyr68b7a472016-04-19 00:13:11 +0200110 case RANAP_ProcedureCode_id_SecurityModeControl:
Neels Hofmeyr39fc8812016-04-19 02:37:04 +0200111 /* FIXME this is not a message received by CN (used by hnb-test) */
Neels Hofmeyr68b7a472016-04-19 00:13:11 +0200112 /* Only an RNC will receive a Security Mode Control as
113 * Initiating Message, in other words: only hnb-test. */
114 ranap_free_securitymodecommandies(&message->msg.securityModeCommandIEs);
115 break;
Neels Hofmeyr39fc8812016-04-19 02:37:04 +0200116 case RANAP_ProcedureCode_id_Iu_Release:
117 /* FIXME this is not a message received by CN (used by hnb-test) */
118 ranap_free_iu_releasecommandies(&message->msg.iu_ReleaseCommandIEs);
119 break;
Daniel Willmannc858fe92016-01-07 14:28:06 +0100120 default:
121 LOGP(DRANAP, LOGL_NOTICE, "Not freeing suspicious RANAP "
122 "Procedure %s (CO, IM) from RNC\n",
123 get_value_string(ranap_procedure_code_vals, message->procedureCode));
124 break;
125 }
126}
127
Harald Welte3cfa4502015-12-25 15:33:41 +0100128static int cn_ranap_rx_successful_msg_co(void *ctx, RANAP_SuccessfulOutcome_t *imsg,
129 ranap_message *message)
130{
131 int rc = 0;
132
133 message->procedureCode = imsg->procedureCode;
134 message->criticality = imsg->criticality;
135
Harald Weltea31e63a2015-12-28 13:19:35 +0100136 DEBUGP(DRANAP, "Rx CO SO (%s)\n",
Harald Welte3cfa4502015-12-25 15:33:41 +0100137 get_value_string(ranap_procedure_code_vals, imsg->procedureCode));
138
139 switch (imsg->procedureCode) {
140 case RANAP_ProcedureCode_id_RAB_Assignment:
141 /* RAB assignment response */
142 rc = ranap_decode_rab_assignmentresponseies(&message->msg.raB_AssignmentResponseIEs, &imsg->value);
143 break;
144 case RANAP_ProcedureCode_id_SecurityModeControl:
145 /* Security Mode Complete */
146 rc = ranap_decode_securitymodecompleteies(&message->msg.securityModeCompleteIEs, &imsg->value);
147 break;
148 case RANAP_ProcedureCode_id_Iu_Release:
149 /* Iu release Complete; confirmation of CN-initiated release */
150 rc = ranap_decode_iu_releasecompleteies(&message->msg.iu_ReleaseCompleteIEs, &imsg->value);
151 break;
152 default:
153 LOGP(DRANAP, LOGL_NOTICE, "Received suspicious RANAP "
154 "Procedure %s (SO) from RNC, ignoring\n",
155 get_value_string(ranap_procedure_code_vals, imsg->procedureCode));
156 rc = -1;
157 break;
158 }
159
160 return rc;
161}
162
Daniel Willmannc858fe92016-01-07 14:28:06 +0100163static void cn_ranap_free_successful_msg_co(ranap_message *message)
164{
165 switch (message->procedureCode) {
166 case RANAP_ProcedureCode_id_RAB_Assignment:
167 /* RAB assignment response */
168 ranap_free_rab_assignmentresponseies(&message->msg.raB_AssignmentResponseIEs);
169 break;
170 case RANAP_ProcedureCode_id_SecurityModeControl:
171 /* Security Mode Complete */
172 ranap_free_securitymodecompleteies(&message->msg.securityModeCompleteIEs);
173 break;
174 case RANAP_ProcedureCode_id_Iu_Release:
175 /* Iu release Complete; confirmation of CN-initiated release */
176 ranap_free_iu_releasecompleteies(&message->msg.iu_ReleaseCompleteIEs);
177 break;
178 default:
179 LOGP(DRANAP, LOGL_NOTICE, "Not freeing suspicious RANAP "
180 "Procedure %s (SO) from RNC\n",
181 get_value_string(ranap_procedure_code_vals, message->procedureCode));
182 break;
183 }
184}
185
Harald Welte7bccc982015-12-28 14:44:49 +0100186static int cn_ranap_rx_outcome_msg_co(void *ctx, RANAP_Outcome_t *imsg,
187 ranap_message *message)
188{
189 int rc = 0;
190
191 message->procedureCode = imsg->procedureCode;
192 message->criticality = imsg->criticality;
193
194 DEBUGP(DRANAP, "Rx CO O (%s)\n",
195 get_value_string(ranap_procedure_code_vals, imsg->procedureCode));
196
197 switch (imsg->procedureCode) {
198 case RANAP_ProcedureCode_id_RAB_Assignment:
199 /* RAB assignment response */
200 rc = ranap_decode_rab_assignmentresponseies(&message->msg.raB_AssignmentResponseIEs, &imsg->value);
201 break;
202 default:
203 LOGP(DRANAP, LOGL_NOTICE, "Received suspicious RANAP "
204 "Procedure %s (O) from RNC, ignoring\n",
205 get_value_string(ranap_procedure_code_vals, imsg->procedureCode));
206 rc = -1;
207 break;
208 }
209
210 return rc;
211}
212
Daniel Willmannc858fe92016-01-07 14:28:06 +0100213static void cn_ranap_free_outcome_msg_co(ranap_message *message)
214{
215 switch (message->procedureCode) {
216 case RANAP_ProcedureCode_id_RAB_Assignment:
217 /* RAB assignment response */
218 ranap_free_rab_assignmentresponseies(&message->msg.raB_AssignmentResponseIEs);
219 break;
220 default:
221 LOGP(DRANAP, LOGL_NOTICE, "Not freeing suspicious RANAP "
222 "Procedure %s (O) from RNC\n",
223 get_value_string(ranap_procedure_code_vals, message->procedureCode));
224 break;
225 }
226}
227
Harald Welte3cfa4502015-12-25 15:33:41 +0100228static int _cn_ranap_rx_co(void *ctx, RANAP_RANAP_PDU_t *pdu, ranap_message *message)
229{
230 int rc = 0;
231
232 switch (pdu->present) {
233 case RANAP_RANAP_PDU_PR_initiatingMessage:
234 rc = cn_ranap_rx_initiating_msg_co(ctx, &pdu->choice.initiatingMessage, message);
235 break;
236 case RANAP_RANAP_PDU_PR_successfulOutcome:
237 rc = cn_ranap_rx_successful_msg_co(ctx, &pdu->choice.successfulOutcome, message);
238 break;
239 case RANAP_RANAP_PDU_PR_unsuccessfulOutcome:
240 LOGP(DRANAP, LOGL_NOTICE, "Received unsupported RANAP "
241 "unsuccessful outcome procedure %s (CO) from RNC, ignoring\n",
242 get_value_string(ranap_procedure_code_vals,
243 pdu->choice.unsuccessfulOutcome.procedureCode));
244 rc = -1;
245 break;
Harald Welte7bccc982015-12-28 14:44:49 +0100246 case RANAP_RANAP_PDU_PR_outcome:
Daniel Willmann366dcf22016-01-07 14:12:07 +0100247 rc = cn_ranap_rx_outcome_msg_co(ctx, &pdu->choice.outcome, message);
Harald Welte7bccc982015-12-28 14:44:49 +0100248 break;
Harald Welte3cfa4502015-12-25 15:33:41 +0100249 default:
250 LOGP(DRANAP, LOGL_NOTICE, "Received suspicious RANAP "
251 "presence %s (CO) from RNC, ignoring\n",
252 get_value_string(ranap_presence_vals, pdu->present));
253 rc = -1;
254 break;
255 }
256
257 return rc;
258}
259
Daniel Willmannc858fe92016-01-07 14:28:06 +0100260static void _cn_ranap_free_co(ranap_message *message)
261{
262 switch (message->direction) {
263 case RANAP_RANAP_PDU_PR_initiatingMessage:
264 cn_ranap_free_initiating_msg_co(message);
265 break;
266 case RANAP_RANAP_PDU_PR_successfulOutcome:
267 cn_ranap_free_successful_msg_co(message);
268 break;
269 case RANAP_RANAP_PDU_PR_unsuccessfulOutcome:
270 LOGP(DRANAP, LOGL_NOTICE, "Not freeing unsupported RANAP "
271 "unsuccessful outcome procedure (CO) from RNC\n");
272 break;
273 case RANAP_RANAP_PDU_PR_outcome:
274 cn_ranap_free_outcome_msg_co(message);
275 break;
276 default:
277 LOGP(DRANAP, LOGL_NOTICE, "Received suspicious RANAP "
278 "presence %s (CO) from RNC, ignoring\n",
279 get_value_string(ranap_presence_vals, message->direction));
280 break;
281 }
282}
283
Harald Welte3cfa4502015-12-25 15:33:41 +0100284/* receive a connection-oriented RANAP message and call
285 * cn_ranap_handle_co() with the resulting ranap_message struct */
Harald Welte8fa5d552016-01-05 15:01:53 +0100286int ranap_cn_rx_co(ranap_handle_cb cb, void *ctx, uint8_t *data, size_t len)
Harald Welte3cfa4502015-12-25 15:33:41 +0100287{
288 RANAP_RANAP_PDU_t *pdu = NULL;
289 ranap_message message;
290 asn_dec_rval_t dec_ret;
291 int rc;
292
293 memset(&message, 0, sizeof(message));
294
Harald Welte3cfa4502015-12-25 15:33:41 +0100295 dec_ret = aper_decode(NULL,&asn_DEF_RANAP_RANAP_PDU, (void **) &pdu,
296 data, len, 0, 0);
297 if (dec_ret.code != RC_OK) {
298 LOGP(DRANAP, LOGL_ERROR, "Error in RANAP ASN.1 decode\n");
Neels Hofmeyra6a68e62016-11-25 13:21:02 +0100299 return -1;
Harald Welte3cfa4502015-12-25 15:33:41 +0100300 }
301
302 message.direction = pdu->present;
303
304 rc = _cn_ranap_rx_co(ctx, pdu, &message);
305
306 if (rc == 0)
Harald Welte8fa5d552016-01-05 15:01:53 +0100307 (*cb)(ctx, &message);
Harald Welte49287972015-12-29 19:00:35 +0100308 else
309 LOGP(DRANAP, LOGL_ERROR, "Not calling cn_ranap_handle_co() due to rc=%d\n", rc);
Harald Welte3cfa4502015-12-25 15:33:41 +0100310
Daniel Willmannc858fe92016-01-07 14:28:06 +0100311 /* Free the asn1 structs in message */
312 _cn_ranap_free_co(&message);
313
Harald Welte3cfa4502015-12-25 15:33:41 +0100314 ASN_STRUCT_FREE(asn_DEF_RANAP_RANAP_PDU, pdu);
315
316 return rc;
317}
318
319static int cn_ranap_rx_initiating_msg_cl(void *ctx, RANAP_InitiatingMessage_t *imsg,
320 ranap_message *message)
321{
Harald Welteda86fe52017-11-21 08:14:37 +0100322 int rc = 0;
Harald Welte3cfa4502015-12-25 15:33:41 +0100323
324 message->procedureCode = imsg->procedureCode;
325 message->criticality = imsg->criticality;
326
327 DEBUGP(DRANAP, "Rx CL IM (%s)\n",
328 get_value_string(ranap_procedure_code_vals, imsg->procedureCode));
329
330 switch (imsg->procedureCode) {
331 case RANAP_ProcedureCode_id_Reset:
332 /* Reset request */
333 rc = ranap_decode_reseties(&message->msg.resetIEs, &imsg->value);
334 break;
335 case RANAP_ProcedureCode_id_OverloadControl: /* Overload ind */
336 rc = ranap_decode_overloadies(&message->msg.overloadIEs, &imsg->value);
337 break;
338 case RANAP_ProcedureCode_id_ErrorIndication: /* Error ind */
339 rc = ranap_decode_errorindicationies(&message->msg.errorIndicationIEs, &imsg->value);
340 break;
341 case RANAP_ProcedureCode_id_ResetResource: /* request */
342 rc = ranap_decode_resetresourceies(&message->msg.resetResourceIEs, &imsg->value);
343 break;
344 case RANAP_ProcedureCode_id_InformationTransfer:
345 rc = ranap_decode_informationtransferindicationies(&message->msg.informationTransferIndicationIEs, &imsg->value);
346 break;
347 case RANAP_ProcedureCode_id_DirectInformationTransfer:
348 rc = ranap_decode_directinformationtransferies(&message->msg.directInformationTransferIEs, &imsg->value);
349 break;
350 case RANAP_ProcedureCode_id_UplinkInformationExchange:
351 rc = ranap_decode_uplinkinformationexchangerequesties(&message->msg.uplinkInformationExchangeRequestIEs, &imsg->value);
352 break;
Neels Hofmeyr39fc8812016-04-19 02:37:04 +0200353 case RANAP_ProcedureCode_id_Paging:
354 /* FIXME this is not a message received by CN (used by hnb-test) */
355 rc = ranap_decode_pagingies(&message->msg.pagingIEs, &imsg->value);
356 break;
Harald Welte3cfa4502015-12-25 15:33:41 +0100357 default:
358 LOGP(DRANAP, LOGL_NOTICE, "Received suspicious RANAP "
359 "Procedure %s (CL, IM) from RNC, ignoring\n",
360 get_value_string(ranap_procedure_code_vals, imsg->procedureCode));
361 break;
362 }
Harald Welteda86fe52017-11-21 08:14:37 +0100363
364 return rc;
Harald Welte3cfa4502015-12-25 15:33:41 +0100365}
366
Daniel Willmannc35b2982016-01-07 14:13:49 +0100367static void cn_ranap_free_initiating_msg_cl(ranap_message *message)
368{
369
370 switch (message->procedureCode) {
371 case RANAP_ProcedureCode_id_Reset:
372 /* Reset request */
373 ranap_free_reseties(&message->msg.resetIEs);
374 break;
375 case RANAP_ProcedureCode_id_OverloadControl: /* Overload ind */
376 ranap_free_overloadies(&message->msg.overloadIEs);
377 break;
378 case RANAP_ProcedureCode_id_ErrorIndication: /* Error ind */
379 ranap_free_errorindicationies(&message->msg.errorIndicationIEs);
380 break;
381 case RANAP_ProcedureCode_id_ResetResource: /* request */
382 ranap_free_resetresourceies(&message->msg.resetResourceIEs);
383 break;
384 case RANAP_ProcedureCode_id_InformationTransfer:
385 ranap_free_informationtransferindicationies(&message->msg.informationTransferIndicationIEs);
386 break;
387 case RANAP_ProcedureCode_id_DirectInformationTransfer:
388 ranap_free_directinformationtransferies(&message->msg.directInformationTransferIEs);
389 break;
390 case RANAP_ProcedureCode_id_UplinkInformationExchange:
391 ranap_free_uplinkinformationexchangerequesties(&message->msg.uplinkInformationExchangeRequestIEs);
392 break;
Neels Hofmeyr39fc8812016-04-19 02:37:04 +0200393 case RANAP_ProcedureCode_id_Paging:
394 /* FIXME this is not a message received by CN (used by hnb-test) */
395 ranap_free_pagingies(&message->msg.pagingIEs);
396 break;
Daniel Willmannc35b2982016-01-07 14:13:49 +0100397 default:
398 LOGP(DRANAP, LOGL_NOTICE, "Not freeing suspicious RANAP "
399 "Procedure %s (CL, IM)\n",
400 get_value_string(ranap_procedure_code_vals, message->procedureCode));
401 break;
402 }
403}
404
Harald Welte3cfa4502015-12-25 15:33:41 +0100405static int cn_ranap_rx_successful_msg_cl(void *ctx, RANAP_SuccessfulOutcome_t *imsg,
406 ranap_message *message)
407{
Harald Welteda86fe52017-11-21 08:14:37 +0100408 int rc = 0;
Harald Welte3cfa4502015-12-25 15:33:41 +0100409
410 message->procedureCode = imsg->procedureCode;
411 message->criticality = imsg->criticality;
412
413 DEBUGP(DRANAP, "Rx CL SO (%s)\n",
414 get_value_string(ranap_procedure_code_vals, imsg->procedureCode));
415
416 switch (imsg->procedureCode) {
417 case RANAP_ProcedureCode_id_Reset: /* Reset acknowledge */
418 rc = ranap_decode_resetacknowledgeies(&message->msg.resetAcknowledgeIEs, &imsg->value);
419 break;
420 case RANAP_ProcedureCode_id_ResetResource: /* response */
421 rc = ranap_decode_resetresourceacknowledgeies(&message->msg.resetResourceAcknowledgeIEs, &imsg->value);
Daniel Willmann618f0f52016-01-07 14:11:01 +0100422 break;
Harald Welte3cfa4502015-12-25 15:33:41 +0100423 case RANAP_ProcedureCode_id_InformationTransfer:
424 rc = ranap_decode_resetresourceacknowledgeies(&message->msg.resetResourceAcknowledgeIEs, &imsg->value);
425 break;
426 case RANAP_ProcedureCode_id_DirectInformationTransfer:
427 rc = ranap_decode_informationtransferconfirmationies(&message->msg.informationTransferConfirmationIEs, &imsg->value);
428 break;
429 case RANAP_ProcedureCode_id_UplinkInformationExchange:
430 rc = ranap_decode_uplinkinformationexchangeresponseies(&message->msg.uplinkInformationExchangeResponseIEs, &imsg->value);
431 break;
432 default:
433 LOGP(DRANAP, LOGL_NOTICE, "Received suspicious RANAP "
434 "Procedure %s (CL, SO) from RNC, ignoring\n",
435 get_value_string(ranap_procedure_code_vals, imsg->procedureCode));
436 break;
437 }
Harald Welteda86fe52017-11-21 08:14:37 +0100438
439 return rc;
Harald Welte3cfa4502015-12-25 15:33:41 +0100440}
441
Daniel Willmannc35b2982016-01-07 14:13:49 +0100442static void cn_ranap_free_successful_msg_cl(ranap_message *message)
443{
444 switch (message->procedureCode) {
445 case RANAP_ProcedureCode_id_Reset: /* Reset acknowledge */
446 ranap_free_resetacknowledgeies(&message->msg.resetAcknowledgeIEs);
447 break;
448 case RANAP_ProcedureCode_id_ResetResource: /* response */
449 ranap_free_resetresourceacknowledgeies(&message->msg.resetResourceAcknowledgeIEs);
450 break;
451 case RANAP_ProcedureCode_id_InformationTransfer:
452 ranap_free_resetresourceacknowledgeies(&message->msg.resetResourceAcknowledgeIEs);
453 break;
454 case RANAP_ProcedureCode_id_DirectInformationTransfer:
455 ranap_free_informationtransferconfirmationies(&message->msg.informationTransferConfirmationIEs);
456 break;
457 case RANAP_ProcedureCode_id_UplinkInformationExchange:
458 ranap_free_uplinkinformationexchangeresponseies(&message->msg.uplinkInformationExchangeResponseIEs);
459 break;
460 default:
461 LOGP(DRANAP, LOGL_NOTICE, "Not freeing suspicious RANAP "
462 "Procedure %s (CL, SO)\n",
463 get_value_string(ranap_procedure_code_vals, message->procedureCode));
464 break;
465 }
466}
467
Harald Welte3cfa4502015-12-25 15:33:41 +0100468static int _cn_ranap_rx_cl(void *ctx, RANAP_RANAP_PDU_t *pdu, ranap_message *message)
469{
Harald Welteda86fe52017-11-21 08:14:37 +0100470 int rc = 0;
Harald Welte3cfa4502015-12-25 15:33:41 +0100471
Daniel Willmannc35b2982016-01-07 14:13:49 +0100472 /* Extend _cn_ranap_free_cl as well when extending this function */
473
Harald Welte3cfa4502015-12-25 15:33:41 +0100474 switch (pdu->present) {
475 case RANAP_RANAP_PDU_PR_initiatingMessage:
476 rc = cn_ranap_rx_initiating_msg_cl(ctx, &pdu->choice.initiatingMessage,
477 message);
478 break;
479 case RANAP_RANAP_PDU_PR_successfulOutcome:
480 rc = cn_ranap_rx_successful_msg_cl(ctx, &pdu->choice.successfulOutcome,
481 message);
482 break;
483 case RANAP_RANAP_PDU_PR_unsuccessfulOutcome:
484 LOGP(DRANAP, LOGL_NOTICE, "Received unsupported RANAP "
485 "unsuccessful outcome procedure %s (CL) from RNC, ignoring\n",
486 get_value_string(ranap_procedure_code_vals,
487 pdu->choice.unsuccessfulOutcome.procedureCode));
488 break;
489 default:
490 LOGP(DRANAP, LOGL_NOTICE, "Received suspicious RANAP "
491 "presence %s (CL) from RNC, ignoring\n",
492 get_value_string(ranap_presence_vals, pdu->present));
493 break;
494 }
Harald Welteda86fe52017-11-21 08:14:37 +0100495
496 return rc;
Harald Welte3cfa4502015-12-25 15:33:41 +0100497}
498
Daniel Willmannc35b2982016-01-07 14:13:49 +0100499static void _cn_ranap_free_cl(ranap_message *message)
500{
501 switch (message->direction) {
502 case RANAP_RANAP_PDU_PR_initiatingMessage:
503 cn_ranap_free_initiating_msg_cl(message);
504 break;
505 case RANAP_RANAP_PDU_PR_successfulOutcome:
506 cn_ranap_free_successful_msg_cl(message);
507 break;
508 case RANAP_RANAP_PDU_PR_unsuccessfulOutcome:
509 LOGP(DRANAP, LOGL_NOTICE, "Not freeing unsupported RANAP "
510 "unsuccessful outcome procedure from RNC\n");
511 break;
512 default:
513 LOGP(DRANAP, LOGL_NOTICE, "Suspicious RANAP "
Harald Welteda86fe52017-11-21 08:14:37 +0100514 "presence %d (CL) from RNC, ignoring\n", message->direction);
Daniel Willmannc35b2982016-01-07 14:13:49 +0100515 break;
516 }
517}
518
519/* receive a connection-less RANAP message and call
Harald Welte3cfa4502015-12-25 15:33:41 +0100520 * cn_ranap_handle_co() with the resulting ranap_message struct */
Harald Welte8fa5d552016-01-05 15:01:53 +0100521int ranap_cn_rx_cl(ranap_handle_cb cb, void *ctx, uint8_t *data, size_t len)
Harald Welte3cfa4502015-12-25 15:33:41 +0100522{
523 RANAP_RANAP_PDU_t *pdu = NULL;
524 ranap_message message;
525 asn_dec_rval_t dec_ret;
526 int rc;
527
528 memset(&message, 0, sizeof(message));
529
Harald Welte3cfa4502015-12-25 15:33:41 +0100530 dec_ret = aper_decode(NULL,&asn_DEF_RANAP_RANAP_PDU, (void **) &pdu,
531 data, len, 0, 0);
532 if (dec_ret.code != RC_OK) {
533 LOGP(DRANAP, LOGL_ERROR, "Error in RANAP ASN.1 decode\n");
Neels Hofmeyra6a68e62016-11-25 13:21:02 +0100534 return -1;
Harald Welte3cfa4502015-12-25 15:33:41 +0100535 }
536
537 message.direction = pdu->present;
538
539 rc = _cn_ranap_rx_cl(ctx, pdu, &message);
540
541 if (rc == 0)
Harald Welte8fa5d552016-01-05 15:01:53 +0100542 (*cb)(ctx, &message);
Harald Welte49287972015-12-29 19:00:35 +0100543 else
544 LOGP(DRANAP, LOGL_ERROR, "Not calling cn_ranap_handle_cl() due to rc=%d\n", rc);
Harald Welte3cfa4502015-12-25 15:33:41 +0100545
Daniel Willmannc35b2982016-01-07 14:13:49 +0100546 /* Free the asn1 structs in message */
547 _cn_ranap_free_cl(&message);
548
Harald Welte3cfa4502015-12-25 15:33:41 +0100549 ASN_STRUCT_FREE(asn_DEF_RANAP_RANAP_PDU, pdu);
550
551 return rc;
552}