blob: 3af564bae1dc8cdc2bddcd58195ec4cf4be5ff20 [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 Welte64b4ebe2015-09-10 19:29:59 +020024static const struct value_string rua_cause_radio_vals[] = {
25 { RUA_CauseRadioNetwork_normal, "normal" },
26 { RUA_CauseRadioNetwork_connect_failed, "connect failed" },
27 { RUA_CauseRadioNetwork_network_release, "network release" },
28 { RUA_CauseRadioNetwork_unspecified, "unspecified" },
29 { 0, NULL }
30};
31
32static const struct value_string rua_cause_transp_vals[] = {
33 { RUA_CauseTransport_transport_resource_unavailable, "resource unavailable" },
34 { RUA_CauseTransport_unspecified, "unspecified" },
35 { 0, NULL }
36};
37
38static const struct value_string rua_cause_prot_vals[] = {
39 { RUA_CauseProtocol_transfer_syntax_error, "syntax error" },
40 { RUA_CauseProtocol_abstract_syntax_error_reject,
41 "abstract syntax error; reject" },
42 { RUA_CauseProtocol_abstract_syntax_error_ignore_and_notify,
43 "abstract syntax error; ignore and notify" },
44 { RUA_CauseProtocol_message_not_compatible_with_receiver_state,
45 "message not compatible with receiver state" },
46 { RUA_CauseProtocol_semantic_error, "semantic error" },
47 { RUA_CauseProtocol_unspecified, "unspecified" },
48 { RUA_CauseProtocol_abstract_syntax_error_falsely_constructed_message,
49 "falsely constructed message" },
50 { 0, NULL }
51};
52
53static const struct value_string rua_cause_misc_vals[] = {
54 { RUA_CauseMisc_processing_overload, "processing overload" },
55 { RUA_CauseMisc_hardware_failure, "hardware failure" },
56 { RUA_CauseMisc_o_and_m_intervention, "OAM intervention" },
57 { RUA_CauseMisc_unspecified, "unspecified" },
58 { 0, NULL }
59};
60
61static char *rua_cause_str(RUA_Cause_t *cause)
62{
63 static char buf[32];
64
65 switch (cause->present) {
66 case RUA_Cause_PR_radioNetwork:
67 snprintf(buf, sizeof(buf), "radio(%s)",
68 get_value_string(rua_cause_radio_vals,
69 cause->choice.radioNetwork));
70 break;
71 case RUA_Cause_PR_transport:
72 snprintf(buf, sizeof(buf), "transport(%s)",
73 get_value_string(rua_cause_transp_vals,
74 cause->choice.transport));
75 break;
76 case RUA_Cause_PR_protocol:
77 snprintf(buf, sizeof(buf), "protocol(%s)",
78 get_value_string(rua_cause_prot_vals,
79 cause->choice.protocol));
80 break;
81 case RUA_Cause_PR_misc:
82 snprintf(buf, sizeof(buf), "misc(%s)",
83 get_value_string(rua_cause_misc_vals,
84 cause->choice.misc));
85 break;
86 }
87 return buf;
88}
89
90
Harald Welte350814a2015-09-10 22:32:15 +020091static int rua_rx_init_connect(struct msgb *msg, ANY_t *in)
Harald Welte64b4ebe2015-09-10 19:29:59 +020092{
93 RUA_ConnectIEs_t ies;
94 uint32_t context_id;
95 int rc;
96
97 rc = rua_decode_connecties(&ies, in);
98 if (rc < 0)
99 return rc;
100
101 context_id = asn1bitstr_to_u32(&ies.context_ID);
102
103 DEBUGP(DMAIN, "Connect.req(ctx=0x%x, %s)\n", context_id,
104 ies.establishment_Cause == RUA_Establishment_Cause_emergency_call
105 ? "emergency" : "normal");
Harald Welte350814a2015-09-10 22:32:15 +0200106 /* FIXME */
Harald Welte64b4ebe2015-09-10 19:29:59 +0200107}
108
Harald Welte350814a2015-09-10 22:32:15 +0200109static int rua_rx_init_disconnect(struct msgb *msg, ANY_t *in)
Harald Welte64b4ebe2015-09-10 19:29:59 +0200110{
111 RUA_DisconnectIEs_t ies;
112 uint32_t context_id;
113 int rc;
114
115 rc = rua_decode_disconnecties(&ies, in);
116 if (rc < 0)
117 return rc;
118
119 context_id = asn1bitstr_to_u32(&ies.context_ID);
120
121 DEBUGP(DMAIN, "Disconnect.req(ctx=0x%x,cause=%s)\n", context_id,
122 rua_cause_str(&ies.cause));
Harald Welte350814a2015-09-10 22:32:15 +0200123 /* FIXME */
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 Welte64b4ebe2015-09-10 19:29:59 +0200140
141}
142
Harald Welte350814a2015-09-10 22:32:15 +0200143static int rua_rx_init_udt(struct msgb *msg, ANY_t *in)
Harald Welte64b4ebe2015-09-10 19:29:59 +0200144{
145 RUA_ConnectionlessTransferIEs_t ies;
146 int rc;
147
148 rc = rua_decode_connectionlesstransferies(&ies, in);
149 if (rc < 0)
150 return rc;
151
152 DEBUGP(DMAIN, "UData.req()\n");
153
Harald Welte350814a2015-09-10 22:32:15 +0200154 /* FIXME: pass on to RANAP */
155 rc = hnbgw_ranap_rx(msg, ies.ranaP_Message.buf, ies.ranaP_Message.size);
156 /* FIXME: what to do with the asn1c-allocated memory */
157
158 return rc;
Harald Welte64b4ebe2015-09-10 19:29:59 +0200159}
160
Harald Welte350814a2015-09-10 22:32:15 +0200161
162static int rua_rx_init_err_ind(struct msgb *msg, ANY_t *in)
Harald Welte64b4ebe2015-09-10 19:29:59 +0200163{
164 RUA_ErrorIndicationIEs_t ies;
165 int rc;
166
167 rc = rua_decode_errorindicationies(&ies, in);
168 if (rc < 0)
169 return rc;
170
171}
Harald Welte318e4d52015-09-10 18:47:08 +0200172
Harald Welte350814a2015-09-10 22:32:15 +0200173static int rua_rx_initiating_msg(struct msgb *msg, RUA_InitiatingMessage_t *imsg)
Harald Welte318e4d52015-09-10 18:47:08 +0200174{
175 int rc;
176
177 switch (imsg->procedureCode) {
178 case RUA_ProcedureCode_id_Connect:
Harald Welte350814a2015-09-10 22:32:15 +0200179 rc = rua_rx_init_connect(msg, &imsg->value);
Harald Welte318e4d52015-09-10 18:47:08 +0200180 break;
181 case RUA_ProcedureCode_id_DirectTransfer:
Harald Welte350814a2015-09-10 22:32:15 +0200182 rc = rua_rx_init_dt(msg, &imsg->value);
Harald Welte318e4d52015-09-10 18:47:08 +0200183 break;
184 case RUA_ProcedureCode_id_Disconnect:
Harald Welte350814a2015-09-10 22:32:15 +0200185 rc = rua_rx_init_disconnect(msg, &imsg->value);
Harald Welte318e4d52015-09-10 18:47:08 +0200186 break;
187 case RUA_ProcedureCode_id_ConnectionlessTransfer:
Harald Welte350814a2015-09-10 22:32:15 +0200188 rc = rua_rx_init_udt(msg, &imsg->value);
Harald Welte318e4d52015-09-10 18:47:08 +0200189 break;
190 case RUA_ProcedureCode_id_ErrorIndication:
Harald Welte350814a2015-09-10 22:32:15 +0200191 rc = rua_rx_init_err_ind(msg, &imsg->value);
Harald Welte64b4ebe2015-09-10 19:29:59 +0200192 break;
Harald Welte318e4d52015-09-10 18:47:08 +0200193 case RUA_ProcedureCode_id_privateMessage:
194 break;
195 default:
Harald Welte64b4ebe2015-09-10 19:29:59 +0200196 return -1;
Harald Welte318e4d52015-09-10 18:47:08 +0200197 }
198}
199
Harald Welte350814a2015-09-10 22:32:15 +0200200static int rua_rx_successful_outcome_msg(struct msgb *msg, RUA_SuccessfulOutcome_t *in)
Harald Welte318e4d52015-09-10 18:47:08 +0200201{
202
203}
204
Harald Welte350814a2015-09-10 22:32:15 +0200205static int rua_rx_unsuccessful_outcome_msg(struct msgb *msg, RUA_UnsuccessfulOutcome_t *in)
Harald Welte318e4d52015-09-10 18:47:08 +0200206{
207
208}
209
210
Harald Welte350814a2015-09-10 22:32:15 +0200211static int _hnbgw_rua_rx(struct msgb *msg, RUA_RUA_PDU_t *pdu)
Harald Welte318e4d52015-09-10 18:47:08 +0200212{
213 int rc;
214
215 /* it's a bit odd that we can't dispatch on procedure code, but
216 * that's not possible */
217 switch (pdu->present) {
218 case RUA_RUA_PDU_PR_initiatingMessage:
Harald Welte350814a2015-09-10 22:32:15 +0200219 rc = rua_rx_initiating_msg(msg, &pdu->choice.initiatingMessage);
Harald Welte318e4d52015-09-10 18:47:08 +0200220 break;
221 case RUA_RUA_PDU_PR_successfulOutcome:
Harald Welte350814a2015-09-10 22:32:15 +0200222 rc = rua_rx_successful_outcome_msg(msg, &pdu->choice.successfulOutcome);
Harald Welte318e4d52015-09-10 18:47:08 +0200223 break;
224 case RUA_RUA_PDU_PR_unsuccessfulOutcome:
Harald Welte350814a2015-09-10 22:32:15 +0200225 rc = rua_rx_unsuccessful_outcome_msg(msg, &pdu->choice.unsuccessfulOutcome);
Harald Welte318e4d52015-09-10 18:47:08 +0200226 break;
227 default:
228 return -1;
229 }
230}
231
232int hnbgw_rua_rx(struct hnb_context *hnb, struct msgb *msg)
233{
234 RUA_RUA_PDU_t _pdu, *pdu = &_pdu;
235 asn_dec_rval_t dec_ret;
236 int rc;
237
238 /* decode and handle to _hnbgw_hnbap_rx() */
239
240 memset(pdu, 0, sizeof(*pdu));
241 dec_ret = aper_decode(NULL, &asn_DEF_RUA_RUA_PDU, (void **) &pdu,
242 msg->data, msgb_length(msg), 0, 0);
243 if (dec_ret.code != RC_OK) {
244 LOGP(DMAIN, LOGL_ERROR, "Error in ASN.1 decode\n");
245 return rc;
246 }
247
Harald Welte350814a2015-09-10 22:32:15 +0200248 rc = _hnbgw_rua_rx(msg, pdu);
Harald Welte318e4d52015-09-10 18:47:08 +0200249
250 return rc;
251}
252
253
254int hnbgw_rua_init(void)
255{
256
257}