1 /*
2  * libpri: An implementation of Primary Rate ISDN
3  *
4  * Copyright (C) 2009 Digium, Inc.
5  *
6  * Richard Mudgett <rmudgett@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2 as published by the
16  * Free Software Foundation. See the LICENSE file included with
17  * this program for more details.
18  *
19  * In addition, when this program is distributed with Asterisk in
20  * any form that would qualify as a 'combined work' or as a
21  * 'derivative work' (but not mere aggregation), you can redistribute
22  * and/or modify the combination under the terms of the license
23  * provided with that copy of Asterisk, instead of the license
24  * terms granted here.
25  */
26 
27 /*!
28  * \file
29  * \brief ROSE Explicit Call Transfer operations.
30  *
31  * Explicit Call Transfer (ECT) Supplementary Services ETS 300 369-1
32  *
33  * \author Richard Mudgett <rmudgett@digium.com>
34  */
35 
36 
37 #include "compat.h"
38 #include "libpri.h"
39 #include "pri_internal.h"
40 #include "rose.h"
41 #include "rose_internal.h"
42 #include "asn1.h"
43 
44 
45 /* ------------------------------------------------------------------- */
46 
47 /*!
48  * \brief Encode the ExplicitEctExecute invoke facility ie arguments.
49  *
50  * \param ctrl D channel controller for diagnostic messages or global options.
51  * \param pos Starting position to encode ASN.1 component.
52  * \param end End of ASN.1 encoding data buffer.
53  * \param args Arguments to encode in the buffer.
54  *
55  * \retval Start of the next ASN.1 component to encode on success.
56  * \retval NULL on error.
57  */
rose_enc_etsi_ExplicitEctExecute_ARG(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_invoke_args * args)58 unsigned char *rose_enc_etsi_ExplicitEctExecute_ARG(struct pri *ctrl, unsigned char *pos,
59 	unsigned char *end, const union rose_msg_invoke_args *args)
60 {
61 	return asn1_enc_int(pos, end, ASN1_TYPE_INTEGER,
62 		args->etsi.ExplicitEctExecute.link_id);
63 }
64 
65 /*!
66  * \brief Encode the SubaddressTransfer invoke facility ie arguments.
67  *
68  * \param ctrl D channel controller for diagnostic messages or global options.
69  * \param pos Starting position to encode ASN.1 component.
70  * \param end End of ASN.1 encoding data buffer.
71  * \param args Arguments to encode in the buffer.
72  *
73  * \retval Start of the next ASN.1 component to encode on success.
74  * \retval NULL on error.
75  */
rose_enc_etsi_SubaddressTransfer_ARG(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_invoke_args * args)76 unsigned char *rose_enc_etsi_SubaddressTransfer_ARG(struct pri *ctrl, unsigned char *pos,
77 	unsigned char *end, const union rose_msg_invoke_args *args)
78 {
79 	return rose_enc_PartySubaddress(ctrl, pos, end,
80 		&args->etsi.SubaddressTransfer.subaddress);
81 }
82 
83 /*!
84  * \brief Encode the EctLinkIdRequest result facility ie arguments.
85  *
86  * \param ctrl D channel controller for diagnostic messages or global options.
87  * \param pos Starting position to encode ASN.1 component.
88  * \param end End of ASN.1 encoding data buffer.
89  * \param args Arguments to encode in the buffer.
90  *
91  * \retval Start of the next ASN.1 component to encode on success.
92  * \retval NULL on error.
93  */
rose_enc_etsi_EctLinkIdRequest_RES(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_result_args * args)94 unsigned char *rose_enc_etsi_EctLinkIdRequest_RES(struct pri *ctrl, unsigned char *pos,
95 	unsigned char *end, const union rose_msg_result_args *args)
96 {
97 	return asn1_enc_int(pos, end, ASN1_TYPE_INTEGER,
98 		args->etsi.EctLinkIdRequest.link_id);
99 }
100 
101 /*!
102  * \brief Encode the EctInform invoke facility ie arguments.
103  *
104  * \param ctrl D channel controller for diagnostic messages or global options.
105  * \param pos Starting position to encode ASN.1 component.
106  * \param end End of ASN.1 encoding data buffer.
107  * \param args Arguments to encode in the buffer.
108  *
109  * \retval Start of the next ASN.1 component to encode on success.
110  * \retval NULL on error.
111  */
rose_enc_etsi_EctInform_ARG(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_invoke_args * args)112 unsigned char *rose_enc_etsi_EctInform_ARG(struct pri *ctrl, unsigned char *pos,
113 	unsigned char *end, const union rose_msg_invoke_args *args)
114 {
115 	const struct roseEtsiEctInform_ARG *ect_inform;
116 	unsigned char *seq_len;
117 
118 	ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
119 
120 	ect_inform = &args->etsi.EctInform;
121 	ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_ENUMERATED, ect_inform->status));
122 	if (ect_inform->redirection_present) {
123 		ASN1_CALL(pos, rose_enc_PresentedNumberUnscreened(ctrl, pos, end,
124 			&ect_inform->redirection));
125 	}
126 
127 	ASN1_CONSTRUCTED_END(seq_len, pos, end);
128 
129 	return pos;
130 }
131 
132 /*!
133  * \brief Encode the EctLoopTest invoke facility ie arguments.
134  *
135  * \param ctrl D channel controller for diagnostic messages or global options.
136  * \param pos Starting position to encode ASN.1 component.
137  * \param end End of ASN.1 encoding data buffer.
138  * \param args Arguments to encode in the buffer.
139  *
140  * \retval Start of the next ASN.1 component to encode on success.
141  * \retval NULL on error.
142  */
rose_enc_etsi_EctLoopTest_ARG(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_invoke_args * args)143 unsigned char *rose_enc_etsi_EctLoopTest_ARG(struct pri *ctrl, unsigned char *pos,
144 	unsigned char *end, const union rose_msg_invoke_args *args)
145 {
146 	return asn1_enc_int(pos, end, ASN1_TYPE_INTEGER,
147 		args->etsi.EctLoopTest.call_transfer_id);
148 }
149 
150 /*!
151  * \brief Encode the EctLoopTest result facility ie arguments.
152  *
153  * \param ctrl D channel controller for diagnostic messages or global options.
154  * \param pos Starting position to encode ASN.1 component.
155  * \param end End of ASN.1 encoding data buffer.
156  * \param args Arguments to encode in the buffer.
157  *
158  * \retval Start of the next ASN.1 component to encode on success.
159  * \retval NULL on error.
160  */
rose_enc_etsi_EctLoopTest_RES(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_result_args * args)161 unsigned char *rose_enc_etsi_EctLoopTest_RES(struct pri *ctrl, unsigned char *pos,
162 	unsigned char *end, const union rose_msg_result_args *args)
163 {
164 	return asn1_enc_int(pos, end, ASN1_TYPE_ENUMERATED,
165 		args->etsi.EctLoopTest.loop_result);
166 }
167 
168 /*!
169  * \brief Decode the ExplicitEctExecute invoke argument parameters.
170  *
171  * \param ctrl D channel controller for diagnostic messages or global options.
172  * \param tag Component tag that identified this structure.
173  * \param pos Starting position of the ASN.1 component length.
174  * \param end End of ASN.1 decoding data buffer.
175  * \param args Arguments to fill in from the decoded buffer.
176  *
177  * \retval Start of the next ASN.1 component on success.
178  * \retval NULL on error.
179  */
rose_dec_etsi_ExplicitEctExecute_ARG(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_invoke_args * args)180 const unsigned char *rose_dec_etsi_ExplicitEctExecute_ARG(struct pri *ctrl, unsigned tag,
181 	const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
182 {
183 	int32_t value;
184 
185 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_INTEGER);
186 	ASN1_CALL(pos, asn1_dec_int(ctrl, "linkId", tag, pos, end, &value));
187 	args->etsi.ExplicitEctExecute.link_id = value;
188 
189 	return pos;
190 }
191 
192 /*!
193  * \brief Decode the SubaddressTransfer invoke argument parameters.
194  *
195  * \param ctrl D channel controller for diagnostic messages or global options.
196  * \param tag Component tag that identified this structure.
197  * \param pos Starting position of the ASN.1 component length.
198  * \param end End of ASN.1 decoding data buffer.
199  * \param args Arguments to fill in from the decoded buffer.
200  *
201  * \retval Start of the next ASN.1 component on success.
202  * \retval NULL on error.
203  */
rose_dec_etsi_SubaddressTransfer_ARG(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_invoke_args * args)204 const unsigned char *rose_dec_etsi_SubaddressTransfer_ARG(struct pri *ctrl, unsigned tag,
205 	const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
206 {
207 	return rose_dec_PartySubaddress(ctrl, "transferredToSubaddress", tag, pos, end,
208 		&args->etsi.SubaddressTransfer.subaddress);
209 }
210 
211 /*!
212  * \brief Decode the EctLinkIdRequest result argument parameters.
213  *
214  * \param ctrl D channel controller for diagnostic messages or global options.
215  * \param tag Component tag that identified this structure.
216  * \param pos Starting position of the ASN.1 component length.
217  * \param end End of ASN.1 decoding data buffer.
218  * \param args Arguments to fill in from the decoded buffer.
219  *
220  * \retval Start of the next ASN.1 component on success.
221  * \retval NULL on error.
222  */
rose_dec_etsi_EctLinkIdRequest_RES(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_result_args * args)223 const unsigned char *rose_dec_etsi_EctLinkIdRequest_RES(struct pri *ctrl, unsigned tag,
224 	const unsigned char *pos, const unsigned char *end, union rose_msg_result_args *args)
225 {
226 	int32_t value;
227 
228 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_INTEGER);
229 	ASN1_CALL(pos, asn1_dec_int(ctrl, "linkId", tag, pos, end, &value));
230 	args->etsi.EctLinkIdRequest.link_id = value;
231 
232 	return pos;
233 }
234 
235 /*!
236  * \brief Decode the EctInform invoke argument parameters.
237  *
238  * \param ctrl D channel controller for diagnostic messages or global options.
239  * \param tag Component tag that identified this structure.
240  * \param pos Starting position of the ASN.1 component length.
241  * \param end End of ASN.1 decoding data buffer.
242  * \param args Arguments to fill in from the decoded buffer.
243  *
244  * \retval Start of the next ASN.1 component on success.
245  * \retval NULL on error.
246  */
rose_dec_etsi_EctInform_ARG(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_invoke_args * args)247 const unsigned char *rose_dec_etsi_EctInform_ARG(struct pri *ctrl, unsigned tag,
248 	const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
249 {
250 	struct roseEtsiEctInform_ARG *ect_inform;
251 	int length;
252 	int seq_offset;
253 	const unsigned char *seq_end;
254 	int32_t value;
255 
256 	if (ctrl->debug & PRI_DEBUG_APDU) {
257 		pri_message(ctrl, "  EctInform %s\n", asn1_tag2str(tag));
258 	}
259 	ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
260 	ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
261 
262 	ect_inform = &args->etsi.EctInform;
263 
264 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
265 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_ENUMERATED);
266 	ASN1_CALL(pos, asn1_dec_int(ctrl, "callStatus", tag, pos, seq_end, &value));
267 	ect_inform->status = value;
268 
269 	if (pos < seq_end && *pos != ASN1_INDEF_TERM) {
270 		ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
271 		ASN1_CALL(pos, rose_dec_PresentedNumberUnscreened(ctrl, "redirectionNumber", tag,
272 			pos, seq_end, &ect_inform->redirection));
273 		ect_inform->redirection_present = 1;
274 	} else {
275 		ect_inform->redirection_present = 0;
276 	}
277 
278 	ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
279 
280 	return pos;
281 }
282 
283 /*!
284  * \brief Decode the EctLoopTest invoke argument parameters.
285  *
286  * \param ctrl D channel controller for diagnostic messages or global options.
287  * \param tag Component tag that identified this structure.
288  * \param pos Starting position of the ASN.1 component length.
289  * \param end End of ASN.1 decoding data buffer.
290  * \param args Arguments to fill in from the decoded buffer.
291  *
292  * \retval Start of the next ASN.1 component on success.
293  * \retval NULL on error.
294  */
rose_dec_etsi_EctLoopTest_ARG(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_invoke_args * args)295 const unsigned char *rose_dec_etsi_EctLoopTest_ARG(struct pri *ctrl, unsigned tag,
296 	const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
297 {
298 	int32_t value;
299 
300 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_INTEGER);
301 	ASN1_CALL(pos, asn1_dec_int(ctrl, "callTransferId", tag, pos, end, &value));
302 	args->etsi.EctLoopTest.call_transfer_id = value;
303 
304 	return pos;
305 }
306 
307 /*!
308  * \brief Decode the EctLoopTest result argument parameters.
309  *
310  * \param ctrl D channel controller for diagnostic messages or global options.
311  * \param tag Component tag that identified this structure.
312  * \param pos Starting position of the ASN.1 component length.
313  * \param end End of ASN.1 decoding data buffer.
314  * \param args Arguments to fill in from the decoded buffer.
315  *
316  * \retval Start of the next ASN.1 component on success.
317  * \retval NULL on error.
318  */
rose_dec_etsi_EctLoopTest_RES(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_result_args * args)319 const unsigned char *rose_dec_etsi_EctLoopTest_RES(struct pri *ctrl, unsigned tag,
320 	const unsigned char *pos, const unsigned char *end, union rose_msg_result_args *args)
321 {
322 	int32_t value;
323 
324 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_ENUMERATED);
325 	ASN1_CALL(pos, asn1_dec_int(ctrl, "loopResult", tag, pos, end, &value));
326 	args->etsi.EctLoopTest.loop_result = value;
327 
328 	return pos;
329 }
330 
331 /* ------------------------------------------------------------------- */
332 /* end rose_etsi_ect.c */
333