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 Q.SIG ROSE Call-Transfer-Operations (CT)
30  *
31  * Call-Transfer-Operations ECMA-178 Annex F Table F.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 Q.SIG CallTransferIdentify result 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_qsig_CallTransferIdentify_RES(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_result_args * args)58 unsigned char *rose_enc_qsig_CallTransferIdentify_RES(struct pri *ctrl,
59 	unsigned char *pos, unsigned char *end, const union rose_msg_result_args *args)
60 {
61 	unsigned char *seq_len;
62 	const struct roseQsigCTIdentifyRes_RES *call_transfer_identify;
63 
64 	call_transfer_identify = &args->qsig.CallTransferIdentify;
65 
66 	ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
67 
68 	ASN1_CALL(pos, asn1_enc_string_max(pos, end, ASN1_TYPE_NUMERIC_STRING,
69 		call_transfer_identify->call_id, sizeof(call_transfer_identify->call_id) - 1));
70 	ASN1_CALL(pos, rose_enc_PartyNumber(ctrl, pos, end,
71 		&call_transfer_identify->rerouting_number));
72 
73 	/* No extension to encode */
74 
75 	ASN1_CONSTRUCTED_END(seq_len, pos, end);
76 
77 	return pos;
78 }
79 
80 /*!
81  * \brief Encode the Q.SIG CallTransferInitiate invoke facility ie arguments.
82  *
83  * \param ctrl D channel controller for diagnostic messages or global options.
84  * \param pos Starting position to encode ASN.1 component.
85  * \param end End of ASN.1 encoding data buffer.
86  * \param args Arguments to encode in the buffer.
87  *
88  * \retval Start of the next ASN.1 component to encode on success.
89  * \retval NULL on error.
90  */
rose_enc_qsig_CallTransferInitiate_ARG(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_invoke_args * args)91 unsigned char *rose_enc_qsig_CallTransferInitiate_ARG(struct pri *ctrl,
92 	unsigned char *pos, unsigned char *end, const union rose_msg_invoke_args *args)
93 {
94 	unsigned char *seq_len;
95 	const struct roseQsigCTInitiateArg_ARG *call_transfer_initiate;
96 
97 	call_transfer_initiate = &args->qsig.CallTransferInitiate;
98 
99 	ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
100 
101 	ASN1_CALL(pos, asn1_enc_string_max(pos, end, ASN1_TYPE_NUMERIC_STRING,
102 		call_transfer_initiate->call_id, sizeof(call_transfer_initiate->call_id) - 1));
103 	ASN1_CALL(pos, rose_enc_PartyNumber(ctrl, pos, end,
104 		&call_transfer_initiate->rerouting_number));
105 
106 	/* No extension to encode */
107 
108 	ASN1_CONSTRUCTED_END(seq_len, pos, end);
109 
110 	return pos;
111 }
112 
113 /*!
114  * \brief Encode the Q.SIG CallTransferSetup invoke facility ie arguments.
115  *
116  * \param ctrl D channel controller for diagnostic messages or global options.
117  * \param pos Starting position to encode ASN.1 component.
118  * \param end End of ASN.1 encoding data buffer.
119  * \param args Arguments to encode in the buffer.
120  *
121  * \retval Start of the next ASN.1 component to encode on success.
122  * \retval NULL on error.
123  */
rose_enc_qsig_CallTransferSetup_ARG(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_invoke_args * args)124 unsigned char *rose_enc_qsig_CallTransferSetup_ARG(struct pri *ctrl, unsigned char *pos,
125 	unsigned char *end, const union rose_msg_invoke_args *args)
126 {
127 	unsigned char *seq_len;
128 	const struct roseQsigCTSetupArg_ARG *call_transfer_setup;
129 
130 	call_transfer_setup = &args->qsig.CallTransferSetup;
131 
132 	ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
133 
134 	ASN1_CALL(pos, asn1_enc_string_max(pos, end, ASN1_TYPE_NUMERIC_STRING,
135 		call_transfer_setup->call_id, sizeof(call_transfer_setup->call_id) - 1));
136 
137 	/* No extension to encode */
138 
139 	ASN1_CONSTRUCTED_END(seq_len, pos, end);
140 
141 	return pos;
142 }
143 
144 /*!
145  * \brief Encode the Q.SIG CallTransferActive invoke facility ie arguments.
146  *
147  * \param ctrl D channel controller for diagnostic messages or global options.
148  * \param pos Starting position to encode ASN.1 component.
149  * \param end End of ASN.1 encoding data buffer.
150  * \param args Arguments to encode in the buffer.
151  *
152  * \retval Start of the next ASN.1 component to encode on success.
153  * \retval NULL on error.
154  */
rose_enc_qsig_CallTransferActive_ARG(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_invoke_args * args)155 unsigned char *rose_enc_qsig_CallTransferActive_ARG(struct pri *ctrl, unsigned char *pos,
156 	unsigned char *end, const union rose_msg_invoke_args *args)
157 {
158 	unsigned char *seq_len;
159 	const struct roseQsigCTActiveArg_ARG *call_transfer_active;
160 
161 	call_transfer_active = &args->qsig.CallTransferActive;
162 
163 	ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
164 
165 	ASN1_CALL(pos, rose_enc_PresentedAddressScreened(ctrl, pos, end,
166 		&call_transfer_active->connected));
167 
168 	if (call_transfer_active->q931ie.length) {
169 		ASN1_CALL(pos, rose_enc_Q931ie(ctrl, pos, end, ASN1_CLASS_APPLICATION | 0,
170 			&call_transfer_active->q931ie));
171 	}
172 
173 	if (call_transfer_active->connected_name_present) {
174 		ASN1_CALL(pos, rose_enc_qsig_Name(ctrl, pos, end,
175 			&call_transfer_active->connected_name));
176 	}
177 
178 	/* No extension to encode */
179 
180 	ASN1_CONSTRUCTED_END(seq_len, pos, end);
181 
182 	return pos;
183 }
184 
185 /*!
186  * \brief Encode the Q.SIG CallTransferComplete invoke facility ie arguments.
187  *
188  * \param ctrl D channel controller for diagnostic messages or global options.
189  * \param pos Starting position to encode ASN.1 component.
190  * \param end End of ASN.1 encoding data buffer.
191  * \param args Arguments to encode in the buffer.
192  *
193  * \retval Start of the next ASN.1 component to encode on success.
194  * \retval NULL on error.
195  */
rose_enc_qsig_CallTransferComplete_ARG(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_invoke_args * args)196 unsigned char *rose_enc_qsig_CallTransferComplete_ARG(struct pri *ctrl,
197 	unsigned char *pos, unsigned char *end, const union rose_msg_invoke_args *args)
198 {
199 	unsigned char *seq_len;
200 	const struct roseQsigCTCompleteArg_ARG *call_transfer_complete;
201 
202 	call_transfer_complete = &args->qsig.CallTransferComplete;
203 
204 	ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
205 
206 	ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_ENUMERATED,
207 		call_transfer_complete->end_designation));
208 
209 	ASN1_CALL(pos, rose_enc_PresentedNumberScreened(ctrl, pos, end,
210 		&call_transfer_complete->redirection));
211 
212 	if (call_transfer_complete->q931ie.length) {
213 		ASN1_CALL(pos, rose_enc_Q931ie(ctrl, pos, end, ASN1_CLASS_APPLICATION | 0,
214 			&call_transfer_complete->q931ie));
215 	}
216 
217 	if (call_transfer_complete->redirection_name_present) {
218 		ASN1_CALL(pos, rose_enc_qsig_Name(ctrl, pos, end,
219 			&call_transfer_complete->redirection_name));
220 	}
221 
222 	if (call_transfer_complete->call_status) {
223 		/* Not the DEFAULT value */
224 		ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_ENUMERATED,
225 			call_transfer_complete->call_status));
226 	}
227 
228 	/* No extension to encode */
229 
230 	ASN1_CONSTRUCTED_END(seq_len, pos, end);
231 
232 	return pos;
233 }
234 
235 /*!
236  * \brief Encode the Q.SIG CallTransferUpdate invoke facility ie arguments.
237  *
238  * \param ctrl D channel controller for diagnostic messages or global options.
239  * \param pos Starting position to encode ASN.1 component.
240  * \param end End of ASN.1 encoding data buffer.
241  * \param args Arguments to encode in the buffer.
242  *
243  * \retval Start of the next ASN.1 component to encode on success.
244  * \retval NULL on error.
245  */
rose_enc_qsig_CallTransferUpdate_ARG(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_invoke_args * args)246 unsigned char *rose_enc_qsig_CallTransferUpdate_ARG(struct pri *ctrl, unsigned char *pos,
247 	unsigned char *end, const union rose_msg_invoke_args *args)
248 {
249 	unsigned char *seq_len;
250 	const struct roseQsigCTUpdateArg_ARG *call_transfer_update;
251 
252 	call_transfer_update = &args->qsig.CallTransferUpdate;
253 
254 	ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
255 
256 	ASN1_CALL(pos, rose_enc_PresentedNumberScreened(ctrl, pos, end,
257 		&call_transfer_update->redirection));
258 
259 	if (call_transfer_update->redirection_name_present) {
260 		ASN1_CALL(pos, rose_enc_qsig_Name(ctrl, pos, end,
261 			&call_transfer_update->redirection_name));
262 	}
263 
264 	if (call_transfer_update->q931ie.length) {
265 		ASN1_CALL(pos, rose_enc_Q931ie(ctrl, pos, end, ASN1_CLASS_APPLICATION | 0,
266 			&call_transfer_update->q931ie));
267 	}
268 
269 	/* No extension to encode */
270 
271 	ASN1_CONSTRUCTED_END(seq_len, pos, end);
272 
273 	return pos;
274 }
275 
276 /*!
277  * \brief Encode the Q.SIG SubaddressTransfer invoke facility ie arguments.
278  *
279  * \param ctrl D channel controller for diagnostic messages or global options.
280  * \param pos Starting position to encode ASN.1 component.
281  * \param end End of ASN.1 encoding data buffer.
282  * \param args Arguments to encode in the buffer.
283  *
284  * \retval Start of the next ASN.1 component to encode on success.
285  * \retval NULL on error.
286  */
rose_enc_qsig_SubaddressTransfer_ARG(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_invoke_args * args)287 unsigned char *rose_enc_qsig_SubaddressTransfer_ARG(struct pri *ctrl, unsigned char *pos,
288 	unsigned char *end, const union rose_msg_invoke_args *args)
289 {
290 	unsigned char *seq_len;
291 	const struct roseQsigSubaddressTransferArg_ARG *subaddress_transfer;
292 
293 	subaddress_transfer = &args->qsig.SubaddressTransfer;
294 
295 	ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
296 
297 	ASN1_CALL(pos, rose_enc_PartySubaddress(ctrl, pos, end,
298 		&subaddress_transfer->redirection_subaddress));
299 
300 	/* No extension to encode */
301 
302 	ASN1_CONSTRUCTED_END(seq_len, pos, end);
303 
304 	return pos;
305 }
306 
307 /*!
308  * \brief Encode the Q.SIG DummyArg invoke facility ie arguments.
309  *
310  * \param ctrl D channel controller for diagnostic messages or global options.
311  * \param pos Starting position to encode ASN.1 component.
312  * \param end End of ASN.1 encoding data buffer.
313  * \param args Arguments to encode in the buffer.
314  *
315  * \retval Start of the next ASN.1 component to encode on success.
316  * \retval NULL on error.
317  *
318  * \details
319  * DummyArg ::= CHOICE {
320  *     none                NULL,
321  *     extension           [1] IMPLICIT Extension,
322  *     multipleExtension   [2] IMPLICIT SEQUENCE OF Extension
323  * }
324  */
rose_enc_qsig_DummyArg_ARG(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_invoke_args * args)325 unsigned char *rose_enc_qsig_DummyArg_ARG(struct pri *ctrl, unsigned char *pos,
326 	unsigned char *end, const union rose_msg_invoke_args *args)
327 {
328 	return asn1_enc_null(pos, end, ASN1_TYPE_NULL);
329 }
330 
331 /*!
332  * \brief Encode the Q.SIG DummyRes result facility ie arguments.
333  *
334  * \param ctrl D channel controller for diagnostic messages or global options.
335  * \param pos Starting position to encode ASN.1 component.
336  * \param end End of ASN.1 encoding data buffer.
337  * \param args Arguments to encode in the buffer.
338  *
339  * \retval Start of the next ASN.1 component to encode on success.
340  * \retval NULL on error.
341  *
342  * \details
343  * DummyRes ::= CHOICE {
344  *     none                NULL,
345  *     extension           [1] IMPLICIT Extension,
346  *     multipleExtension   [2] IMPLICIT SEQUENCE OF Extension
347  * }
348  */
rose_enc_qsig_DummyRes_RES(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_result_args * args)349 unsigned char *rose_enc_qsig_DummyRes_RES(struct pri *ctrl, unsigned char *pos,
350 	unsigned char *end, const union rose_msg_result_args *args)
351 {
352 	return asn1_enc_null(pos, end, ASN1_TYPE_NULL);
353 }
354 
355 /*!
356  * \brief Decode the Q.SIG CallTransferIdentify result argument parameters.
357  *
358  * \param ctrl D channel controller for diagnostic messages or global options.
359  * \param tag Component tag that identified this structure.
360  * \param pos Starting position of the ASN.1 component length.
361  * \param end End of ASN.1 decoding data buffer.
362  * \param args Arguments to fill in from the decoded buffer.
363  *
364  * \retval Start of the next ASN.1 component on success.
365  * \retval NULL on error.
366  */
rose_dec_qsig_CallTransferIdentify_RES(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_result_args * args)367 const unsigned char *rose_dec_qsig_CallTransferIdentify_RES(struct pri *ctrl,
368 	unsigned tag, const unsigned char *pos, const unsigned char *end,
369 	union rose_msg_result_args *args)
370 {
371 	size_t str_len;
372 	int length;
373 	int seq_offset;
374 	const unsigned char *seq_end;
375 	struct roseQsigCTIdentifyRes_RES *call_transfer_identify;
376 
377 	call_transfer_identify = &args->qsig.CallTransferIdentify;
378 
379 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
380 	if (ctrl->debug & PRI_DEBUG_APDU) {
381 		pri_message(ctrl, "  CallTransferIdentify %s\n", asn1_tag2str(tag));
382 	}
383 	ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
384 	ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
385 
386 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
387 	ASN1_CHECK_TAG(ctrl, tag & ~ASN1_PC_MASK, tag, ASN1_TYPE_NUMERIC_STRING);
388 	ASN1_CALL(pos, asn1_dec_string_max(ctrl, "callIdentity", tag, pos, seq_end,
389 		sizeof(call_transfer_identify->call_id), call_transfer_identify->call_id,
390 		&str_len));
391 
392 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
393 	ASN1_CALL(pos, rose_dec_PartyNumber(ctrl, "reroutingNumber", tag, pos, seq_end,
394 		&call_transfer_identify->rerouting_number));
395 
396 	/* Fixup will skip over any OPTIONAL manufacturer extension information */
397 	ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
398 
399 	return pos;
400 }
401 
402 /*!
403  * \brief Decode the Q.SIG CallTransferInitiate invoke argument parameters.
404  *
405  * \param ctrl D channel controller for diagnostic messages or global options.
406  * \param tag Component tag that identified this structure.
407  * \param pos Starting position of the ASN.1 component length.
408  * \param end End of ASN.1 decoding data buffer.
409  * \param args Arguments to fill in from the decoded buffer.
410  *
411  * \retval Start of the next ASN.1 component on success.
412  * \retval NULL on error.
413  */
rose_dec_qsig_CallTransferInitiate_ARG(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_invoke_args * args)414 const unsigned char *rose_dec_qsig_CallTransferInitiate_ARG(struct pri *ctrl,
415 	unsigned tag, const unsigned char *pos, const unsigned char *end,
416 	union rose_msg_invoke_args *args)
417 {
418 	size_t str_len;
419 	int length;
420 	int seq_offset;
421 	const unsigned char *seq_end;
422 	struct roseQsigCTInitiateArg_ARG *call_transfer_initiate;
423 
424 	call_transfer_initiate = &args->qsig.CallTransferInitiate;
425 
426 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
427 	if (ctrl->debug & PRI_DEBUG_APDU) {
428 		pri_message(ctrl, "  CallTransferInitiate %s\n", asn1_tag2str(tag));
429 	}
430 	ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
431 	ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
432 
433 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
434 	ASN1_CHECK_TAG(ctrl, tag & ~ASN1_PC_MASK, tag, ASN1_TYPE_NUMERIC_STRING);
435 	ASN1_CALL(pos, asn1_dec_string_max(ctrl, "callIdentity", tag, pos, seq_end,
436 		sizeof(call_transfer_initiate->call_id), call_transfer_initiate->call_id,
437 		&str_len));
438 
439 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
440 	ASN1_CALL(pos, rose_dec_PartyNumber(ctrl, "reroutingNumber", tag, pos, seq_end,
441 		&call_transfer_initiate->rerouting_number));
442 
443 	/* Fixup will skip over any OPTIONAL manufacturer extension information */
444 	ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
445 
446 	return pos;
447 }
448 
449 /*!
450  * \brief Decode the Q.SIG CallTransferSetup invoke argument parameters.
451  *
452  * \param ctrl D channel controller for diagnostic messages or global options.
453  * \param tag Component tag that identified this structure.
454  * \param pos Starting position of the ASN.1 component length.
455  * \param end End of ASN.1 decoding data buffer.
456  * \param args Arguments to fill in from the decoded buffer.
457  *
458  * \retval Start of the next ASN.1 component on success.
459  * \retval NULL on error.
460  */
rose_dec_qsig_CallTransferSetup_ARG(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_invoke_args * args)461 const unsigned char *rose_dec_qsig_CallTransferSetup_ARG(struct pri *ctrl, unsigned tag,
462 	const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
463 {
464 	size_t str_len;
465 	int length;
466 	int seq_offset;
467 	const unsigned char *seq_end;
468 	struct roseQsigCTSetupArg_ARG *call_transfer_setup;
469 
470 	call_transfer_setup = &args->qsig.CallTransferSetup;
471 
472 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
473 	if (ctrl->debug & PRI_DEBUG_APDU) {
474 		pri_message(ctrl, "  CallTransferSetup %s\n", asn1_tag2str(tag));
475 	}
476 	ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
477 	ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
478 
479 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
480 	ASN1_CHECK_TAG(ctrl, tag & ~ASN1_PC_MASK, tag, ASN1_TYPE_NUMERIC_STRING);
481 	ASN1_CALL(pos, asn1_dec_string_max(ctrl, "callIdentity", tag, pos, seq_end,
482 		sizeof(call_transfer_setup->call_id), call_transfer_setup->call_id, &str_len));
483 
484 	/* Fixup will skip over any OPTIONAL manufacturer extension information */
485 	ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
486 
487 	return pos;
488 }
489 
490 /*!
491  * \brief Decode the Q.SIG CallTransferActive invoke argument parameters.
492  *
493  * \param ctrl D channel controller for diagnostic messages or global options.
494  * \param tag Component tag that identified this structure.
495  * \param pos Starting position of the ASN.1 component length.
496  * \param end End of ASN.1 decoding data buffer.
497  * \param args Arguments to fill in from the decoded buffer.
498  *
499  * \retval Start of the next ASN.1 component on success.
500  * \retval NULL on error.
501  */
rose_dec_qsig_CallTransferActive_ARG(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_invoke_args * args)502 const unsigned char *rose_dec_qsig_CallTransferActive_ARG(struct pri *ctrl, unsigned tag,
503 	const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
504 {
505 	int length;
506 	int seq_offset;
507 	const unsigned char *seq_end;
508 	const unsigned char *save_pos;
509 	struct roseQsigCTActiveArg_ARG *call_transfer_active;
510 
511 	call_transfer_active = &args->qsig.CallTransferActive;
512 
513 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
514 	if (ctrl->debug & PRI_DEBUG_APDU) {
515 		pri_message(ctrl, "  CallTransferActive %s\n", asn1_tag2str(tag));
516 	}
517 	ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
518 	ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
519 
520 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
521 	ASN1_CALL(pos, rose_dec_PresentedAddressScreened(ctrl, "connectedAddress", tag, pos,
522 		seq_end, &call_transfer_active->connected));
523 
524 	/*
525 	 * A sequence specifies an ordered list of component types.
526 	 * However, for simplicity we are not checking the order of
527 	 * the remaining optional components.
528 	 */
529 	call_transfer_active->q931ie.length = 0;
530 	call_transfer_active->connected_name_present = 0;
531 	while (pos < seq_end && *pos != ASN1_INDEF_TERM) {
532 		save_pos = pos;
533 		ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
534 		switch (tag & ~ASN1_PC_MASK) {
535 		case ASN1_CLASS_APPLICATION | 0:
536 			ASN1_CALL(pos, rose_dec_Q931ie(ctrl, "basicCallInfoElements", tag, pos,
537 				seq_end, &call_transfer_active->q931ie,
538 				sizeof(call_transfer_active->q931ie_contents)));
539 			break;
540 		case ASN1_CLASS_CONTEXT_SPECIFIC | 0:
541 		case ASN1_CLASS_CONTEXT_SPECIFIC | 1:
542 		case ASN1_CLASS_CONTEXT_SPECIFIC | 2:
543 		case ASN1_CLASS_CONTEXT_SPECIFIC | 3:
544 		case ASN1_CLASS_CONTEXT_SPECIFIC | 4:
545 		case ASN1_CLASS_CONTEXT_SPECIFIC | 7:
546 			ASN1_CALL(pos, rose_dec_qsig_Name(ctrl, "connectedName", tag, pos, seq_end,
547 				&call_transfer_active->connected_name));
548 			call_transfer_active->connected_name_present = 1;
549 			break;
550 		case ASN1_CLASS_CONTEXT_SPECIFIC | 9:
551 		case ASN1_CLASS_CONTEXT_SPECIFIC | 10:
552 			if (ctrl->debug & PRI_DEBUG_APDU) {
553 				pri_message(ctrl, "  argumentExtension %s\n", asn1_tag2str(tag));
554 			}
555 			/* Fixup will skip over the manufacturer extension information */
556 		default:
557 			pos = save_pos;
558 			goto cancel_options;
559 		}
560 	}
561 cancel_options:;
562 
563 	ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
564 
565 	return pos;
566 }
567 
568 /*!
569  * \brief Decode the Q.SIG CallTransferComplete invoke argument parameters.
570  *
571  * \param ctrl D channel controller for diagnostic messages or global options.
572  * \param tag Component tag that identified this structure.
573  * \param pos Starting position of the ASN.1 component length.
574  * \param end End of ASN.1 decoding data buffer.
575  * \param args Arguments to fill in from the decoded buffer.
576  *
577  * \retval Start of the next ASN.1 component on success.
578  * \retval NULL on error.
579  */
rose_dec_qsig_CallTransferComplete_ARG(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_invoke_args * args)580 const unsigned char *rose_dec_qsig_CallTransferComplete_ARG(struct pri *ctrl,
581 	unsigned tag, const unsigned char *pos, const unsigned char *end,
582 	union rose_msg_invoke_args *args)
583 {
584 	int32_t value;
585 	int length;
586 	int seq_offset;
587 	const unsigned char *seq_end;
588 	const unsigned char *save_pos;
589 	struct roseQsigCTCompleteArg_ARG *call_transfer_complete;
590 
591 	call_transfer_complete = &args->qsig.CallTransferComplete;
592 
593 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
594 	if (ctrl->debug & PRI_DEBUG_APDU) {
595 		pri_message(ctrl, "  CallTransferComplete %s\n", asn1_tag2str(tag));
596 	}
597 	ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
598 	ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
599 
600 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
601 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_ENUMERATED);
602 	ASN1_CALL(pos, asn1_dec_int(ctrl, "endDesignation", tag, pos, seq_end, &value));
603 	call_transfer_complete->end_designation = value;
604 
605 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
606 	ASN1_CALL(pos, rose_dec_PresentedNumberScreened(ctrl, "redirectionNumber", tag, pos,
607 		seq_end, &call_transfer_complete->redirection));
608 
609 	/*
610 	 * A sequence specifies an ordered list of component types.
611 	 * However, for simplicity we are not checking the order of
612 	 * the remaining optional components.
613 	 */
614 	call_transfer_complete->q931ie.length = 0;
615 	call_transfer_complete->redirection_name_present = 0;
616 	call_transfer_complete->call_status = 0;	/* DEFAULT answered */
617 	while (pos < seq_end && *pos != ASN1_INDEF_TERM) {
618 		save_pos = pos;
619 		ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
620 		switch (tag & ~ASN1_PC_MASK) {
621 		case ASN1_CLASS_APPLICATION | 0:
622 			ASN1_CALL(pos, rose_dec_Q931ie(ctrl, "basicCallInfoElements", tag, pos,
623 				seq_end, &call_transfer_complete->q931ie,
624 				sizeof(call_transfer_complete->q931ie_contents)));
625 			break;
626 		case ASN1_CLASS_CONTEXT_SPECIFIC | 0:
627 		case ASN1_CLASS_CONTEXT_SPECIFIC | 1:
628 		case ASN1_CLASS_CONTEXT_SPECIFIC | 2:
629 		case ASN1_CLASS_CONTEXT_SPECIFIC | 3:
630 		case ASN1_CLASS_CONTEXT_SPECIFIC | 4:
631 		case ASN1_CLASS_CONTEXT_SPECIFIC | 7:
632 			ASN1_CALL(pos, rose_dec_qsig_Name(ctrl, "redirectionName", tag, pos, seq_end,
633 				&call_transfer_complete->redirection_name));
634 			call_transfer_complete->redirection_name_present = 1;
635 			break;
636 		case ASN1_TYPE_ENUMERATED:
637 			/* Must not be constructed but we will not check for it for simplicity. */
638 			ASN1_CALL(pos, asn1_dec_int(ctrl, "callStatus", tag, pos, seq_end, &value));
639 			call_transfer_complete->call_status = value;
640 			break;
641 		case ASN1_CLASS_CONTEXT_SPECIFIC | 9:
642 		case ASN1_CLASS_CONTEXT_SPECIFIC | 10:
643 			if (ctrl->debug & PRI_DEBUG_APDU) {
644 				pri_message(ctrl, "  argumentExtension %s\n", asn1_tag2str(tag));
645 			}
646 			/* Fixup will skip over the manufacturer extension information */
647 		default:
648 			pos = save_pos;
649 			goto cancel_options;
650 		}
651 	}
652 cancel_options:;
653 
654 	ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
655 
656 	return pos;
657 }
658 
659 /*!
660  * \brief Decode the Q.SIG CallTransferUpdate invoke argument parameters.
661  *
662  * \param ctrl D channel controller for diagnostic messages or global options.
663  * \param tag Component tag that identified this structure.
664  * \param pos Starting position of the ASN.1 component length.
665  * \param end End of ASN.1 decoding data buffer.
666  * \param args Arguments to fill in from the decoded buffer.
667  *
668  * \retval Start of the next ASN.1 component on success.
669  * \retval NULL on error.
670  */
rose_dec_qsig_CallTransferUpdate_ARG(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_invoke_args * args)671 const unsigned char *rose_dec_qsig_CallTransferUpdate_ARG(struct pri *ctrl, unsigned tag,
672 	const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
673 {
674 	int length;
675 	int seq_offset;
676 	const unsigned char *seq_end;
677 	const unsigned char *save_pos;
678 	struct roseQsigCTUpdateArg_ARG *call_transfer_update;
679 
680 	call_transfer_update = &args->qsig.CallTransferUpdate;
681 
682 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
683 	if (ctrl->debug & PRI_DEBUG_APDU) {
684 		pri_message(ctrl, "  CallTransferUpdate %s\n", asn1_tag2str(tag));
685 	}
686 	ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
687 	ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
688 
689 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
690 	ASN1_CALL(pos, rose_dec_PresentedNumberScreened(ctrl, "redirectionNumber", tag, pos,
691 		seq_end, &call_transfer_update->redirection));
692 
693 	/*
694 	 * A sequence specifies an ordered list of component types.
695 	 * However, for simplicity we are not checking the order of
696 	 * the remaining optional components.
697 	 */
698 	call_transfer_update->redirection_name_present = 0;
699 	call_transfer_update->q931ie.length = 0;
700 	while (pos < seq_end && *pos != ASN1_INDEF_TERM) {
701 		save_pos = pos;
702 		ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
703 		switch (tag & ~ASN1_PC_MASK) {
704 		case ASN1_CLASS_CONTEXT_SPECIFIC | 0:
705 		case ASN1_CLASS_CONTEXT_SPECIFIC | 1:
706 		case ASN1_CLASS_CONTEXT_SPECIFIC | 2:
707 		case ASN1_CLASS_CONTEXT_SPECIFIC | 3:
708 		case ASN1_CLASS_CONTEXT_SPECIFIC | 4:
709 		case ASN1_CLASS_CONTEXT_SPECIFIC | 7:
710 			ASN1_CALL(pos, rose_dec_qsig_Name(ctrl, "redirectionName", tag, pos, seq_end,
711 				&call_transfer_update->redirection_name));
712 			call_transfer_update->redirection_name_present = 1;
713 			break;
714 		case ASN1_CLASS_APPLICATION | 0:
715 			ASN1_CALL(pos, rose_dec_Q931ie(ctrl, "basicCallInfoElements", tag, pos,
716 				seq_end, &call_transfer_update->q931ie,
717 				sizeof(call_transfer_update->q931ie_contents)));
718 			break;
719 		case ASN1_CLASS_CONTEXT_SPECIFIC | 9:
720 		case ASN1_CLASS_CONTEXT_SPECIFIC | 10:
721 			if (ctrl->debug & PRI_DEBUG_APDU) {
722 				pri_message(ctrl, "  argumentExtension %s\n", asn1_tag2str(tag));
723 			}
724 			/* Fixup will skip over the manufacturer extension information */
725 		default:
726 			pos = save_pos;
727 			goto cancel_options;
728 		}
729 	}
730 cancel_options:;
731 
732 	ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
733 
734 	return pos;
735 }
736 
737 /*!
738  * \brief Decode the Q.SIG SubaddressTransfer invoke argument parameters.
739  *
740  * \param ctrl D channel controller for diagnostic messages or global options.
741  * \param tag Component tag that identified this structure.
742  * \param pos Starting position of the ASN.1 component length.
743  * \param end End of ASN.1 decoding data buffer.
744  * \param args Arguments to fill in from the decoded buffer.
745  *
746  * \retval Start of the next ASN.1 component on success.
747  * \retval NULL on error.
748  */
rose_dec_qsig_SubaddressTransfer_ARG(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_invoke_args * args)749 const unsigned char *rose_dec_qsig_SubaddressTransfer_ARG(struct pri *ctrl, unsigned tag,
750 	const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
751 {
752 	int length;
753 	int seq_offset;
754 	const unsigned char *seq_end;
755 	struct roseQsigSubaddressTransferArg_ARG *subaddress_transfer;
756 
757 	subaddress_transfer = &args->qsig.SubaddressTransfer;
758 
759 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
760 	if (ctrl->debug & PRI_DEBUG_APDU) {
761 		pri_message(ctrl, "  SubaddressTransfer %s\n", asn1_tag2str(tag));
762 	}
763 	ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
764 	ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
765 
766 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
767 	ASN1_CALL(pos, rose_dec_PartySubaddress(ctrl, "redirectionSubaddress", tag, pos,
768 		seq_end, &subaddress_transfer->redirection_subaddress));
769 
770 	/* Fixup will skip over any OPTIONAL manufacturer extension information */
771 	ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
772 
773 	return pos;
774 }
775 
776 /*!
777  * \brief Decode the Q.SIG DummyArg invoke argument parameters.
778  *
779  * \param ctrl D channel controller for diagnostic messages or global options.
780  * \param tag Component tag that identified this structure.
781  * \param pos Starting position of the ASN.1 component length.
782  * \param end End of ASN.1 decoding data buffer.
783  * \param args Arguments to fill in from the decoded buffer.
784  *
785  * \retval Start of the next ASN.1 component on success.
786  * \retval NULL on error.
787  *
788  * \details
789  * DummyArg ::= CHOICE {
790  *     none                NULL,
791  *     extension           [1] IMPLICIT Extension,
792  *     multipleExtension   [2] IMPLICIT SEQUENCE OF Extension
793  * }
794  */
rose_dec_qsig_DummyArg_ARG(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_invoke_args * args)795 const unsigned char *rose_dec_qsig_DummyArg_ARG(struct pri *ctrl, unsigned tag,
796 	const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
797 {
798 	const char *name;
799 	int length;
800 	int seq_offset;
801 	const unsigned char *seq_end;
802 
803 	switch (tag) {
804 	case ASN1_TYPE_NULL:
805 		return asn1_dec_null(ctrl, "none", tag, pos, end);
806 	case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 1:
807 		name = "extension Extension";
808 		break;
809 	case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 2:
810 		name = "multipleExtension SEQUENCE OF Extension";
811 		break;
812 	default:
813 		ASN1_DID_NOT_EXPECT_TAG(ctrl, tag);
814 		return NULL;
815 	}
816 
817 	if (ctrl->debug & PRI_DEBUG_APDU) {
818 		pri_message(ctrl, "  %s %s\n", name, asn1_tag2str(tag));
819 	}
820 	ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
821 	ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
822 
823 	/* Fixup will skip over the manufacturer extension information */
824 	ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
825 
826 	return pos;
827 }
828 
829 /*!
830  * \brief Decode the Q.SIG DummyRes result argument parameters.
831  *
832  * \param ctrl D channel controller for diagnostic messages or global options.
833  * \param tag Component tag that identified this structure.
834  * \param pos Starting position of the ASN.1 component length.
835  * \param end End of ASN.1 decoding data buffer.
836  * \param args Arguments to fill in from the decoded buffer.
837  *
838  * \retval Start of the next ASN.1 component on success.
839  * \retval NULL on error.
840  *
841  * \details
842  * DummyRes ::= CHOICE {
843  *     none                NULL,
844  *     extension           [1] IMPLICIT Extension,
845  *     multipleExtension   [2] IMPLICIT SEQUENCE OF Extension
846  * }
847  */
rose_dec_qsig_DummyRes_RES(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_result_args * args)848 const unsigned char *rose_dec_qsig_DummyRes_RES(struct pri *ctrl, unsigned tag,
849 	const unsigned char *pos, const unsigned char *end, union rose_msg_result_args *args)
850 {
851 	const char *name;
852 	int length;
853 	int seq_offset;
854 	const unsigned char *seq_end;
855 
856 	switch (tag) {
857 	case ASN1_TYPE_NULL:
858 		return asn1_dec_null(ctrl, "none", tag, pos, end);
859 	case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 1:
860 		name = "extension Extension";
861 		break;
862 	case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 2:
863 		name = "multipleExtension SEQUENCE OF Extension";
864 		break;
865 	default:
866 		ASN1_DID_NOT_EXPECT_TAG(ctrl, tag);
867 		return NULL;
868 	}
869 
870 	if (ctrl->debug & PRI_DEBUG_APDU) {
871 		pri_message(ctrl, "  %s %s\n", name, asn1_tag2str(tag));
872 	}
873 	ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
874 	ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
875 
876 	/* Fixup will skip over the manufacturer extension information */
877 	ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
878 
879 	return pos;
880 }
881 
882 /* ------------------------------------------------------------------- */
883 /* end rose_qsig_ct.c */
884