blob: 4cc10ac23798ee9d5298f7da2f68a89b73f5e580 [file] [log] [blame]
Harald Welte318e4d52015-09-10 18:47:08 +02001#include <osmocom/core/msgb.h>
2#include <osmocom/core/utils.h>
3
4#include <unistd.h>
5#include <errno.h>
6#include <string.h>
7
8#include "asn1helpers.h"
9
10#include "hnbgw.h"
Harald Welte350814a2015-09-10 22:32:15 +020011#include "hnbgw_ranap.h"
Harald Welte318e4d52015-09-10 18:47:08 +020012#include "rua_common.h"
13#include "rua_ies_defs.h"
14
15static int hnbgw_rua_tx(struct hnb_context *ctx, struct msgb *msg)
16{
17 if (!msg)
18 return -EINVAL;
19
20 msgb_ppid(msg) = IUH_PPI_RUA;
21 return osmo_wqueue_enqueue(&ctx->wqueue, msg);
22}
23
Harald Weltee2e5d4d2015-09-10 23:49:45 +020024int rua_tx_udt(struct msgb *inmsg)
Harald Welte64b4ebe2015-09-10 19:29:59 +020025{
Harald Weltee2e5d4d2015-09-10 23:49:45 +020026 RUA_ConnectionlessTransfer_t out;
27 RUA_ConnectionlessTransferIEs_t ies;
28 struct msgb *msg;
29 int rc;
Harald Welte64b4ebe2015-09-10 19:29:59 +020030
Harald Weltee2e5d4d2015-09-10 23:49:45 +020031 memset(&ies, 0, sizeof(ies));
32 ies.ranaP_Message.buf = inmsg->data;
33 ies.ranaP_Message.size = msgb_length(inmsg);
34
35 /* FIXME: msgb_free(msg)? ownership not yet clear */
36
37 memset(&out, 0, sizeof(out));
38 rc = rua_encode_connectionlesstransferies(&out, &ies);
39 if (rc < 0)
40 return rc;
41
42 msg = rua_generate_initiating_message(RUA_ProcedureCode_id_ConnectionlessTransfer,
43 RUA_Criticality_reject,
44 &asn_DEF_RUA_ConnectionlessTransfer,
45 &out);
46 msg->dst = inmsg->dst;
47
48 DEBUGP(DMAIN, "transmitting RUA payload of %u bytes\n", msgb_length(msg));
49
50 return hnbgw_rua_tx(msg->dst, msg);
Harald Welte64b4ebe2015-09-10 19:29:59 +020051}
52
Harald Welte0f0ea812015-09-11 18:58:28 +020053int rua_tx_dt(struct msgb *inmsg)
54{
55 RUA_DirectTransfer_t out;
56 RUA_DirectTransferIEs_t ies;
57 struct msgb *msg;
58 int rc;
59
60 memset(&ies, 0, sizeof(ies));
61 ies.ranaP_Message.buf = inmsg->data;
62 ies.ranaP_Message.size = msgb_length(inmsg);
63
64 /* FIXME: msgb_free(msg)? ownership not yet clear */
65
66 memset(&out, 0, sizeof(out));
67 rc = rua_encode_directtransferies(&out, &ies);
68 if (rc < 0)
69 return rc;
70
71 msg = rua_generate_initiating_message(RUA_ProcedureCode_id_DirectTransfer,
72 RUA_Criticality_reject,
73 &asn_DEF_RUA_DirectTransfer,
74 &out);
75 msg->dst = inmsg->dst;
76
77 DEBUGP(DMAIN, "transmitting RUA payload of %u bytes\n", msgb_length(msg));
78
79 return hnbgw_rua_tx(msg->dst, msg);
80}
81
82
Harald Welte350814a2015-09-10 22:32:15 +020083static int rua_rx_init_connect(struct msgb *msg, ANY_t *in)
Harald Welte64b4ebe2015-09-10 19:29:59 +020084{
85 RUA_ConnectIEs_t ies;
86 uint32_t context_id;
87 int rc;
88
89 rc = rua_decode_connecties(&ies, in);
90 if (rc < 0)
91 return rc;
92
93 context_id = asn1bitstr_to_u32(&ies.context_ID);
94
95 DEBUGP(DMAIN, "Connect.req(ctx=0x%x, %s)\n", context_id,
96 ies.establishment_Cause == RUA_Establishment_Cause_emergency_call
97 ? "emergency" : "normal");
Harald Welte0f0ea812015-09-11 18:58:28 +020098 /* FIXME: route to CS (MSC) or PS (SGSN) domain */
99 rc = hnbgw_ranap_rx(msg, ies.ranaP_Message.buf, ies.ranaP_Message.size);
100
101 return rc;
Harald Welte64b4ebe2015-09-10 19:29:59 +0200102}
103
Harald Welte350814a2015-09-10 22:32:15 +0200104static int rua_rx_init_disconnect(struct msgb *msg, ANY_t *in)
Harald Welte64b4ebe2015-09-10 19:29:59 +0200105{
106 RUA_DisconnectIEs_t ies;
107 uint32_t context_id;
108 int rc;
109
110 rc = rua_decode_disconnecties(&ies, in);
111 if (rc < 0)
112 return rc;
113
114 context_id = asn1bitstr_to_u32(&ies.context_ID);
115
116 DEBUGP(DMAIN, "Disconnect.req(ctx=0x%x,cause=%s)\n", context_id,
117 rua_cause_str(&ies.cause));
Harald Welte0f0ea812015-09-11 18:58:28 +0200118 if (ies.presenceMask & DISCONNECTIES_RUA_RANAP_MESSAGE_PRESENT)
119 rc = hnbgw_ranap_rx(msg, ies.ranaP_Message.buf,
120 ies.ranaP_Message.size);
121
Harald Welte350814a2015-09-10 22:32:15 +0200122 /* FIXME */
Harald Welte0f0ea812015-09-11 18:58:28 +0200123 return rc;
Harald Welte64b4ebe2015-09-10 19:29:59 +0200124}
125
Harald Welte350814a2015-09-10 22:32:15 +0200126static int rua_rx_init_dt(struct msgb *msg, ANY_t *in)
Harald Welte64b4ebe2015-09-10 19:29:59 +0200127{
128 RUA_DirectTransferIEs_t ies;
129 uint32_t context_id;
130 int rc;
131
132 rc = rua_decode_directtransferies(&ies, in);
133 if (rc < 0)
134 return rc;
135
136 context_id = asn1bitstr_to_u32(&ies.context_ID);
137
138 DEBUGP(DMAIN, "Data.req(ctx=0x%x)\n", context_id);
Harald Welte350814a2015-09-10 22:32:15 +0200139 /* FIXME */
Harald Welte0f0ea812015-09-11 18:58:28 +0200140 rc = hnbgw_ranap_rx(msg, ies.ranaP_Message.buf, ies.ranaP_Message.size);
141
142 return rc;
Harald Welte64b4ebe2015-09-10 19:29:59 +0200143
144}
145
Harald Welte350814a2015-09-10 22:32:15 +0200146static int rua_rx_init_udt(struct msgb *msg, ANY_t *in)
Harald Welte64b4ebe2015-09-10 19:29:59 +0200147{
148 RUA_ConnectionlessTransferIEs_t ies;
149 int rc;
150
151 rc = rua_decode_connectionlesstransferies(&ies, in);
152 if (rc < 0)
153 return rc;
154
155 DEBUGP(DMAIN, "UData.req()\n");
156
Harald Welte350814a2015-09-10 22:32:15 +0200157 /* FIXME: pass on to RANAP */
158 rc = hnbgw_ranap_rx(msg, ies.ranaP_Message.buf, ies.ranaP_Message.size);
159 /* FIXME: what to do with the asn1c-allocated memory */
160
161 return rc;
Harald Welte64b4ebe2015-09-10 19:29:59 +0200162}
163
Harald Welte350814a2015-09-10 22:32:15 +0200164
165static int rua_rx_init_err_ind(struct msgb *msg, ANY_t *in)
Harald Welte64b4ebe2015-09-10 19:29:59 +0200166{
167 RUA_ErrorIndicationIEs_t ies;
168 int rc;
169
170 rc = rua_decode_errorindicationies(&ies, in);
171 if (rc < 0)
172 return rc;
173
174}
Harald Welte318e4d52015-09-10 18:47:08 +0200175
Harald Welte350814a2015-09-10 22:32:15 +0200176static int rua_rx_initiating_msg(struct msgb *msg, RUA_InitiatingMessage_t *imsg)
Harald Welte318e4d52015-09-10 18:47:08 +0200177{
178 int rc;
179
180 switch (imsg->procedureCode) {
181 case RUA_ProcedureCode_id_Connect:
Harald Welte350814a2015-09-10 22:32:15 +0200182 rc = rua_rx_init_connect(msg, &imsg->value);
Harald Welte318e4d52015-09-10 18:47:08 +0200183 break;
184 case RUA_ProcedureCode_id_DirectTransfer:
Harald Welte350814a2015-09-10 22:32:15 +0200185 rc = rua_rx_init_dt(msg, &imsg->value);
Harald Welte318e4d52015-09-10 18:47:08 +0200186 break;
187 case RUA_ProcedureCode_id_Disconnect:
Harald Welte350814a2015-09-10 22:32:15 +0200188 rc = rua_rx_init_disconnect(msg, &imsg->value);
Harald Welte318e4d52015-09-10 18:47:08 +0200189 break;
190 case RUA_ProcedureCode_id_ConnectionlessTransfer:
Harald Welte350814a2015-09-10 22:32:15 +0200191 rc = rua_rx_init_udt(msg, &imsg->value);
Harald Welte318e4d52015-09-10 18:47:08 +0200192 break;
193 case RUA_ProcedureCode_id_ErrorIndication:
Harald Welte350814a2015-09-10 22:32:15 +0200194 rc = rua_rx_init_err_ind(msg, &imsg->value);
Harald Welte64b4ebe2015-09-10 19:29:59 +0200195 break;
Harald Welte318e4d52015-09-10 18:47:08 +0200196 case RUA_ProcedureCode_id_privateMessage:
197 break;
198 default:
Harald Welte64b4ebe2015-09-10 19:29:59 +0200199 return -1;
Harald Welte318e4d52015-09-10 18:47:08 +0200200 }
201}
202
Harald Welte350814a2015-09-10 22:32:15 +0200203static int rua_rx_successful_outcome_msg(struct msgb *msg, RUA_SuccessfulOutcome_t *in)
Harald Welte318e4d52015-09-10 18:47:08 +0200204{
205
206}
207
Harald Welte350814a2015-09-10 22:32:15 +0200208static int rua_rx_unsuccessful_outcome_msg(struct msgb *msg, RUA_UnsuccessfulOutcome_t *in)
Harald Welte318e4d52015-09-10 18:47:08 +0200209{
210
211}
212
213
Harald Welte350814a2015-09-10 22:32:15 +0200214static int _hnbgw_rua_rx(struct msgb *msg, RUA_RUA_PDU_t *pdu)
Harald Welte318e4d52015-09-10 18:47:08 +0200215{
216 int rc;
217
218 /* it's a bit odd that we can't dispatch on procedure code, but
219 * that's not possible */
220 switch (pdu->present) {
221 case RUA_RUA_PDU_PR_initiatingMessage:
Harald Welte350814a2015-09-10 22:32:15 +0200222 rc = rua_rx_initiating_msg(msg, &pdu->choice.initiatingMessage);
Harald Welte318e4d52015-09-10 18:47:08 +0200223 break;
224 case RUA_RUA_PDU_PR_successfulOutcome:
Harald Welte350814a2015-09-10 22:32:15 +0200225 rc = rua_rx_successful_outcome_msg(msg, &pdu->choice.successfulOutcome);
Harald Welte318e4d52015-09-10 18:47:08 +0200226 break;
227 case RUA_RUA_PDU_PR_unsuccessfulOutcome:
Harald Welte350814a2015-09-10 22:32:15 +0200228 rc = rua_rx_unsuccessful_outcome_msg(msg, &pdu->choice.unsuccessfulOutcome);
Harald Welte318e4d52015-09-10 18:47:08 +0200229 break;
230 default:
231 return -1;
232 }
233}
234
235int hnbgw_rua_rx(struct hnb_context *hnb, struct msgb *msg)
236{
237 RUA_RUA_PDU_t _pdu, *pdu = &_pdu;
238 asn_dec_rval_t dec_ret;
239 int rc;
240
241 /* decode and handle to _hnbgw_hnbap_rx() */
242
243 memset(pdu, 0, sizeof(*pdu));
244 dec_ret = aper_decode(NULL, &asn_DEF_RUA_RUA_PDU, (void **) &pdu,
245 msg->data, msgb_length(msg), 0, 0);
246 if (dec_ret.code != RC_OK) {
247 LOGP(DMAIN, LOGL_ERROR, "Error in ASN.1 decode\n");
248 return rc;
249 }
250
Harald Welte350814a2015-09-10 22:32:15 +0200251 rc = _hnbgw_rua_rx(msg, pdu);
Harald Welte318e4d52015-09-10 18:47:08 +0200252
253 return rc;
254}
255
256
257int hnbgw_rua_init(void)
258{
259
260}