blob: a5e46f06805b5f7ccfdbcf47f7624c4b69b992dc [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"
11#include "rua_common.h"
12#include "rua_ies_defs.h"
13
14static int hnbgw_rua_tx(struct hnb_context *ctx, struct msgb *msg)
15{
16 if (!msg)
17 return -EINVAL;
18
19 msgb_ppid(msg) = IUH_PPI_RUA;
20 return osmo_wqueue_enqueue(&ctx->wqueue, msg);
21}
22
Harald Welte64b4ebe2015-09-10 19:29:59 +020023static const struct value_string rua_cause_radio_vals[] = {
24 { RUA_CauseRadioNetwork_normal, "normal" },
25 { RUA_CauseRadioNetwork_connect_failed, "connect failed" },
26 { RUA_CauseRadioNetwork_network_release, "network release" },
27 { RUA_CauseRadioNetwork_unspecified, "unspecified" },
28 { 0, NULL }
29};
30
31static const struct value_string rua_cause_transp_vals[] = {
32 { RUA_CauseTransport_transport_resource_unavailable, "resource unavailable" },
33 { RUA_CauseTransport_unspecified, "unspecified" },
34 { 0, NULL }
35};
36
37static const struct value_string rua_cause_prot_vals[] = {
38 { RUA_CauseProtocol_transfer_syntax_error, "syntax error" },
39 { RUA_CauseProtocol_abstract_syntax_error_reject,
40 "abstract syntax error; reject" },
41 { RUA_CauseProtocol_abstract_syntax_error_ignore_and_notify,
42 "abstract syntax error; ignore and notify" },
43 { RUA_CauseProtocol_message_not_compatible_with_receiver_state,
44 "message not compatible with receiver state" },
45 { RUA_CauseProtocol_semantic_error, "semantic error" },
46 { RUA_CauseProtocol_unspecified, "unspecified" },
47 { RUA_CauseProtocol_abstract_syntax_error_falsely_constructed_message,
48 "falsely constructed message" },
49 { 0, NULL }
50};
51
52static const struct value_string rua_cause_misc_vals[] = {
53 { RUA_CauseMisc_processing_overload, "processing overload" },
54 { RUA_CauseMisc_hardware_failure, "hardware failure" },
55 { RUA_CauseMisc_o_and_m_intervention, "OAM intervention" },
56 { RUA_CauseMisc_unspecified, "unspecified" },
57 { 0, NULL }
58};
59
60static char *rua_cause_str(RUA_Cause_t *cause)
61{
62 static char buf[32];
63
64 switch (cause->present) {
65 case RUA_Cause_PR_radioNetwork:
66 snprintf(buf, sizeof(buf), "radio(%s)",
67 get_value_string(rua_cause_radio_vals,
68 cause->choice.radioNetwork));
69 break;
70 case RUA_Cause_PR_transport:
71 snprintf(buf, sizeof(buf), "transport(%s)",
72 get_value_string(rua_cause_transp_vals,
73 cause->choice.transport));
74 break;
75 case RUA_Cause_PR_protocol:
76 snprintf(buf, sizeof(buf), "protocol(%s)",
77 get_value_string(rua_cause_prot_vals,
78 cause->choice.protocol));
79 break;
80 case RUA_Cause_PR_misc:
81 snprintf(buf, sizeof(buf), "misc(%s)",
82 get_value_string(rua_cause_misc_vals,
83 cause->choice.misc));
84 break;
85 }
86 return buf;
87}
88
89
90static int rua_rx_init_connect(struct hnb_context *hnb, ANY_t *in)
91{
92 RUA_ConnectIEs_t ies;
93 uint32_t context_id;
94 int rc;
95
96 rc = rua_decode_connecties(&ies, in);
97 if (rc < 0)
98 return rc;
99
100 context_id = asn1bitstr_to_u32(&ies.context_ID);
101
102 DEBUGP(DMAIN, "Connect.req(ctx=0x%x, %s)\n", context_id,
103 ies.establishment_Cause == RUA_Establishment_Cause_emergency_call
104 ? "emergency" : "normal");
105}
106
107static int rua_rx_init_disconnect(struct hnb_context *hnb, ANY_t *in)
108{
109 RUA_DisconnectIEs_t ies;
110 uint32_t context_id;
111 int rc;
112
113 rc = rua_decode_disconnecties(&ies, in);
114 if (rc < 0)
115 return rc;
116
117 context_id = asn1bitstr_to_u32(&ies.context_ID);
118
119 DEBUGP(DMAIN, "Disconnect.req(ctx=0x%x,cause=%s)\n", context_id,
120 rua_cause_str(&ies.cause));
121}
122
123static int rua_rx_init_dt(struct hnb_context *hnb, ANY_t *in)
124{
125 RUA_DirectTransferIEs_t ies;
126 uint32_t context_id;
127 int rc;
128
129 rc = rua_decode_directtransferies(&ies, in);
130 if (rc < 0)
131 return rc;
132
133 context_id = asn1bitstr_to_u32(&ies.context_ID);
134
135 DEBUGP(DMAIN, "Data.req(ctx=0x%x)\n", context_id);
136
137}
138
139static int rua_rx_init_udt(struct hnb_context *hnb, ANY_t *in)
140{
141 RUA_ConnectionlessTransferIEs_t ies;
142 int rc;
143
144 rc = rua_decode_connectionlesstransferies(&ies, in);
145 if (rc < 0)
146 return rc;
147
148 DEBUGP(DMAIN, "UData.req()\n");
149
150}
151
152static int rua_rx_init_err_ind(struct hnb_context *hnb, ANY_t *in)
153{
154 RUA_ErrorIndicationIEs_t ies;
155 int rc;
156
157 rc = rua_decode_errorindicationies(&ies, in);
158 if (rc < 0)
159 return rc;
160
161}
Harald Welte318e4d52015-09-10 18:47:08 +0200162
163static int rua_rx_initiating_msg(struct hnb_context *hnb, RUA_InitiatingMessage_t *imsg)
164{
165 int rc;
166
167 switch (imsg->procedureCode) {
168 case RUA_ProcedureCode_id_Connect:
Harald Welte64b4ebe2015-09-10 19:29:59 +0200169 rc = rua_rx_init_connect(hnb, &imsg->value);
Harald Welte318e4d52015-09-10 18:47:08 +0200170 break;
171 case RUA_ProcedureCode_id_DirectTransfer:
Harald Welte64b4ebe2015-09-10 19:29:59 +0200172 rc = rua_rx_init_dt(hnb, &imsg->value);
Harald Welte318e4d52015-09-10 18:47:08 +0200173 break;
174 case RUA_ProcedureCode_id_Disconnect:
Harald Welte64b4ebe2015-09-10 19:29:59 +0200175 rc = rua_rx_init_disconnect(hnb, &imsg->value);
Harald Welte318e4d52015-09-10 18:47:08 +0200176 break;
177 case RUA_ProcedureCode_id_ConnectionlessTransfer:
Harald Welte64b4ebe2015-09-10 19:29:59 +0200178 rc = rua_rx_init_udt(hnb, &imsg->value);
Harald Welte318e4d52015-09-10 18:47:08 +0200179 break;
180 case RUA_ProcedureCode_id_ErrorIndication:
Harald Welte64b4ebe2015-09-10 19:29:59 +0200181 rc = rua_rx_init_err_ind(hnb, &imsg->value);
182 break;
Harald Welte318e4d52015-09-10 18:47:08 +0200183 case RUA_ProcedureCode_id_privateMessage:
184 break;
185 default:
Harald Welte64b4ebe2015-09-10 19:29:59 +0200186 return -1;
Harald Welte318e4d52015-09-10 18:47:08 +0200187 }
188}
189
190static int rua_rx_successful_outcome_msg(struct hnb_context *hnb, RUA_SuccessfulOutcome_t *msg)
191{
192
193}
194
195static int rua_rx_unsuccessful_outcome_msg(struct hnb_context *hnb, RUA_UnsuccessfulOutcome_t *msg)
196{
197
198}
199
200
201static int _hnbgw_rua_rx(struct hnb_context *hnb, RUA_RUA_PDU_t *pdu)
202{
203 int rc;
204
205 /* it's a bit odd that we can't dispatch on procedure code, but
206 * that's not possible */
207 switch (pdu->present) {
208 case RUA_RUA_PDU_PR_initiatingMessage:
209 rc = rua_rx_initiating_msg(hnb, &pdu->choice.initiatingMessage);
210 break;
211 case RUA_RUA_PDU_PR_successfulOutcome:
212 rc = rua_rx_successful_outcome_msg(hnb, &pdu->choice.successfulOutcome);
213 break;
214 case RUA_RUA_PDU_PR_unsuccessfulOutcome:
215 rc = rua_rx_unsuccessful_outcome_msg(hnb, &pdu->choice.unsuccessfulOutcome);
216 break;
217 default:
218 return -1;
219 }
220}
221
222int hnbgw_rua_rx(struct hnb_context *hnb, struct msgb *msg)
223{
224 RUA_RUA_PDU_t _pdu, *pdu = &_pdu;
225 asn_dec_rval_t dec_ret;
226 int rc;
227
228 /* decode and handle to _hnbgw_hnbap_rx() */
229
230 memset(pdu, 0, sizeof(*pdu));
231 dec_ret = aper_decode(NULL, &asn_DEF_RUA_RUA_PDU, (void **) &pdu,
232 msg->data, msgb_length(msg), 0, 0);
233 if (dec_ret.code != RC_OK) {
234 LOGP(DMAIN, LOGL_ERROR, "Error in ASN.1 decode\n");
235 return rc;
236 }
237
238 rc = _hnbgw_rua_rx(hnb, pdu);
239
240 return rc;
241}
242
243
244int hnbgw_rua_init(void)
245{
246
247}