blob: c890b6a68ec758056872ec03868d48cf419c1cfb [file] [log] [blame]
Harald Welte77847ad2015-10-06 22:07:04 +02001/* hnb-gw specific code for RUA (Ranap User Adaption) */
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
Harald Welte318e4d52015-09-10 18:47:08 +020022#include <osmocom/core/msgb.h>
23#include <osmocom/core/utils.h>
Harald Welteffa7c0a2015-12-23 00:03:41 +010024#include <osmocom/netif/stream.h>
Harald Welte318e4d52015-09-10 18:47:08 +020025
26#include <unistd.h>
27#include <errno.h>
28#include <string.h>
29
30#include "asn1helpers.h"
31
32#include "hnbgw.h"
Harald Welte350814a2015-09-10 22:32:15 +020033#include "hnbgw_ranap.h"
Harald Welte318e4d52015-09-10 18:47:08 +020034#include "rua_common.h"
35#include "rua_ies_defs.h"
36
37static int hnbgw_rua_tx(struct hnb_context *ctx, struct msgb *msg)
38{
39 if (!msg)
40 return -EINVAL;
41
Harald Welteffa7c0a2015-12-23 00:03:41 +010042 msgb_sctp_ppid(msg) = IUH_PPI_RUA;
Harald Welte318e4d52015-09-10 18:47:08 +020043 return osmo_wqueue_enqueue(&ctx->wqueue, msg);
44}
45
Harald Weltee2e5d4d2015-09-10 23:49:45 +020046int rua_tx_udt(struct msgb *inmsg)
Harald Welte64b4ebe2015-09-10 19:29:59 +020047{
Harald Weltee2e5d4d2015-09-10 23:49:45 +020048 RUA_ConnectionlessTransfer_t out;
49 RUA_ConnectionlessTransferIEs_t ies;
50 struct msgb *msg;
51 int rc;
Harald Welte64b4ebe2015-09-10 19:29:59 +020052
Harald Weltee2e5d4d2015-09-10 23:49:45 +020053 memset(&ies, 0, sizeof(ies));
54 ies.ranaP_Message.buf = inmsg->data;
55 ies.ranaP_Message.size = msgb_length(inmsg);
56
57 /* FIXME: msgb_free(msg)? ownership not yet clear */
58
59 memset(&out, 0, sizeof(out));
60 rc = rua_encode_connectionlesstransferies(&out, &ies);
61 if (rc < 0)
62 return rc;
63
64 msg = rua_generate_initiating_message(RUA_ProcedureCode_id_ConnectionlessTransfer,
65 RUA_Criticality_reject,
66 &asn_DEF_RUA_ConnectionlessTransfer,
67 &out);
68 msg->dst = inmsg->dst;
69
70 DEBUGP(DMAIN, "transmitting RUA payload of %u bytes\n", msgb_length(msg));
71
72 return hnbgw_rua_tx(msg->dst, msg);
Harald Welte64b4ebe2015-09-10 19:29:59 +020073}
74
Harald Welte0f0ea812015-09-11 18:58:28 +020075int rua_tx_dt(struct msgb *inmsg)
76{
77 RUA_DirectTransfer_t out;
78 RUA_DirectTransferIEs_t ies;
79 struct msgb *msg;
80 int rc;
81
82 memset(&ies, 0, sizeof(ies));
83 ies.ranaP_Message.buf = inmsg->data;
84 ies.ranaP_Message.size = msgb_length(inmsg);
85
86 /* FIXME: msgb_free(msg)? ownership not yet clear */
87
88 memset(&out, 0, sizeof(out));
89 rc = rua_encode_directtransferies(&out, &ies);
90 if (rc < 0)
91 return rc;
92
93 msg = rua_generate_initiating_message(RUA_ProcedureCode_id_DirectTransfer,
94 RUA_Criticality_reject,
95 &asn_DEF_RUA_DirectTransfer,
96 &out);
97 msg->dst = inmsg->dst;
98
99 DEBUGP(DMAIN, "transmitting RUA payload of %u bytes\n", msgb_length(msg));
100
101 return hnbgw_rua_tx(msg->dst, msg);
102}
103
104
Harald Welte350814a2015-09-10 22:32:15 +0200105static int rua_rx_init_connect(struct msgb *msg, ANY_t *in)
Harald Welte64b4ebe2015-09-10 19:29:59 +0200106{
107 RUA_ConnectIEs_t ies;
108 uint32_t context_id;
109 int rc;
110
111 rc = rua_decode_connecties(&ies, in);
112 if (rc < 0)
113 return rc;
114
115 context_id = asn1bitstr_to_u32(&ies.context_ID);
116
117 DEBUGP(DMAIN, "Connect.req(ctx=0x%x, %s)\n", context_id,
118 ies.establishment_Cause == RUA_Establishment_Cause_emergency_call
119 ? "emergency" : "normal");
Harald Welte0f0ea812015-09-11 18:58:28 +0200120 /* FIXME: route to CS (MSC) or PS (SGSN) domain */
121 rc = hnbgw_ranap_rx(msg, ies.ranaP_Message.buf, ies.ranaP_Message.size);
122
123 return rc;
Harald Welte64b4ebe2015-09-10 19:29:59 +0200124}
125
Harald Welte350814a2015-09-10 22:32:15 +0200126static int rua_rx_init_disconnect(struct msgb *msg, ANY_t *in)
Harald Welte64b4ebe2015-09-10 19:29:59 +0200127{
128 RUA_DisconnectIEs_t ies;
129 uint32_t context_id;
130 int rc;
131
132 rc = rua_decode_disconnecties(&ies, in);
133 if (rc < 0)
134 return rc;
135
136 context_id = asn1bitstr_to_u32(&ies.context_ID);
137
138 DEBUGP(DMAIN, "Disconnect.req(ctx=0x%x,cause=%s)\n", context_id,
139 rua_cause_str(&ies.cause));
Harald Welte0f0ea812015-09-11 18:58:28 +0200140 if (ies.presenceMask & DISCONNECTIES_RUA_RANAP_MESSAGE_PRESENT)
141 rc = hnbgw_ranap_rx(msg, ies.ranaP_Message.buf,
142 ies.ranaP_Message.size);
143
Harald Welte350814a2015-09-10 22:32:15 +0200144 /* FIXME */
Harald Welte0f0ea812015-09-11 18:58:28 +0200145 return rc;
Harald Welte64b4ebe2015-09-10 19:29:59 +0200146}
147
Harald Welte350814a2015-09-10 22:32:15 +0200148static int rua_rx_init_dt(struct msgb *msg, ANY_t *in)
Harald Welte64b4ebe2015-09-10 19:29:59 +0200149{
150 RUA_DirectTransferIEs_t ies;
151 uint32_t context_id;
152 int rc;
153
154 rc = rua_decode_directtransferies(&ies, in);
155 if (rc < 0)
156 return rc;
157
158 context_id = asn1bitstr_to_u32(&ies.context_ID);
159
160 DEBUGP(DMAIN, "Data.req(ctx=0x%x)\n", context_id);
Harald Welte350814a2015-09-10 22:32:15 +0200161 /* FIXME */
Harald Welte0f0ea812015-09-11 18:58:28 +0200162 rc = hnbgw_ranap_rx(msg, ies.ranaP_Message.buf, ies.ranaP_Message.size);
163
164 return rc;
Harald Welte64b4ebe2015-09-10 19:29:59 +0200165
166}
167
Harald Welte350814a2015-09-10 22:32:15 +0200168static int rua_rx_init_udt(struct msgb *msg, ANY_t *in)
Harald Welte64b4ebe2015-09-10 19:29:59 +0200169{
170 RUA_ConnectionlessTransferIEs_t ies;
171 int rc;
172
173 rc = rua_decode_connectionlesstransferies(&ies, in);
174 if (rc < 0)
175 return rc;
176
177 DEBUGP(DMAIN, "UData.req()\n");
178
Harald Welte350814a2015-09-10 22:32:15 +0200179 /* FIXME: pass on to RANAP */
180 rc = hnbgw_ranap_rx(msg, ies.ranaP_Message.buf, ies.ranaP_Message.size);
181 /* FIXME: what to do with the asn1c-allocated memory */
182
183 return rc;
Harald Welte64b4ebe2015-09-10 19:29:59 +0200184}
185
Harald Welte350814a2015-09-10 22:32:15 +0200186
187static int rua_rx_init_err_ind(struct msgb *msg, ANY_t *in)
Harald Welte64b4ebe2015-09-10 19:29:59 +0200188{
189 RUA_ErrorIndicationIEs_t ies;
190 int rc;
191
192 rc = rua_decode_errorindicationies(&ies, in);
193 if (rc < 0)
194 return rc;
195
196}
Harald Welte318e4d52015-09-10 18:47:08 +0200197
Harald Welte350814a2015-09-10 22:32:15 +0200198static int rua_rx_initiating_msg(struct msgb *msg, RUA_InitiatingMessage_t *imsg)
Harald Welte318e4d52015-09-10 18:47:08 +0200199{
200 int rc;
201
202 switch (imsg->procedureCode) {
203 case RUA_ProcedureCode_id_Connect:
Harald Welte350814a2015-09-10 22:32:15 +0200204 rc = rua_rx_init_connect(msg, &imsg->value);
Harald Welte318e4d52015-09-10 18:47:08 +0200205 break;
206 case RUA_ProcedureCode_id_DirectTransfer:
Harald Welte350814a2015-09-10 22:32:15 +0200207 rc = rua_rx_init_dt(msg, &imsg->value);
Harald Welte318e4d52015-09-10 18:47:08 +0200208 break;
209 case RUA_ProcedureCode_id_Disconnect:
Harald Welte350814a2015-09-10 22:32:15 +0200210 rc = rua_rx_init_disconnect(msg, &imsg->value);
Harald Welte318e4d52015-09-10 18:47:08 +0200211 break;
212 case RUA_ProcedureCode_id_ConnectionlessTransfer:
Harald Welte350814a2015-09-10 22:32:15 +0200213 rc = rua_rx_init_udt(msg, &imsg->value);
Harald Welte318e4d52015-09-10 18:47:08 +0200214 break;
215 case RUA_ProcedureCode_id_ErrorIndication:
Harald Welte350814a2015-09-10 22:32:15 +0200216 rc = rua_rx_init_err_ind(msg, &imsg->value);
Harald Welte64b4ebe2015-09-10 19:29:59 +0200217 break;
Harald Welte318e4d52015-09-10 18:47:08 +0200218 case RUA_ProcedureCode_id_privateMessage:
219 break;
220 default:
Harald Welte64b4ebe2015-09-10 19:29:59 +0200221 return -1;
Harald Welte318e4d52015-09-10 18:47:08 +0200222 }
223}
224
Harald Welte350814a2015-09-10 22:32:15 +0200225static int rua_rx_successful_outcome_msg(struct msgb *msg, RUA_SuccessfulOutcome_t *in)
Harald Welte318e4d52015-09-10 18:47:08 +0200226{
227
228}
229
Harald Welte350814a2015-09-10 22:32:15 +0200230static int rua_rx_unsuccessful_outcome_msg(struct msgb *msg, RUA_UnsuccessfulOutcome_t *in)
Harald Welte318e4d52015-09-10 18:47:08 +0200231{
232
233}
234
235
Harald Welte350814a2015-09-10 22:32:15 +0200236static int _hnbgw_rua_rx(struct msgb *msg, RUA_RUA_PDU_t *pdu)
Harald Welte318e4d52015-09-10 18:47:08 +0200237{
238 int rc;
239
240 /* it's a bit odd that we can't dispatch on procedure code, but
241 * that's not possible */
242 switch (pdu->present) {
243 case RUA_RUA_PDU_PR_initiatingMessage:
Harald Welte350814a2015-09-10 22:32:15 +0200244 rc = rua_rx_initiating_msg(msg, &pdu->choice.initiatingMessage);
Harald Welte318e4d52015-09-10 18:47:08 +0200245 break;
246 case RUA_RUA_PDU_PR_successfulOutcome:
Harald Welte350814a2015-09-10 22:32:15 +0200247 rc = rua_rx_successful_outcome_msg(msg, &pdu->choice.successfulOutcome);
Harald Welte318e4d52015-09-10 18:47:08 +0200248 break;
249 case RUA_RUA_PDU_PR_unsuccessfulOutcome:
Harald Welte350814a2015-09-10 22:32:15 +0200250 rc = rua_rx_unsuccessful_outcome_msg(msg, &pdu->choice.unsuccessfulOutcome);
Harald Welte318e4d52015-09-10 18:47:08 +0200251 break;
252 default:
253 return -1;
254 }
255}
256
257int hnbgw_rua_rx(struct hnb_context *hnb, struct msgb *msg)
258{
259 RUA_RUA_PDU_t _pdu, *pdu = &_pdu;
260 asn_dec_rval_t dec_ret;
261 int rc;
262
263 /* decode and handle to _hnbgw_hnbap_rx() */
264
265 memset(pdu, 0, sizeof(*pdu));
266 dec_ret = aper_decode(NULL, &asn_DEF_RUA_RUA_PDU, (void **) &pdu,
267 msg->data, msgb_length(msg), 0, 0);
268 if (dec_ret.code != RC_OK) {
Harald Weltef42317b2015-12-23 15:36:31 +0100269 LOGP(DRUA, LOGL_ERROR, "Error in ASN.1 decode\n");
Harald Welte318e4d52015-09-10 18:47:08 +0200270 return rc;
271 }
272
Harald Welte350814a2015-09-10 22:32:15 +0200273 rc = _hnbgw_rua_rx(msg, pdu);
Harald Welte318e4d52015-09-10 18:47:08 +0200274
275 return rc;
276}
277
278
279int hnbgw_rua_init(void)
280{
281
282}