blob: bad99c8c63c8b06c0d4b248d6a6546359c6339d5 [file] [log] [blame]
Harald Welte350814a2015-09-10 22:32:15 +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 Weltee2e5d4d2015-09-10 23:49:45 +020011#include "hnbgw_rua.h"
Harald Welte350814a2015-09-10 22:32:15 +020012//#include "ranap_common.h"
13
14#include "ranap/RANAP_RANAP-PDU.h"
15#include "ranap/RANAP_ResetAcknowledge.h"
16#include "ranap/RANAP_Reset.h"
17#include "ranap/RANAP_ProtocolIE-ID.h"
18#include "ranap/RANAP_Cause.h"
19#include "ranap/RANAP_CN-DomainIndicator.h"
20#include "ranap/RANAP_GlobalRNC-ID.h"
21#include "ranap/RANAP_CriticalityDiagnostics.h"
22
23
24/***********************************************************************
25 * BEGIN auto-generated copy+pasted
26 ***********************************************************************/
27
28/* this is copy+pasted from the asn1tostruct generated code that doesn't
29 * compile as a whole */
30
31#define RANAP_DEBUG(x, args ...) DEBUGP(0, x, ## args)
32
33extern int asn1_xer_print;
34
35struct msgb *ranap_generate_successful_outcome(
36 e_RANAP_ProcedureCode procedureCode,
37 RANAP_Criticality_t criticality,
38 asn_TYPE_descriptor_t * td,
39 void *sptr);
40
41RANAP_IE_t *ranap_new_ie(RANAP_ProtocolIE_ID_t id, RANAP_Criticality_t criticality,
42 asn_TYPE_descriptor_t *type, void *sptr);
43
44#define RESETIES_RANAP_GLOBALRNC_ID_PRESENT (1 << 0)
45
46typedef struct RANAP_ResetIEs_s {
47 uint16_t presenceMask;
48 RANAP_Cause_t cause;
49 RANAP_CN_DomainIndicator_t cN_DomainIndicator;
50 RANAP_GlobalRNC_ID_t globalRNC_ID; ///< Optional field
51} RANAP_ResetIEs_t;
52
53#define RESETACKNOWLEDGEIES_RANAP_CRITICALITYDIAGNOSTICS_PRESENT (1 << 0)
54#define RESETACKNOWLEDGEIES_RANAP_GLOBALRNC_ID_PRESENT (1 << 1)
55
56typedef struct RANAP_ResetAcknowledgeIEs_s {
57 uint16_t presenceMask;
58 RANAP_CN_DomainIndicator_t cN_DomainIndicator;
59 RANAP_CriticalityDiagnostics_t criticalityDiagnostics; ///< Optional field
60 RANAP_GlobalRNC_ID_t globalRNC_ID; ///< Optional field
61} RANAP_ResetAcknowledgeIEs_t;
62
63int ranap_decode_reseties(
64 RANAP_ResetIEs_t *resetIEs,
65 ANY_t *any_p) {
66
67 RANAP_Reset_t reset;
68 RANAP_Reset_t *reset_p = &reset;
69 int i, decoded = 0;
70 int tempDecoded = 0;
71 assert(any_p != NULL);
72 assert(resetIEs != NULL);
73
74 RANAP_DEBUG("Decoding message RANAP_ResetIEs (%s:%d)\n", __FILE__, __LINE__);
75
76 ANY_to_type_aper(any_p, &asn_DEF_RANAP_Reset, (void**)&reset_p);
77
78 for (i = 0; i < reset_p->reset_ies.list.count; i++) {
79 RANAP_IE_t *ie_p;
80 ie_p = reset_p->reset_ies.list.array[i];
81 switch(ie_p->id) {
82 case RANAP_ProtocolIE_ID_id_Cause:
83 {
84 RANAP_Cause_t ranaP_Cause;
85 RANAP_Cause_t *ranaP_Cause_p = &ranaP_Cause;
86 tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_RANAP_Cause, (void**)&ranaP_Cause_p);
87 if (tempDecoded < 0) {
88 RANAP_DEBUG("Decoding of IE cause failed\n");
89 return -1;
90 }
91 decoded += tempDecoded;
92 if (asn1_xer_print)
93 xer_fprint(stdout, &asn_DEF_RANAP_Cause, ranaP_Cause_p);
94 memcpy(&resetIEs->cause, ranaP_Cause_p, sizeof(RANAP_Cause_t));
95 } break;
96 case RANAP_ProtocolIE_ID_id_CN_DomainIndicator:
97 {
98 RANAP_CN_DomainIndicator_t ranaP_CNDomainIndicator;
99 RANAP_CN_DomainIndicator_t *ranaP_CNDomainIndicator_p = &ranaP_CNDomainIndicator;
100 tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_RANAP_CN_DomainIndicator, (void**)&ranaP_CNDomainIndicator_p);
101 if (tempDecoded < 0) {
102 RANAP_DEBUG("Decoding of IE cN_DomainIndicator failed\n");
103 return -1;
104 }
105 decoded += tempDecoded;
106 if (asn1_xer_print)
107 xer_fprint(stdout, &asn_DEF_RANAP_CN_DomainIndicator, ranaP_CNDomainIndicator_p);
108 memcpy(&resetIEs->cN_DomainIndicator, ranaP_CNDomainIndicator_p, sizeof(RANAP_CN_DomainIndicator_t));
109 } break;
110 /* Optional field */
111 case RANAP_ProtocolIE_ID_id_GlobalRNC_ID:
112 {
113#if 0
114 RANAP_GlobalRNC_ID_t ranaP_GlobalRNCID;
115 RANAP_GlobalRNC_ID_t *ranaP_GlobalRNCID_p = &ranaP_GlobalRNCID;
116 resetIEs->presenceMask |= RESETIES_RANAP_GLOBALRNC_ID_PRESENT;
117 tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_RANAP_GlobalRNC_ID, (void**)&ranaP_GlobalRNCID_p);
118 if (tempDecoded < 0) {
119 RANAP_DEBUG("Decoding of IE globalRNC_ID failed\n");
120 return -1;
121 }
122 decoded += tempDecoded;
123 if (asn1_xer_print)
124 xer_fprint(stdout, &asn_DEF_RANAP_GlobalRNC_ID, ranaP_GlobalRNCID_p);
125 memcpy(&resetIEs->globalRNC_ID, ranaP_GlobalRNCID_p, sizeof(RANAP_GlobalRNC_ID_t));
126#endif
127 } break;
128 default:
129 RANAP_DEBUG("Unknown protocol IE id (%d) for message reseties\n", (int)ie_p->id);
130 return -1;
131 }
132 }
133 return decoded;
134}
135
136int ranap_encode_resetacknowledgeies(
137 RANAP_ResetAcknowledge_t *resetAcknowledge,
138 RANAP_ResetAcknowledgeIEs_t *resetAcknowledgeIEs) {
139
140 RANAP_IE_t *ie;
141
142 if ((ie = ranap_new_ie(RANAP_ProtocolIE_ID_id_CN_DomainIndicator,
143 RANAP_Criticality_reject,
144 &asn_DEF_RANAP_CN_DomainIndicator,
145 &resetAcknowledgeIEs->cN_DomainIndicator)) == NULL) {
146 return -1;
147 }
148 ASN_SEQUENCE_ADD(&resetAcknowledge->resetAcknowledge_ies.list, ie);
149
150 /* Optional field */
151 if ((resetAcknowledgeIEs->presenceMask & RESETACKNOWLEDGEIES_RANAP_CRITICALITYDIAGNOSTICS_PRESENT)
152 == RESETACKNOWLEDGEIES_RANAP_CRITICALITYDIAGNOSTICS_PRESENT) {
153 if ((ie = ranap_new_ie(RANAP_ProtocolIE_ID_id_CriticalityDiagnostics,
154 RANAP_Criticality_ignore,
155 &asn_DEF_RANAP_CriticalityDiagnostics,
156 &resetAcknowledgeIEs->criticalityDiagnostics)) == NULL) {
157 return -1;
158 }
159 ASN_SEQUENCE_ADD(&resetAcknowledge->resetAcknowledge_ies.list, ie);
160 }
161
162 /* Optional field */
163 if ((resetAcknowledgeIEs->presenceMask & RESETACKNOWLEDGEIES_RANAP_GLOBALRNC_ID_PRESENT)
164 == RESETACKNOWLEDGEIES_RANAP_GLOBALRNC_ID_PRESENT) {
165 if ((ie = ranap_new_ie(RANAP_ProtocolIE_ID_id_GlobalRNC_ID,
166 RANAP_Criticality_ignore,
167 &asn_DEF_RANAP_GlobalRNC_ID,
168 &resetAcknowledgeIEs->globalRNC_ID)) == NULL) {
169 return -1;
170 }
171 ASN_SEQUENCE_ADD(&resetAcknowledge->resetAcknowledge_ies.list, ie);
172 }
173
174 return 0;
175}
176
177/***********************************************************************
178 * END auto-generated copy+pasted
179 ***********************************************************************/
180
Harald Weltee2e5d4d2015-09-10 23:49:45 +0200181static int ranap_tx_reset_ack(struct hnb_context *hnb,
182 RANAP_CN_DomainIndicator_t domain)
Harald Welte350814a2015-09-10 22:32:15 +0200183{
Harald Weltee2e5d4d2015-09-10 23:49:45 +0200184 RANAP_ResetAcknowledge_t out;
185 RANAP_ResetAcknowledgeIEs_t ies;
186 struct msgb *msg;
187 int rc;
Harald Welte350814a2015-09-10 22:32:15 +0200188
189 memset(&ies, 0, sizeof(ies));
Harald Weltee2e5d4d2015-09-10 23:49:45 +0200190 ies.cN_DomainIndicator = domain;
Harald Welte350814a2015-09-10 22:32:15 +0200191
Harald Weltee2e5d4d2015-09-10 23:49:45 +0200192 memset(&out, 0, sizeof(out));
193 rc = ranap_encode_resetacknowledgeies(&out, &ies);
194 if (rc < 0) {
195 LOGP(DMAIN, LOGL_ERROR, "error encoding reset ack IEs: %d\n", rc);
196 return rc;
197 }
198
199 msg = ranap_generate_successful_outcome(RANAP_ProcedureCode_id_Reset,
200 RANAP_Criticality_reject,
201 &asn_DEF_RANAP_ResetAcknowledge,
202 &out);
203 if (!msg)
204 return -1;
205
206 msg->dst = hnb;
207
208 rc = rua_tx_udt(msg);
209
210 return rc;
Harald Welte350814a2015-09-10 22:32:15 +0200211}
Harald Welte350814a2015-09-10 22:32:15 +0200212
213static int ranap_rx_init_reset(struct hnb_context *hnb, ANY_t *in)
214{
215 RANAP_ResetIEs_t ies;
216 int rc;
217
218 rc = ranap_decode_reseties(&ies, in);
219 if (rc < 0)
220 return rc;
221
222 DEBUGP(DMAIN, "RESET.req\n");
223
Harald Weltee2e5d4d2015-09-10 23:49:45 +0200224 ranap_tx_reset_ack(hnb, ies.cN_DomainIndicator);
225
Harald Welte350814a2015-09-10 22:32:15 +0200226 return 0;
227}
228
229static int ranap_rx_initiating_msg(struct hnb_context *hnb, RANAP_InitiatingMessage_t *imsg)
230{
231 int rc;
232
233 switch (imsg->procedureCode) {
234 case RANAP_ProcedureCode_id_Reset:
235 rc = ranap_rx_init_reset(hnb, &imsg->value);
236 break;
237 }
238}
239
240static int _hnbgw_ranap_rx(struct hnb_context *hnb, RANAP_RANAP_PDU_t *pdu)
241{
242 int rc;
243
244 switch (pdu->present) {
245 case RANAP_RANAP_PDU_PR_initiatingMessage:
246 rc = ranap_rx_initiating_msg(hnb, &pdu->choice.initiatingMessage);
247 break;
248 case RANAP_RANAP_PDU_PR_successfulOutcome:
249 break;
250 case RANAP_RANAP_PDU_PR_unsuccessfulOutcome:
251 break;
252 default:
253 break;
254 }
255}
256
257
258int hnbgw_ranap_rx(struct msgb *msg, uint8_t *data, size_t len)
259{
260 RANAP_RANAP_PDU_t _pdu, *pdu = &_pdu;
261 asn_dec_rval_t dec_ret;
262 int rc;
263
264 memset(pdu, 0, sizeof(*pdu));
265 dec_ret = aper_decode(NULL,&asn_DEF_RANAP_RANAP_PDU, (void **) &pdu,
266 data, len, 0, 0);
267 if (dec_ret.code != RC_OK) {
268 LOGP(DMAIN, LOGL_ERROR, "Error in RANAP ASN.1 decode\n");
269 return rc;
270 }
271
272 rc = _hnbgw_ranap_rx(msg->dst, pdu);
273
274 return rc;
275}
276
277int hnbgw_ranap_init(void)
278{
279
280}