blob: cdb0e32d97104bc7878bca048fb2a26a3b36ab59 [file] [log] [blame]
Harald Weltee844bf72019-05-06 15:25:10 +02001/* common SABP 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#include <stdint.h>
22
23#include <osmocom/core/msgb.h>
24
25#include <osmocom/sabp/sabp_common.h>
26#include <asn1c/asn1helpers.h>
27
28extern int asn1_xer_print;
29int _sabp_DSABP = 0;
30#define DSABP _sabp_DSABP
31
32const struct value_string sabp_presence_vals[] = {
33 { SABP_SABP_PDU_PR_initiatingMessage, "Initiating" },
34 { SABP_SABP_PDU_PR_successfulOutcome, "Successful Outcome" },
35 { SABP_SABP_PDU_PR_unsuccessfulOutcome, "Unsuccessful Outcome" },
36 { 0, NULL }
37};
38
39const struct value_string sabp_procedure_code_vals[] = {
40 { SABP_ProcedureCode_id_Write_Replace, "Write-Replace" },
41 { SABP_ProcedureCode_id_Kill, "Kill" },
42 { SABP_ProcedureCode_id_Load_Status_Enquiry, "Load-Status-Enquiry" },
43 { SABP_ProcedureCode_id_Message_Status_Query, "Message-Status-Query" },
44 { SABP_ProcedureCode_id_Restart_Indication, "Restart-Indication" },
45 { SABP_ProcedureCode_id_Reset, "Reset" },
46 { SABP_ProcedureCode_id_Failure_Indication, "Failure-Indication" },
47 { SABP_ProcedureCode_id_Error_Indication, "Error-Indication" },
48 { 0, NULL }
49};
50
51const struct value_string sabp_cause_vals[] = {
52 { SABP_Cause_parameter_not_recognised, "Parameter not recognized" },
53 { SABP_Cause_parameter_value_invalid, "Parameter value invalid" },
54 { SABP_Cause_valid_CN_message_not_identified, "Valid CN message not identified" },
55 { SABP_Cause_service_area_identity_not_valid, "Service Area Identity not valid" },
56 { SABP_Cause_unrecognised_message, "Unrecognised message" },
57 { SABP_Cause_missing_mandatory_element, "Missing mandatory element" },
58 { SABP_Cause_rNC_capacity_exceeded, "RNC capacity exceeded" },
59 { SABP_Cause_rNC_memory_exceeded, "RNC memory exceeded" },
60 { SABP_Cause_service_area_broadcast_not_supported, "Service Area Broadcast not supported" },
61 { SABP_Cause_service_area_broadcast_not_operational, "Service Area Broadcast not operational" },
62 { SABP_Cause_message_reference_already_used, "Message Reference already used" },
63 { SABP_Cause_unspecifed_error, "Unspecified Error" },
64 { SABP_Cause_transfer_syntax_error, "Transfer Syntax Error" },
65 { SABP_Cause_semantic_error, "Semantic Error" },
66 { SABP_Cause_message_not_compatible_with_receiver_state,
67 "Message not compatible with receiver state" },
68 { SABP_Cause_abstract_syntax_error_reject, "Abstract Syntax Error - Reject" },
69 { SABP_Cause_abstract_syntax_error_ignore_and_notify,
70 "Abstract Syntax Error - Ignore and Notify" },
71 { SABP_Cause_abstract_syntax_error_falsely_constructed_message,
72 "Abstract Syntax Error - Falsely constructed message" },
73 { 0, NULL }
74};
75
76static struct msgb *sabp_msgb_alloc(void)
77{
78 return msgb_alloc_headroom(1024+512, 512, "SABP Tx");
79}
80
81static struct msgb *_sabp_gen_msg(SABP_SABP_PDU_t *pdu)
82{
83 struct msgb *msg = sabp_msgb_alloc();
84 asn_enc_rval_t rval;
85
86 if (!msg)
87 return NULL;
88
89 rval = aper_encode_to_buffer(&asn_DEF_SABP_SABP_PDU, pdu,
90 msg->data, msgb_tailroom(msg));
91 if (rval.encoded < 0) {
92 LOGP(DSABP, LOGL_ERROR, "Error encoding type: %s\n",
93 rval.failed_type->name);
94
95 }
96
97 msgb_put(msg, rval.encoded/8);
98
99 return msg;
100}
101
102struct msgb *sabp_generate_initiating_message(e_SABP_ProcedureCode procedureCode,
103 SABP_Criticality_t criticality,
104 asn_TYPE_descriptor_t *td, void *sptr)
105{
106 SABP_SABP_PDU_t pdu;
107 struct msgb *msg;
108 int rc;
109
110 memset(&pdu, 0, sizeof(pdu));
111
112 pdu.present = SABP_SABP_PDU_PR_initiatingMessage;
113 pdu.choice.initiatingMessage.procedureCode = procedureCode;
114 pdu.choice.initiatingMessage.criticality = criticality;
115 rc = ANY_fromType_aper(&pdu.choice.initiatingMessage.value, td, sptr);
116 if (rc < 0) {
117 LOGP(DSABP, LOGL_ERROR, "Error in ANY_fromType_aper\n");
118 return NULL;
119 }
120
121 msg = _sabp_gen_msg(&pdu);
122 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_SABP_SABP_PDU, &pdu);
123
124 return msg;
125}
126
127struct msgb *sabp_generate_successful_outcome(
128 e_SABP_ProcedureCode procedureCode,
129 SABP_Criticality_t criticality,
130 asn_TYPE_descriptor_t * td,
131 void *sptr)
132{
133 SABP_SABP_PDU_t pdu;
134 struct msgb *msg;
135 int rc;
136
137 memset(&pdu, 0, sizeof(pdu));
138
139 pdu.present = SABP_SABP_PDU_PR_successfulOutcome;
140 pdu.choice.successfulOutcome.procedureCode = procedureCode;
141 pdu.choice.successfulOutcome.criticality = criticality;
142 rc = ANY_fromType_aper(&pdu.choice.successfulOutcome.value, td, sptr);
143 if (rc < 0) {
144 LOGP(DSABP, LOGL_ERROR, "Error in ANY_fromType_aper\n");
145 return NULL;
146 }
147
148 msg = _sabp_gen_msg(&pdu);
149 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_SABP_SABP_PDU, &pdu);
150
151 return msg;
152}
153
154struct msgb *sabp_generate_unsuccessful_outcome(
155 e_SABP_ProcedureCode procedureCode,
156 SABP_Criticality_t criticality,
157 asn_TYPE_descriptor_t * td,
158 void *sptr)
159{
160 SABP_SABP_PDU_t pdu;
161 struct msgb *msg;
162 int rc;
163
164 memset(&pdu, 0, sizeof(pdu));
165
166 pdu.present = SABP_SABP_PDU_PR_unsuccessfulOutcome;
167 pdu.choice.unsuccessfulOutcome.procedureCode = procedureCode;
168 pdu.choice.unsuccessfulOutcome.criticality = criticality;
169 rc = ANY_fromType_aper(&pdu.choice.unsuccessfulOutcome.value, td, sptr);
170 if (rc < 0) {
171 LOGP(DSABP, LOGL_ERROR, "Error in ANY_fromType_aper\n");
172 return NULL;
173 }
174
175 msg = _sabp_gen_msg(&pdu);
176 ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_SABP_SABP_PDU, &pdu);
177
178 return msg;
179}
180
181SABP_IE_t *sabp_new_ie(SABP_ProtocolIE_ID_t id,
182 SABP_Criticality_t criticality,
183 asn_TYPE_descriptor_t * type, void *sptr)
184{
185 SABP_IE_t *buff;
186 int rc;
187
188 if ((buff = CALLOC(1, sizeof(*buff))) == NULL) {
189 // Possible error on malloc
190 return NULL;
191 }
192
193 buff->id = id;
194 buff->criticality = criticality;
195
196 rc = ANY_fromType_aper(&buff->value, type, sptr);
197 if (rc < 0) {
198 LOGP(DSABP, LOGL_ERROR, "Error in ANY_fromType_aper\n");
199 FREEMEM(buff);
200 return NULL;
201 }
202
203 if (asn1_xer_print)
204 if (xer_fprint(stdout, &asn_DEF_SABP_IE, buff) < 0) {
205 FREEMEM(buff);
206 return NULL;
207 }
208
209 return buff;
210}
211
212void sabp_set_log_area(int log_area)
213{
214 _sabp_DSABP = log_area;
215}