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