blob: b1021b0dd3ace76cebeeae0feaba71fe44f2110a [file] [log] [blame]
Harald Welte77847ad2015-10-06 22:07:04 +02001/* common RANAP 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
Harald Welteac9c0242015-09-10 21:18:16 +020021#include <stdint.h>
22
23#include <osmocom/core/msgb.h>
24
Harald Welteace1d242015-12-16 23:07:19 +010025#include "ranap_common.h"
Harald Welteac9c0242015-09-10 21:18:16 +020026#include "hnbgw.h"
27
28extern int asn1_xer_print;
29
30static struct msgb *ranap_msgb_alloc(void)
31{
32 return msgb_alloc(1024, "RANAP Tx");
33}
34
Harald Welte8dacb072015-12-16 20:27:14 +010035static struct msgb *_ranap_gen_msg(RANAP_RANAP_PDU_t *pdu)
Harald Welteac9c0242015-09-10 21:18:16 +020036{
Harald Weltecbaaeef2015-12-16 20:17:26 +010037 struct msgb *msg = ranap_msgb_alloc();
38 asn_enc_rval_t rval;
Harald Welteac9c0242015-09-10 21:18:16 +020039
Harald Welte8dacb072015-12-16 20:27:14 +010040 if (!msg)
Harald Weltecbaaeef2015-12-16 20:17:26 +010041 return NULL;
Harald Welteac9c0242015-09-10 21:18:16 +020042
Harald Welte8dacb072015-12-16 20:27:14 +010043 rval = aper_encode_to_buffer(&asn_DEF_RANAP_RANAP_PDU, pdu,
Harald Weltecbaaeef2015-12-16 20:17:26 +010044 msg->data, msgb_tailroom(msg));
45 if (rval.encoded < 0) {
46 LOGP(DMAIN, LOGL_ERROR, "Error encoding type: %s\n",
47 rval.failed_type->name);
48
49 }
50
51 msgb_put(msg, rval.encoded/8);
52
53 return msg;
Harald Welteac9c0242015-09-10 21:18:16 +020054}
Harald Welteac9c0242015-09-10 21:18:16 +020055
Harald Welte8dacb072015-12-16 20:27:14 +010056struct msgb *ranap_generate_initiating_message(e_RANAP_ProcedureCode procedureCode,
57 RANAP_Criticality_t criticality,
58 asn_TYPE_descriptor_t *td, void *sptr)
59{
60 RANAP_RANAP_PDU_t pdu;
61 int rc;
62
63 memset(&pdu, 0, sizeof(pdu));
64
65 pdu.present = RANAP_RANAP_PDU_PR_initiatingMessage;
66 pdu.choice.initiatingMessage.procedureCode = procedureCode;
67 pdu.choice.initiatingMessage.criticality = criticality;
68 rc = ANY_fromType_aper(&pdu.choice.initiatingMessage.value, td, sptr);
69 if (rc < 0) {
70 LOGP(DMAIN, LOGL_ERROR, "Error in ANY_fromType_aper\n");
71 return NULL;
72 }
73
74 return _ranap_gen_msg(&pdu);
75}
76
Harald Welteac9c0242015-09-10 21:18:16 +020077struct msgb *ranap_generate_successful_outcome(
78 e_RANAP_ProcedureCode procedureCode,
79 RANAP_Criticality_t criticality,
80 asn_TYPE_descriptor_t * td,
81 void *sptr)
82{
Harald Welteac9c0242015-09-10 21:18:16 +020083 RANAP_RANAP_PDU_t pdu;
Harald Welteac9c0242015-09-10 21:18:16 +020084 int rc;
85
86 memset(&pdu, 0, sizeof(pdu));
Harald Welte8dacb072015-12-16 20:27:14 +010087
Harald Welteac9c0242015-09-10 21:18:16 +020088 pdu.present = RANAP_RANAP_PDU_PR_successfulOutcome;
89 pdu.choice.successfulOutcome.procedureCode = procedureCode;
90 pdu.choice.successfulOutcome.criticality = criticality;
91 rc = ANY_fromType_aper(&pdu.choice.successfulOutcome.value, td, sptr);
92 if (rc < 0) {
93 LOGP(DMAIN, LOGL_ERROR, "Error in ANY_fromType_aper\n");
Harald Welteac9c0242015-09-10 21:18:16 +020094 return NULL;
95 }
96
Harald Welte8dacb072015-12-16 20:27:14 +010097 return _ranap_gen_msg(&pdu);
Harald Welteac9c0242015-09-10 21:18:16 +020098}
99
Harald Weltecbaaeef2015-12-16 20:17:26 +0100100struct msgb *ranap_generate_unsuccessful_outcome(
Harald Welteac9c0242015-09-10 21:18:16 +0200101 e_RANAP_ProcedureCode procedureCode,
102 RANAP_Criticality_t criticality,
103 asn_TYPE_descriptor_t * td,
104 void *sptr)
105{
Harald Welteac9c0242015-09-10 21:18:16 +0200106 RANAP_RANAP_PDU_t pdu;
Harald Weltecbaaeef2015-12-16 20:17:26 +0100107 int rc;
Harald Welteac9c0242015-09-10 21:18:16 +0200108
109 memset(&pdu, 0, sizeof(pdu));
110
111 pdu.present = RANAP_RANAP_PDU_PR_unsuccessfulOutcome;
Harald Weltec16117a2015-12-16 20:30:11 +0100112 pdu.choice.unsuccessfulOutcome.procedureCode = procedureCode;
113 pdu.choice.unsuccessfulOutcome.criticality = criticality;
114 rc = ANY_fromType_aper(&pdu.choice.unsuccessfulOutcome.value, td, sptr);
Harald Weltecbaaeef2015-12-16 20:17:26 +0100115 if (rc < 0) {
116 LOGP(DMAIN, LOGL_ERROR, "Error in ANY_fromType_aper\n");
Harald Weltecbaaeef2015-12-16 20:17:26 +0100117 return NULL;
Harald Welteac9c0242015-09-10 21:18:16 +0200118 }
119
Harald Welte8dacb072015-12-16 20:27:14 +0100120 return _ranap_gen_msg(&pdu);
Harald Welteac9c0242015-09-10 21:18:16 +0200121}
Harald Welteac9c0242015-09-10 21:18:16 +0200122
Harald Weltec16117a2015-12-16 20:30:11 +0100123struct msgb *ranap_generate_outcome(
124 e_RANAP_ProcedureCode procedureCode,
125 RANAP_Criticality_t criticality,
126 asn_TYPE_descriptor_t * td,
127 void *sptr)
128{
129 RANAP_RANAP_PDU_t pdu;
130 int rc;
131
132 memset(&pdu, 0, sizeof(pdu));
133
134 pdu.present = RANAP_RANAP_PDU_PR_outcome;
135 pdu.choice.outcome.procedureCode = procedureCode;
136 pdu.choice.outcome.criticality = criticality;
137 rc = ANY_fromType_aper(&pdu.choice.outcome.value, td, sptr);
138 if (rc < 0) {
139 LOGP(DMAIN, LOGL_ERROR, "Error in ANY_fromType_aper\n");
140 return NULL;
141 }
142
143 return _ranap_gen_msg(&pdu);
144}
145
146
Harald Welteac9c0242015-09-10 21:18:16 +0200147RANAP_IE_t *ranap_new_ie(RANAP_ProtocolIE_ID_t id,
148 RANAP_Criticality_t criticality,
149 asn_TYPE_descriptor_t * type, void *sptr)
150{
151
152 RANAP_IE_t *buff;
153
154 if ((buff = malloc(sizeof(*buff))) == NULL) {
155 // Possible error on malloc
156 return NULL;
157 }
158 memset((void *)buff, 0, sizeof(*buff));
159
160 buff->id = id;
161 buff->criticality = criticality;
162
163 ANY_fromType_aper(&buff->value, type, sptr);
164
165 if (asn1_xer_print)
166 if (xer_fprint(stdout, &asn_DEF_RANAP_IE, buff) < 0) {
167 free(buff);
168 return NULL;
169 }
170
171 return buff;
172}
Harald Welteace1d242015-12-16 23:07:19 +0100173
174RANAP_ProtocolIE_FieldPair_t *ranap_new_ie_pair(RANAP_ProtocolIE_ID_t id,
175 RANAP_Criticality_t criticality1,
176 asn_TYPE_descriptor_t *type1, void *sptr1,
177 RANAP_Criticality_t criticality2,
178 asn_TYPE_descriptor_t *type2, void *sptr2)
179{
180
181 RANAP_ProtocolIE_FieldPair_t *buff;
182
183 if ((buff = malloc(sizeof(*buff))) == NULL) {
184 // Possible error on malloc
185 return NULL;
186 }
187 memset((void *)buff, 0, sizeof(*buff));
188
189 buff->id = id;
190 buff->firstCriticality = criticality1;
191 buff->secondCriticality = criticality2;
192
193 ANY_fromType_aper(&buff->firstValue, type1, sptr1);
194 ANY_fromType_aper(&buff->secondValue, type2, sptr2);
195
196 if (asn1_xer_print)
197 if (xer_fprint(stdout, &asn_DEF_RANAP_IE, buff) < 0) {
198 free(buff);
199 return NULL;
200 }
201
202 return buff;
203}