blob: 3c9d773404d1a444714d0d1b0ba8000c1c696da3 [file] [log] [blame]
Harald Welte77847ad2015-10-06 22:07:04 +02001/* common RUA (RANAP User Adaption) Code */
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 Welte656ad302015-09-10 18:33:47 +020022#include <stdint.h>
23
24#include <osmocom/core/msgb.h>
25
Neels Hofmeyr83457922016-08-26 23:56:44 +020026#include <osmocom/rua/rua_common.h>
Neels Hofmeyrdf63de22016-08-18 13:13:55 +020027#include <osmocom/iuh/hnbgw.h>
Harald Welte656ad302015-09-10 18:33:47 +020028
29extern int asn1_xer_print;
30
Harald Weltee2e5d4d2015-09-10 23:49:45 +020031static const struct value_string rua_cause_radio_vals[] = {
32 { RUA_CauseRadioNetwork_normal, "normal" },
33 { RUA_CauseRadioNetwork_connect_failed, "connect failed" },
34 { RUA_CauseRadioNetwork_network_release, "network release" },
35 { RUA_CauseRadioNetwork_unspecified, "unspecified" },
36 { 0, NULL }
37};
38
39static const struct value_string rua_cause_transp_vals[] = {
40 { RUA_CauseTransport_transport_resource_unavailable, "resource unavailable" },
41 { RUA_CauseTransport_unspecified, "unspecified" },
42 { 0, NULL }
43};
44
45static const struct value_string rua_cause_prot_vals[] = {
46 { RUA_CauseProtocol_transfer_syntax_error, "syntax error" },
47 { RUA_CauseProtocol_abstract_syntax_error_reject,
48 "abstract syntax error; reject" },
49 { RUA_CauseProtocol_abstract_syntax_error_ignore_and_notify,
50 "abstract syntax error; ignore and notify" },
51 { RUA_CauseProtocol_message_not_compatible_with_receiver_state,
52 "message not compatible with receiver state" },
53 { RUA_CauseProtocol_semantic_error, "semantic error" },
54 { RUA_CauseProtocol_unspecified, "unspecified" },
55 { RUA_CauseProtocol_abstract_syntax_error_falsely_constructed_message,
56 "falsely constructed message" },
57 { 0, NULL }
58};
59
60static const struct value_string rua_cause_misc_vals[] = {
61 { RUA_CauseMisc_processing_overload, "processing overload" },
62 { RUA_CauseMisc_hardware_failure, "hardware failure" },
63 { RUA_CauseMisc_o_and_m_intervention, "OAM intervention" },
64 { RUA_CauseMisc_unspecified, "unspecified" },
65 { 0, NULL }
66};
67
68char *rua_cause_str(RUA_Cause_t *cause)
69{
70 static char buf[32];
71
72 switch (cause->present) {
73 case RUA_Cause_PR_radioNetwork:
74 snprintf(buf, sizeof(buf), "radio(%s)",
75 get_value_string(rua_cause_radio_vals,
76 cause->choice.radioNetwork));
77 break;
78 case RUA_Cause_PR_transport:
79 snprintf(buf, sizeof(buf), "transport(%s)",
80 get_value_string(rua_cause_transp_vals,
81 cause->choice.transport));
82 break;
83 case RUA_Cause_PR_protocol:
84 snprintf(buf, sizeof(buf), "protocol(%s)",
85 get_value_string(rua_cause_prot_vals,
86 cause->choice.protocol));
87 break;
88 case RUA_Cause_PR_misc:
89 snprintf(buf, sizeof(buf), "misc(%s)",
90 get_value_string(rua_cause_misc_vals,
91 cause->choice.misc));
92 break;
Harald Weltec3ca7eb2015-12-25 10:17:17 +010093 default:
94 strcpy(buf, "unknown");
95 break;
Harald Weltee2e5d4d2015-09-10 23:49:45 +020096 }
97 return buf;
98}
99
100
Harald Welte656ad302015-09-10 18:33:47 +0200101static struct msgb *rua_msgb_alloc(void)
102{
103 return msgb_alloc(1024, "RUA Tx");
104}
105
Harald Welte8dacb072015-12-16 20:27:14 +0100106static struct msgb *_rua_gen_msg(RUA_RUA_PDU_t *pdu)
107{
108 struct msgb *msg = rua_msgb_alloc();
109 asn_enc_rval_t rval;
110
111 if (!msg)
112 return NULL;
113
114 rval = aper_encode_to_buffer(&asn_DEF_RUA_RUA_PDU, pdu,
115 msg->data, msgb_tailroom(msg));
116 if (rval.encoded < 0) {
Harald Weltef42317b2015-12-23 15:36:31 +0100117 LOGP(DRUA, LOGL_ERROR, "Error encoding type: %s\n",
Harald Welte8dacb072015-12-16 20:27:14 +0100118 rval.failed_type->name);
119
120 }
121
122 msgb_put(msg, rval.encoded/8);
123
124 return msg;
125}
126
127
Harald Weltee2e5d4d2015-09-10 23:49:45 +0200128struct msgb *rua_generate_initiating_message(
Harald Welte656ad302015-09-10 18:33:47 +0200129 e_RUA_ProcedureCode procedureCode,
130 RUA_Criticality_t criticality,
131 asn_TYPE_descriptor_t * td, void *sptr)
132{
133 RUA_RUA_PDU_t pdu;
Harald Welte8dacb072015-12-16 20:27:14 +0100134 int rc;
Harald Welte656ad302015-09-10 18:33:47 +0200135
136 memset(&pdu, 0, sizeof(pdu));
Harald Welte8dacb072015-12-16 20:27:14 +0100137
Harald Welte656ad302015-09-10 18:33:47 +0200138 pdu.present = RUA_RUA_PDU_PR_initiatingMessage;
139 pdu.choice.initiatingMessage.procedureCode = procedureCode;
140 pdu.choice.initiatingMessage.criticality = criticality;
Harald Welte8dacb072015-12-16 20:27:14 +0100141 rc = ANY_fromType_aper(&pdu.choice.initiatingMessage.value, td, sptr);
142 if (rc < 0) {
Harald Weltef42317b2015-12-23 15:36:31 +0100143 LOGP(DRUA, LOGL_ERROR, "Error in ANY_fromType_aper\n");
Harald Weltee2e5d4d2015-09-10 23:49:45 +0200144 return NULL;
Harald Welte656ad302015-09-10 18:33:47 +0200145 }
146
Harald Welte8dacb072015-12-16 20:27:14 +0100147 return _rua_gen_msg(&pdu);
Harald Welte656ad302015-09-10 18:33:47 +0200148}
Harald Welte656ad302015-09-10 18:33:47 +0200149
150struct msgb *rua_generate_successful_outcome(
151 e_RUA_ProcedureCode procedureCode,
152 RUA_Criticality_t criticality,
153 asn_TYPE_descriptor_t * td,
154 void *sptr)
155{
Harald Welte656ad302015-09-10 18:33:47 +0200156 RUA_RUA_PDU_t pdu;
Harald Welte656ad302015-09-10 18:33:47 +0200157 int rc;
158
159 memset(&pdu, 0, sizeof(pdu));
Harald Welte8dacb072015-12-16 20:27:14 +0100160
Harald Welte656ad302015-09-10 18:33:47 +0200161 pdu.present = RUA_RUA_PDU_PR_successfulOutcome;
162 pdu.choice.successfulOutcome.procedureCode = procedureCode;
163 pdu.choice.successfulOutcome.criticality = criticality;
164 rc = ANY_fromType_aper(&pdu.choice.successfulOutcome.value, td, sptr);
165 if (rc < 0) {
Harald Weltef42317b2015-12-23 15:36:31 +0100166 LOGP(DRUA, LOGL_ERROR, "Error in ANY_fromType_aper\n");
Harald Welte656ad302015-09-10 18:33:47 +0200167 return NULL;
168 }
169
Harald Welte8dacb072015-12-16 20:27:14 +0100170 return _rua_gen_msg(&pdu);
Harald Welte656ad302015-09-10 18:33:47 +0200171}
172
Harald Weltecbaaeef2015-12-16 20:17:26 +0100173struct msgb *rua_generate_unsuccessful_outcome(
174 e_RUA_ProcedureCode procedureCode,
175 RUA_Criticality_t criticality,
176 asn_TYPE_descriptor_t * td,
177 void *sptr)
Harald Welte656ad302015-09-10 18:33:47 +0200178{
Harald Welte656ad302015-09-10 18:33:47 +0200179 RUA_RUA_PDU_t pdu;
Harald Weltecbaaeef2015-12-16 20:17:26 +0100180 int rc;
Harald Welte656ad302015-09-10 18:33:47 +0200181
182 memset(&pdu, 0, sizeof(pdu));
Harald Welte8dacb072015-12-16 20:27:14 +0100183
Harald Welte656ad302015-09-10 18:33:47 +0200184 pdu.present = RUA_RUA_PDU_PR_unsuccessfulOutcome;
Harald Weltecbaaeef2015-12-16 20:17:26 +0100185 pdu.choice.unsuccessfulOutcome.procedureCode = procedureCode;
186 pdu.choice.unsuccessfulOutcome.criticality = criticality;
187 rc = ANY_fromType_aper(&pdu.choice.unsuccessfulOutcome.value, td, sptr);
188 if (rc < 0) {
Harald Weltef42317b2015-12-23 15:36:31 +0100189 LOGP(DRUA, LOGL_ERROR, "Error in ANY_fromType_aper\n");
Harald Weltecbaaeef2015-12-16 20:17:26 +0100190 return NULL;
Harald Welte656ad302015-09-10 18:33:47 +0200191 }
192
Harald Welte8dacb072015-12-16 20:27:14 +0100193 return _rua_gen_msg(&pdu);
Harald Welte656ad302015-09-10 18:33:47 +0200194}
Harald Welte656ad302015-09-10 18:33:47 +0200195
196RUA_IE_t *rua_new_ie(RUA_ProtocolIE_ID_t id,
197 RUA_Criticality_t criticality,
198 asn_TYPE_descriptor_t * type, void *sptr)
199{
200
201 RUA_IE_t *buff;
Harald Welte04329dc2015-12-18 15:17:21 +0100202 int rc;
Harald Welte656ad302015-09-10 18:33:47 +0200203
Harald Welte8526d152015-12-18 13:41:39 +0100204 if ((buff = CALLOC(1, sizeof(*buff))) == NULL) {
Harald Welte656ad302015-09-10 18:33:47 +0200205 // Possible error on malloc
206 return NULL;
207 }
Harald Welte656ad302015-09-10 18:33:47 +0200208
209 buff->id = id;
210 buff->criticality = criticality;
211
Harald Welte04329dc2015-12-18 15:17:21 +0100212 rc = ANY_fromType_aper(&buff->value, type, sptr);
213 if (rc < 0) {
Harald Weltef42317b2015-12-23 15:36:31 +0100214 LOGP(DRUA, LOGL_ERROR, "Error in ANY_fromType_aper\n");
Harald Welte04329dc2015-12-18 15:17:21 +0100215 FREEMEM(buff);
216 return NULL;
217 }
Harald Welte656ad302015-09-10 18:33:47 +0200218
219 if (asn1_xer_print)
220 if (xer_fprint(stdout, &asn_DEF_RUA_IE, buff) < 0) {
Harald Welte62939132015-12-18 14:57:04 +0100221 FREEMEM(buff);
Harald Welte656ad302015-09-10 18:33:47 +0200222 return NULL;
223 }
224
225 return buff;
226}