blob: 6822752e95d9d648444ec4e503bc29bb9eca273c [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>
25
26#include <unistd.h>
27#include <errno.h>
28#include <string.h>
29
30#include "asn1helpers.h"
31
Neels Hofmeyrdf63de22016-08-18 13:13:55 +020032#include <osmocom/iuh/hnbgw.h>
33#include <osmocom/iuh/hnbgw_rua.h>
Neels Hofmeyr96979af2016-01-05 15:19:44 +010034#include <osmocom/ranap/ranap_common.h>
35#include <osmocom/ranap/ranap_ies_defs.h>
Neels Hofmeyrf168a3b2016-04-25 15:09:20 +020036#include <osmocom/ranap/ranap_msg_factory.h>
Harald Welte350814a2015-09-10 22:32:15 +020037
Harald Weltee2e5d4d2015-09-10 23:49:45 +020038static int ranap_tx_reset_ack(struct hnb_context *hnb,
39 RANAP_CN_DomainIndicator_t domain)
Harald Welte350814a2015-09-10 22:32:15 +020040{
Harald Weltee2e5d4d2015-09-10 23:49:45 +020041 struct msgb *msg;
42 int rc;
Harald Welte350814a2015-09-10 22:32:15 +020043
Harald Weltec4338de2015-12-24 00:40:52 +010044 msg = ranap_new_msg_reset_ack(domain, NULL);
Harald Weltee2e5d4d2015-09-10 23:49:45 +020045 if (!msg)
46 return -1;
47
Harald Weltec4338de2015-12-24 00:40:52 +010048 rc = rua_tx_udt(hnb, msg->data, msgb_length(msg));
Harald Weltee2e5d4d2015-09-10 23:49:45 +020049
Harald Weltec4338de2015-12-24 00:40:52 +010050 msgb_free(msg);
Harald Weltee2e5d4d2015-09-10 23:49:45 +020051
52 return rc;
Harald Welte350814a2015-09-10 22:32:15 +020053}
Harald Welte350814a2015-09-10 22:32:15 +020054
55static int ranap_rx_init_reset(struct hnb_context *hnb, ANY_t *in)
56{
57 RANAP_ResetIEs_t ies;
Harald Welteea98b6f2015-12-24 15:09:06 +010058 int rc, is_ps = 0;
Harald Welte350814a2015-09-10 22:32:15 +020059
60 rc = ranap_decode_reseties(&ies, in);
61 if (rc < 0)
62 return rc;
63
Harald Welteea98b6f2015-12-24 15:09:06 +010064 if (ies.cN_DomainIndicator == RANAP_CN_DomainIndicator_ps_domain)
65 is_ps=1;
66
Harald Welte23058e12015-12-25 10:25:01 +010067 LOGP(DRANAP, LOGL_INFO, "Rx RESET.req(%s,%s)\n", is_ps ? "ps" : "cs",
68 ranap_cause_str(&ies.cause));
Harald Welte350814a2015-09-10 22:32:15 +020069
Harald Welte80401ad2015-09-11 19:48:06 +020070 /* FIXME: Actually we have to wait for some guard time? */
71 /* FIXME: Reset all resources related to this HNB/RNC */
Harald Weltee2e5d4d2015-09-10 23:49:45 +020072 ranap_tx_reset_ack(hnb, ies.cN_DomainIndicator);
73
Harald Welte350814a2015-09-10 22:32:15 +020074 return 0;
75}
76
Harald Welte23058e12015-12-25 10:25:01 +010077static int ranap_rx_error_ind(struct hnb_context *hnb, ANY_t *in)
78{
79 RANAP_ErrorIndicationIEs_t ies;
Harald Welteda86fe52017-11-21 08:14:37 +010080 int rc;
Harald Welte23058e12015-12-25 10:25:01 +010081
82 rc = ranap_decode_errorindicationies(&ies, in);
83 if (rc < 0)
84 return rc;
85
86 if (ies.presenceMask & ERRORINDICATIONIES_RANAP_CAUSE_PRESENT) {
87 LOGP(DRANAP, LOGL_ERROR, "Rx ERROR.ind(%s)\n",
88 ranap_cause_str(&ies.cause));
89 } else
90 LOGP(DRANAP, LOGL_ERROR, "Rx ERROR.ind\n");
91
92 return 0;
93}
94
Harald Welte350814a2015-09-10 22:32:15 +020095static int ranap_rx_initiating_msg(struct hnb_context *hnb, RANAP_InitiatingMessage_t *imsg)
96{
Harald Welteda86fe52017-11-21 08:14:37 +010097 int rc = 0;
Harald Welte350814a2015-09-10 22:32:15 +020098
Harald Weltec4338de2015-12-24 00:40:52 +010099 /* according tot the spec, we can primarily receive Overload,
100 * Reset, Reset ACK, Error Indication, reset Resource, Reset
101 * Resurce Acknowledge as connecitonless RANAP. There are some
102 * more messages regarding Information Transfer, Direct
103 * Information Transfer and Uplink Information Trnansfer that we
104 * can ignore. In either case, it is RANAP that we need to
105 * decode... */
Harald Welte350814a2015-09-10 22:32:15 +0200106 switch (imsg->procedureCode) {
107 case RANAP_ProcedureCode_id_Reset:
Harald Weltec4338de2015-12-24 00:40:52 +0100108 /* Reset request */
Harald Welte350814a2015-09-10 22:32:15 +0200109 rc = ranap_rx_init_reset(hnb, &imsg->value);
110 break;
Harald Weltec4338de2015-12-24 00:40:52 +0100111 case RANAP_ProcedureCode_id_OverloadControl: /* Overload ind */
Harald Welte80401ad2015-09-11 19:48:06 +0200112 break;
Harald Weltec4338de2015-12-24 00:40:52 +0100113 case RANAP_ProcedureCode_id_ErrorIndication: /* Error ind */
Harald Welte23058e12015-12-25 10:25:01 +0100114 rc = ranap_rx_error_ind(hnb, &imsg->value);
Harald Weltec4338de2015-12-24 00:40:52 +0100115 break;
116 case RANAP_ProcedureCode_id_ResetResource: /* request */
117 case RANAP_ProcedureCode_id_InformationTransfer:
118 case RANAP_ProcedureCode_id_DirectInformationTransfer:
119 case RANAP_ProcedureCode_id_UplinkInformationExchange:
120 LOGP(DRANAP, LOGL_NOTICE, "Received unsupported RANAP "
Harald Welteda86fe52017-11-21 08:14:37 +0100121 "Procedure %lu from HNB, ignoring\n", imsg->procedureCode);
Harald Weltec4338de2015-12-24 00:40:52 +0100122 break;
123 default:
124 LOGP(DRANAP, LOGL_NOTICE, "Received suspicious RANAP "
Harald Welteda86fe52017-11-21 08:14:37 +0100125 "Procedure %lu from HNB, ignoring\n", imsg->procedureCode);
Harald Welte1c2ada02015-09-11 20:10:17 +0200126 break;
Harald Welte350814a2015-09-10 22:32:15 +0200127 }
Harald Welteda86fe52017-11-21 08:14:37 +0100128
129 return rc;
Harald Welte350814a2015-09-10 22:32:15 +0200130}
131
Harald Weltec4338de2015-12-24 00:40:52 +0100132static int ranap_rx_successful_msg(struct hnb_context *hnb, RANAP_SuccessfulOutcome_t *imsg)
133{
Harald Weltec4338de2015-12-24 00:40:52 +0100134 /* according tot the spec, we can primarily receive Overload,
135 * Reset, Reset ACK, Error Indication, reset Resource, Reset
136 * Resurce Acknowledge as connecitonless RANAP. There are some
137 * more messages regarding Information Transfer, Direct
138 * Information Transfer and Uplink Information Trnansfer that we
139 * can ignore. In either case, it is RANAP that we need to
140 * decode... */
141 switch (imsg->procedureCode) {
142 case RANAP_ProcedureCode_id_Reset: /* Reset acknowledge */
143 break;
144 case RANAP_ProcedureCode_id_ResetResource: /* response */
145 case RANAP_ProcedureCode_id_InformationTransfer:
146 case RANAP_ProcedureCode_id_DirectInformationTransfer:
147 case RANAP_ProcedureCode_id_UplinkInformationExchange:
148 LOGP(DRANAP, LOGL_NOTICE, "Received unsupported RANAP "
Harald Welteda86fe52017-11-21 08:14:37 +0100149 "Procedure %lu from HNB, ignoring\n", imsg->procedureCode);
Harald Weltec4338de2015-12-24 00:40:52 +0100150 break;
151 default:
152 LOGP(DRANAP, LOGL_NOTICE, "Received suspicious RANAP "
Harald Welteda86fe52017-11-21 08:14:37 +0100153 "Procedure %lu from HNB, ignoring\n", imsg->procedureCode);
Harald Weltec4338de2015-12-24 00:40:52 +0100154 break;
155 }
Harald Welteda86fe52017-11-21 08:14:37 +0100156
157 return 0;
Harald Weltec4338de2015-12-24 00:40:52 +0100158}
159
160
161
Harald Welte350814a2015-09-10 22:32:15 +0200162static int _hnbgw_ranap_rx(struct hnb_context *hnb, RANAP_RANAP_PDU_t *pdu)
163{
Harald Welteda86fe52017-11-21 08:14:37 +0100164 int rc = 0;
Harald Welte350814a2015-09-10 22:32:15 +0200165
166 switch (pdu->present) {
167 case RANAP_RANAP_PDU_PR_initiatingMessage:
168 rc = ranap_rx_initiating_msg(hnb, &pdu->choice.initiatingMessage);
169 break;
170 case RANAP_RANAP_PDU_PR_successfulOutcome:
Harald Weltec4338de2015-12-24 00:40:52 +0100171 rc = ranap_rx_successful_msg(hnb, &pdu->choice.successfulOutcome);
Harald Welte350814a2015-09-10 22:32:15 +0200172 break;
173 case RANAP_RANAP_PDU_PR_unsuccessfulOutcome:
Harald Weltec4338de2015-12-24 00:40:52 +0100174 LOGP(DRANAP, LOGL_NOTICE, "Received unsupported RANAP "
Harald Welteda86fe52017-11-21 08:14:37 +0100175 "unsuccessful outcome procedure %lu from HNB, ignoring\n",
Harald Weltec4338de2015-12-24 00:40:52 +0100176 pdu->choice.unsuccessfulOutcome.procedureCode);
Harald Welte350814a2015-09-10 22:32:15 +0200177 break;
178 default:
Harald Weltec4338de2015-12-24 00:40:52 +0100179 LOGP(DRANAP, LOGL_NOTICE, "Received suspicious RANAP "
180 "presence %u from HNB, ignoring\n", pdu->present);
Harald Welte350814a2015-09-10 22:32:15 +0200181 break;
182 }
Harald Welteda86fe52017-11-21 08:14:37 +0100183
184 return rc;
Harald Welte350814a2015-09-10 22:32:15 +0200185}
186
187
188int hnbgw_ranap_rx(struct msgb *msg, uint8_t *data, size_t len)
189{
190 RANAP_RANAP_PDU_t _pdu, *pdu = &_pdu;
191 asn_dec_rval_t dec_ret;
192 int rc;
193
194 memset(pdu, 0, sizeof(*pdu));
195 dec_ret = aper_decode(NULL,&asn_DEF_RANAP_RANAP_PDU, (void **) &pdu,
196 data, len, 0, 0);
197 if (dec_ret.code != RC_OK) {
Harald Weltef42317b2015-12-23 15:36:31 +0100198 LOGP(DRANAP, LOGL_ERROR, "Error in RANAP ASN.1 decode\n");
Neels Hofmeyra6a68e62016-11-25 13:21:02 +0100199 return -1;
Harald Welte350814a2015-09-10 22:32:15 +0200200 }
201
202 rc = _hnbgw_ranap_rx(msg->dst, pdu);
203
204 return rc;
205}
206
207int hnbgw_ranap_init(void)
208{
Harald Welteda86fe52017-11-21 08:14:37 +0100209 return 0;
Harald Welte350814a2015-09-10 22:32:15 +0200210}