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 Advice-Of-Charge (AOC) operations
30  *
31  * SS-AOC-Operations ECMA-212 Annex E Table E.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  * \internal
49  * \brief Encode the Time type.
50  *
51  * \param ctrl D channel controller for diagnostic messages or global options.
52  * \param pos Starting position to encode ASN.1 component.
53  * \param end End of ASN.1 encoding data buffer.
54  * \param tag Component tag to identify the encoded component.
55  *   The tag should be ASN1_TAG_SEQUENCE unless the caller implicitly
56  *   tags it otherwise.
57  * \param time Time information to encode.
58  *
59  * \retval Start of the next ASN.1 component to encode on success.
60  * \retval NULL on error.
61  */
rose_enc_qsig_AOC_Time(struct pri * ctrl,unsigned char * pos,unsigned char * end,unsigned tag,const struct roseQsigAOCTime * time)62 static unsigned char *rose_enc_qsig_AOC_Time(struct pri *ctrl, unsigned char *pos,
63 	unsigned char *end, unsigned tag, const struct roseQsigAOCTime *time)
64 {
65 	unsigned char *seq_len;
66 
67 	ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, tag);
68 
69 	ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 1,
70 		time->length));
71 	ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 2, time->scale));
72 
73 	ASN1_CONSTRUCTED_END(seq_len, pos, end);
74 
75 	return pos;
76 }
77 
78 /*!
79  * \internal
80  * \brief Encode the Amount type.
81  *
82  * \param ctrl D channel controller for diagnostic messages or global options.
83  * \param pos Starting position to encode ASN.1 component.
84  * \param end End of ASN.1 encoding data buffer.
85  * \param tag Component tag to identify the encoded component.
86  *   The tag should be ASN1_TAG_SEQUENCE unless the caller implicitly
87  *   tags it otherwise.
88  * \param amount Amount information to encode.
89  *
90  * \retval Start of the next ASN.1 component to encode on success.
91  * \retval NULL on error.
92  */
rose_enc_qsig_AOC_Amount(struct pri * ctrl,unsigned char * pos,unsigned char * end,unsigned tag,const struct roseQsigAOCAmount * amount)93 static unsigned char *rose_enc_qsig_AOC_Amount(struct pri *ctrl, unsigned char *pos,
94 	unsigned char *end, unsigned tag, const struct roseQsigAOCAmount *amount)
95 {
96 	unsigned char *seq_len;
97 
98 	ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, tag);
99 
100 	ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 1,
101 		amount->currency));
102 	ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 2,
103 		amount->multiplier));
104 
105 	ASN1_CONSTRUCTED_END(seq_len, pos, end);
106 
107 	return pos;
108 }
109 
110 /*!
111  * \internal
112  * \brief Encode the RecordedCurrency type.
113  *
114  * \param ctrl D channel controller for diagnostic messages or global options.
115  * \param pos Starting position to encode ASN.1 component.
116  * \param end End of ASN.1 encoding data buffer.
117  * \param tag Component tag to identify the encoded component.
118  *   The tag should be ASN1_TAG_SEQUENCE unless the caller implicitly
119  *   tags it otherwise.
120  * \param recorded Recorded currency information to encode.
121  *
122  * \retval Start of the next ASN.1 component to encode on success.
123  * \retval NULL on error.
124  */
rose_enc_qsig_AOC_RecordedCurrency(struct pri * ctrl,unsigned char * pos,unsigned char * end,unsigned tag,const struct roseQsigAOCRecordedCurrency * recorded)125 static unsigned char *rose_enc_qsig_AOC_RecordedCurrency(struct pri *ctrl,
126 	unsigned char *pos, unsigned char *end, unsigned tag,
127 	const struct roseQsigAOCRecordedCurrency *recorded)
128 {
129 	unsigned char *seq_len;
130 
131 	ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, tag);
132 
133 	ASN1_CALL(pos, asn1_enc_string_max(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 1,
134 		recorded->currency, sizeof(recorded->currency) - 1));
135 	ASN1_CALL(pos, rose_enc_qsig_AOC_Amount(ctrl, pos, end,
136 		ASN1_CLASS_CONTEXT_SPECIFIC | 2, &recorded->amount));
137 
138 	ASN1_CONSTRUCTED_END(seq_len, pos, end);
139 
140 	return pos;
141 }
142 
143 /*!
144  * \internal
145  * \brief Encode the DurationCurrency type.
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 tag Component tag to identify the encoded component.
151  *   The tag should be ASN1_TAG_SEQUENCE unless the caller implicitly
152  *   tags it otherwise.
153  * \param duration Duration currency information to encode.
154  *
155  * \retval Start of the next ASN.1 component to encode on success.
156  * \retval NULL on error.
157  */
rose_enc_qsig_AOC_DurationCurrency(struct pri * ctrl,unsigned char * pos,unsigned char * end,unsigned tag,const struct roseQsigAOCDurationCurrency * duration)158 static unsigned char *rose_enc_qsig_AOC_DurationCurrency(struct pri *ctrl,
159 	unsigned char *pos, unsigned char *end, unsigned tag,
160 	const struct roseQsigAOCDurationCurrency *duration)
161 {
162 	unsigned char *seq_len;
163 
164 	ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, tag);
165 
166 	ASN1_CALL(pos, asn1_enc_string_max(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 1,
167 		duration->currency, sizeof(duration->currency) - 1));
168 	ASN1_CALL(pos, rose_enc_qsig_AOC_Amount(ctrl, pos, end,
169 		ASN1_CLASS_CONTEXT_SPECIFIC | 2, &duration->amount));
170 	ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 3,
171 		duration->charging_type));
172 	ASN1_CALL(pos, rose_enc_qsig_AOC_Time(ctrl, pos, end,
173 		ASN1_CLASS_CONTEXT_SPECIFIC | 4, &duration->time));
174 	if (duration->granularity_present) {
175 		ASN1_CALL(pos, rose_enc_qsig_AOC_Time(ctrl, pos, end,
176 			ASN1_CLASS_CONTEXT_SPECIFIC | 5, &duration->granularity));
177 	}
178 
179 	ASN1_CONSTRUCTED_END(seq_len, pos, end);
180 
181 	return pos;
182 }
183 
184 /*!
185  * \internal
186  * \brief Encode the FlatRateCurrency type.
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 tag Component tag to identify the encoded component.
192  *   The tag should be ASN1_TAG_SEQUENCE unless the caller implicitly
193  *   tags it otherwise.
194  * \param flat_rate Flat rate currency information to encode.
195  *
196  * \retval Start of the next ASN.1 component to encode on success.
197  * \retval NULL on error.
198  */
rose_enc_qsig_AOC_FlatRateCurrency(struct pri * ctrl,unsigned char * pos,unsigned char * end,unsigned tag,const struct roseQsigAOCFlatRateCurrency * flat_rate)199 static unsigned char *rose_enc_qsig_AOC_FlatRateCurrency(struct pri *ctrl,
200 	unsigned char *pos, unsigned char *end, unsigned tag,
201 	const struct roseQsigAOCFlatRateCurrency *flat_rate)
202 {
203 	unsigned char *seq_len;
204 
205 	ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, tag);
206 
207 	ASN1_CALL(pos, asn1_enc_string_max(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 1,
208 		flat_rate->currency, sizeof(flat_rate->currency) - 1));
209 	ASN1_CALL(pos, rose_enc_qsig_AOC_Amount(ctrl, pos, end,
210 		ASN1_CLASS_CONTEXT_SPECIFIC | 2, &flat_rate->amount));
211 
212 	ASN1_CONSTRUCTED_END(seq_len, pos, end);
213 
214 	return pos;
215 }
216 
217 /*!
218  * \internal
219  * \brief Encode the VolumeRateCurrency type.
220  *
221  * \param ctrl D channel controller for diagnostic messages or global options.
222  * \param pos Starting position to encode ASN.1 component.
223  * \param end End of ASN.1 encoding data buffer.
224  * \param tag Component tag to identify the encoded component.
225  *   The tag should be ASN1_TAG_SEQUENCE unless the caller implicitly
226  *   tags it otherwise.
227  * \param volume_rate Volume rate currency information to encode.
228  *
229  * \retval Start of the next ASN.1 component to encode on success.
230  * \retval NULL on error.
231  */
rose_enc_qsig_AOC_VolumeRateCurrency(struct pri * ctrl,unsigned char * pos,unsigned char * end,unsigned tag,const struct roseQsigAOCVolumeRateCurrency * volume_rate)232 static unsigned char *rose_enc_qsig_AOC_VolumeRateCurrency(struct pri *ctrl,
233 	unsigned char *pos, unsigned char *end, unsigned tag,
234 	const struct roseQsigAOCVolumeRateCurrency *volume_rate)
235 {
236 	unsigned char *seq_len;
237 
238 	ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, tag);
239 
240 	ASN1_CALL(pos, asn1_enc_string_max(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 1,
241 		volume_rate->currency, sizeof(volume_rate->currency) - 1));
242 	ASN1_CALL(pos, rose_enc_qsig_AOC_Amount(ctrl, pos, end,
243 		ASN1_CLASS_CONTEXT_SPECIFIC | 2, &volume_rate->amount));
244 	ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 3,
245 		volume_rate->unit));
246 
247 	ASN1_CONSTRUCTED_END(seq_len, pos, end);
248 
249 	return pos;
250 }
251 
252 /*!
253  * \internal
254  * \brief Encode the AOCSCurrencyInfo type.
255  *
256  * \param ctrl D channel controller for diagnostic messages or global options.
257  * \param pos Starting position to encode ASN.1 component.
258  * \param end End of ASN.1 encoding data buffer.
259  * \param tag Component tag to identify the encoded component.
260  *   The tag should be ASN1_TAG_SEQUENCE unless the caller implicitly
261  *   tags it otherwise.
262  * \param currency_info Currency information record to encode.
263  *
264  * \retval Start of the next ASN.1 component to encode on success.
265  * \retval NULL on error.
266  */
rose_enc_qsig_AOCSCurrencyInfo(struct pri * ctrl,unsigned char * pos,unsigned char * end,unsigned tag,const struct roseQsigAOCSCurrencyInfo * currency_info)267 static unsigned char *rose_enc_qsig_AOCSCurrencyInfo(struct pri *ctrl,
268 	unsigned char *pos, unsigned char *end, unsigned tag,
269 	const struct roseQsigAOCSCurrencyInfo *currency_info)
270 {
271 	unsigned char *seq_len;
272 
273 	ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, tag);
274 
275 	ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_ENUMERATED,
276 		currency_info->charged_item));
277 
278 	switch (currency_info->currency_type) {
279 	case 0:	/* specialChargingCode */
280 		ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_INTEGER,
281 			currency_info->u.special_charging_code));
282 		break;
283 	case 1:	/* durationCurrency */
284 		ASN1_CALL(pos, rose_enc_qsig_AOC_DurationCurrency(ctrl, pos, end,
285 			ASN1_CLASS_CONTEXT_SPECIFIC | 1, &currency_info->u.duration));
286 		break;
287 	case 2:	/* flatRateCurrency */
288 		ASN1_CALL(pos, rose_enc_qsig_AOC_FlatRateCurrency(ctrl, pos, end,
289 			ASN1_CLASS_CONTEXT_SPECIFIC | 2, &currency_info->u.flat_rate));
290 		break;
291 	case 3:	/* volumeRateCurrency */
292 		ASN1_CALL(pos, rose_enc_qsig_AOC_VolumeRateCurrency(ctrl, pos, end,
293 			ASN1_CLASS_CONTEXT_SPECIFIC | 3, &currency_info->u.volume_rate));
294 		break;
295 	case 4:	/* freeOfCharge */
296 		ASN1_CALL(pos, asn1_enc_null(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 4));
297 		break;
298 	case 5:	/* currencyInfoNotAvailable */
299 		ASN1_CALL(pos, asn1_enc_null(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 5));
300 		break;
301 	case 6:	/* freeOfChargeFromBeginning */
302 		ASN1_CALL(pos, asn1_enc_null(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 6));
303 		break;
304 	default:
305 		ASN1_ENC_ERROR(ctrl, "Unknown currency type");
306 		return NULL;
307 	}
308 
309 	ASN1_CONSTRUCTED_END(seq_len, pos, end);
310 
311 	return pos;
312 }
313 
314 /*!
315  * \internal
316  * \brief Encode the AOCSCurrencyInfoList type.
317  *
318  * \param ctrl D channel controller for diagnostic messages or global options.
319  * \param pos Starting position to encode ASN.1 component.
320  * \param end End of ASN.1 encoding data buffer.
321  * \param tag Component tag to identify the encoded component.
322  *   The tag should be ASN1_TAG_SEQUENCE unless the caller implicitly
323  *   tags it otherwise.
324  * \param currency_info Currency information list to encode.
325  *
326  * \retval Start of the next ASN.1 component to encode on success.
327  * \retval NULL on error.
328  */
rose_enc_qsig_AOCSCurrencyInfoList(struct pri * ctrl,unsigned char * pos,unsigned char * end,unsigned tag,const struct roseQsigAOCSCurrencyInfoList * currency_info)329 static unsigned char *rose_enc_qsig_AOCSCurrencyInfoList(struct pri *ctrl,
330 	unsigned char *pos, unsigned char *end, unsigned tag,
331 	const struct roseQsigAOCSCurrencyInfoList *currency_info)
332 {
333 	unsigned index;
334 	unsigned char *seq_len;
335 
336 	ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, tag);
337 
338 	for (index = 0; index < currency_info->num_records; ++index) {
339 		ASN1_CALL(pos, rose_enc_qsig_AOCSCurrencyInfo(ctrl, pos, end, ASN1_TAG_SEQUENCE,
340 			&currency_info->list[index]));
341 	}
342 
343 	ASN1_CONSTRUCTED_END(seq_len, pos, end);
344 
345 	return pos;
346 }
347 
348 /*!
349  * \internal
350  * \brief Encode the ChargingAssociation type.
351  *
352  * \param ctrl D channel controller for diagnostic messages or global options.
353  * \param pos Starting position to encode ASN.1 component.
354  * \param end End of ASN.1 encoding data buffer.
355  * \param charging Charging association information to encode.
356  *
357  * \retval Start of the next ASN.1 component to encode on success.
358  * \retval NULL on error.
359  */
rose_enc_qsig_AOC_ChargingAssociation(struct pri * ctrl,unsigned char * pos,unsigned char * end,const struct roseQsigAOCChargingAssociation * charging)360 static unsigned char *rose_enc_qsig_AOC_ChargingAssociation(struct pri *ctrl,
361 	unsigned char *pos, unsigned char *end,
362 	const struct roseQsigAOCChargingAssociation *charging)
363 {
364 	unsigned char *explicit_len;
365 
366 	switch (charging->type) {
367 	case 0:	/* charge_identifier */
368 		ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_INTEGER, charging->id));
369 		break;
370 	case 1:	/* charged_number */
371 		/* EXPLICIT tag */
372 		ASN1_CONSTRUCTED_BEGIN(explicit_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 0);
373 		ASN1_CALL(pos, rose_enc_PartyNumber(ctrl, pos, end, &charging->number));
374 		ASN1_CONSTRUCTED_END(explicit_len, pos, end);
375 		break;
376 	default:
377 		ASN1_ENC_ERROR(ctrl, "Unknown ChargingAssociation type");
378 		return NULL;
379 	}
380 
381 	return pos;
382 }
383 
384 /*!
385  * \brief Encode the Q.SIG ChargeRequest invoke facility ie arguments.
386  *
387  * \param ctrl D channel controller for diagnostic messages or global options.
388  * \param pos Starting position to encode ASN.1 component.
389  * \param end End of ASN.1 encoding data buffer.
390  * \param args Arguments to encode in the buffer.
391  *
392  * \retval Start of the next ASN.1 component to encode on success.
393  * \retval NULL on error.
394  */
rose_enc_qsig_ChargeRequest_ARG(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_invoke_args * args)395 unsigned char *rose_enc_qsig_ChargeRequest_ARG(struct pri *ctrl, unsigned char *pos,
396 	unsigned char *end, const union rose_msg_invoke_args *args)
397 {
398 	unsigned index;
399 	unsigned char *seq_len;
400 	unsigned char *advice_len;
401 	const struct roseQsigChargeRequestArg_ARG *charge_request;
402 
403 	charge_request = &args->qsig.ChargeRequest;
404 
405 	ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
406 
407 	/* SEQUENCE SIZE(0..7) OF AdviceModeCombination */
408 	ASN1_CONSTRUCTED_BEGIN(advice_len, pos, end, ASN1_TAG_SEQUENCE);
409 	for (index = 0; index < charge_request->num_records; ++index) {
410 		ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_ENUMERATED,
411 			charge_request->advice_mode_combinations[index]));
412 	}
413 	ASN1_CONSTRUCTED_END(advice_len, pos, end);
414 
415 	/* No extension to encode */
416 
417 	ASN1_CONSTRUCTED_END(seq_len, pos, end);
418 
419 	return pos;
420 }
421 
422 /*!
423  * \brief Encode the Q.SIG ChargeRequest result facility ie arguments.
424  *
425  * \param ctrl D channel controller for diagnostic messages or global options.
426  * \param pos Starting position to encode ASN.1 component.
427  * \param end End of ASN.1 encoding data buffer.
428  * \param args Arguments to encode in the buffer.
429  *
430  * \retval Start of the next ASN.1 component to encode on success.
431  * \retval NULL on error.
432  */
rose_enc_qsig_ChargeRequest_RES(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_result_args * args)433 unsigned char *rose_enc_qsig_ChargeRequest_RES(struct pri *ctrl, unsigned char *pos,
434 	unsigned char *end, const union rose_msg_result_args *args)
435 {
436 	unsigned char *seq_len;
437 	const struct roseQsigChargeRequestRes_RES *charge_request;
438 
439 	charge_request = &args->qsig.ChargeRequest;
440 
441 	ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
442 
443 	ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_ENUMERATED,
444 		charge_request->advice_mode_combination));
445 
446 	/* No extension to encode */
447 
448 	ASN1_CONSTRUCTED_END(seq_len, pos, end);
449 
450 	return pos;
451 }
452 
453 /*!
454  * \brief Encode the Q.SIG AocFinal invoke facility ie arguments.
455  *
456  * \param ctrl D channel controller for diagnostic messages or global options.
457  * \param pos Starting position to encode ASN.1 component.
458  * \param end End of ASN.1 encoding data buffer.
459  * \param args Arguments to encode in the buffer.
460  *
461  * \retval Start of the next ASN.1 component to encode on success.
462  * \retval NULL on error.
463  */
rose_enc_qsig_AocFinal_ARG(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_invoke_args * args)464 unsigned char *rose_enc_qsig_AocFinal_ARG(struct pri *ctrl, unsigned char *pos,
465 	unsigned char *end, const union rose_msg_invoke_args *args)
466 {
467 	unsigned char *seq_len;
468 	unsigned char *specific_len;
469 	const struct roseQsigAocFinalArg_ARG *aoc_final;
470 
471 	aoc_final = &args->qsig.AocFinal;
472 
473 	ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
474 
475 	switch (aoc_final->type) {
476 	case 0:	/* charge_not_available */
477 		ASN1_CALL(pos, asn1_enc_null(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 0));
478 		break;
479 	case 1:	/* free_of_charge */
480 		ASN1_CALL(pos, asn1_enc_null(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 1));
481 		break;
482 	case 2:	/* specific_currency */
483 		ASN1_CONSTRUCTED_BEGIN(specific_len, pos, end, ASN1_TAG_SEQUENCE);
484 
485 		ASN1_CALL(pos, rose_enc_qsig_AOC_RecordedCurrency(ctrl, pos, end,
486 			ASN1_CLASS_CONTEXT_SPECIFIC | 1, &aoc_final->specific.recorded));
487 
488 		if (aoc_final->specific.billing_id_present) {
489 			ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 2,
490 				aoc_final->specific.billing_id));
491 		}
492 
493 		ASN1_CONSTRUCTED_END(specific_len, pos, end);
494 		break;
495 	default:
496 		ASN1_ENC_ERROR(ctrl, "Unknown AocFinal type");
497 		return NULL;
498 	}
499 
500 	if (aoc_final->charging_association_present) {
501 		ASN1_CALL(pos, rose_enc_qsig_AOC_ChargingAssociation(ctrl, pos, end,
502 			&aoc_final->charging_association));
503 	}
504 
505 	/* No extension to encode */
506 
507 	ASN1_CONSTRUCTED_END(seq_len, pos, end);
508 
509 	return pos;
510 }
511 
512 /*!
513  * \brief Encode the Q.SIG AocInterim invoke facility ie arguments.
514  *
515  * \param ctrl D channel controller for diagnostic messages or global options.
516  * \param pos Starting position to encode ASN.1 component.
517  * \param end End of ASN.1 encoding data buffer.
518  * \param args Arguments to encode in the buffer.
519  *
520  * \retval Start of the next ASN.1 component to encode on success.
521  * \retval NULL on error.
522  */
rose_enc_qsig_AocInterim_ARG(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_invoke_args * args)523 unsigned char *rose_enc_qsig_AocInterim_ARG(struct pri *ctrl, unsigned char *pos,
524 	unsigned char *end, const union rose_msg_invoke_args *args)
525 {
526 	unsigned char *seq_len;
527 	unsigned char *specific_len;
528 	const struct roseQsigAocInterimArg_ARG *aoc_interim;
529 
530 	aoc_interim = &args->qsig.AocInterim;
531 
532 	ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
533 
534 	switch (aoc_interim->type) {
535 	case 0:	/* charge_not_available */
536 		ASN1_CALL(pos, asn1_enc_null(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 0));
537 		break;
538 	case 1:	/* free_of_charge */
539 		ASN1_CALL(pos, asn1_enc_null(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 1));
540 		break;
541 	case 2:	/* specific_currency */
542 		ASN1_CONSTRUCTED_BEGIN(specific_len, pos, end, ASN1_TAG_SEQUENCE);
543 
544 		ASN1_CALL(pos, rose_enc_qsig_AOC_RecordedCurrency(ctrl, pos, end,
545 			ASN1_CLASS_CONTEXT_SPECIFIC | 1, &aoc_interim->specific.recorded));
546 
547 		if (aoc_interim->specific.billing_id_present) {
548 			ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 2,
549 				aoc_interim->specific.billing_id));
550 		}
551 
552 		ASN1_CONSTRUCTED_END(specific_len, pos, end);
553 		break;
554 	default:
555 		ASN1_ENC_ERROR(ctrl, "Unknown AocInterim type");
556 		return NULL;
557 	}
558 
559 	/* No extension to encode */
560 
561 	ASN1_CONSTRUCTED_END(seq_len, pos, end);
562 
563 	return pos;
564 }
565 
566 /*!
567  * \brief Encode the Q.SIG AocRate invoke facility ie arguments.
568  *
569  * \param ctrl D channel controller for diagnostic messages or global options.
570  * \param pos Starting position to encode ASN.1 component.
571  * \param end End of ASN.1 encoding data buffer.
572  * \param args Arguments to encode in the buffer.
573  *
574  * \retval Start of the next ASN.1 component to encode on success.
575  * \retval NULL on error.
576  */
rose_enc_qsig_AocRate_ARG(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_invoke_args * args)577 unsigned char *rose_enc_qsig_AocRate_ARG(struct pri *ctrl, unsigned char *pos,
578 	unsigned char *end, const union rose_msg_invoke_args *args)
579 {
580 	unsigned char *seq_len;
581 	const struct roseQsigAocRateArg_ARG *aoc_rate;
582 
583 	aoc_rate = &args->qsig.AocRate;
584 
585 	ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
586 
587 	switch (aoc_rate->type) {
588 	case 0:	/* charge_not_available */
589 		ASN1_CALL(pos, asn1_enc_null(pos, end, ASN1_TYPE_NULL));
590 		break;
591 	case 1:	/* currency_info_list */
592 		ASN1_CALL(pos, rose_enc_qsig_AOCSCurrencyInfoList(ctrl, pos, end,
593 			ASN1_TAG_SEQUENCE, &aoc_rate->currency_info));
594 		break;
595 	default:
596 		ASN1_ENC_ERROR(ctrl, "Unknown AocRate type");
597 		return NULL;
598 	}
599 
600 	/* No extension to encode */
601 
602 	ASN1_CONSTRUCTED_END(seq_len, pos, end);
603 
604 	return pos;
605 }
606 
607 /*!
608  * \brief Encode the Q.SIG AocComplete invoke facility ie arguments.
609  *
610  * \param ctrl D channel controller for diagnostic messages or global options.
611  * \param pos Starting position to encode ASN.1 component.
612  * \param end End of ASN.1 encoding data buffer.
613  * \param args Arguments to encode in the buffer.
614  *
615  * \retval Start of the next ASN.1 component to encode on success.
616  * \retval NULL on error.
617  */
rose_enc_qsig_AocComplete_ARG(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_invoke_args * args)618 unsigned char *rose_enc_qsig_AocComplete_ARG(struct pri *ctrl, unsigned char *pos,
619 	unsigned char *end, const union rose_msg_invoke_args *args)
620 {
621 	unsigned char *seq_len;
622 	const struct roseQsigAocCompleteArg_ARG *aoc_complete;
623 
624 	aoc_complete = &args->qsig.AocComplete;
625 
626 	ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
627 
628 	ASN1_CALL(pos, rose_enc_PartyNumber(ctrl, pos, end,
629 		&aoc_complete->charged_user_number));
630 
631 	if (aoc_complete->charging_association_present) {
632 		ASN1_CALL(pos, rose_enc_qsig_AOC_ChargingAssociation(ctrl, pos, end,
633 			&aoc_complete->charging_association));
634 	}
635 
636 	/* No extension to encode */
637 
638 	ASN1_CONSTRUCTED_END(seq_len, pos, end);
639 
640 	return pos;
641 }
642 
643 /*!
644  * \brief Encode the Q.SIG AocComplete result facility ie arguments.
645  *
646  * \param ctrl D channel controller for diagnostic messages or global options.
647  * \param pos Starting position to encode ASN.1 component.
648  * \param end End of ASN.1 encoding data buffer.
649  * \param args Arguments to encode in the buffer.
650  *
651  * \retval Start of the next ASN.1 component to encode on success.
652  * \retval NULL on error.
653  */
rose_enc_qsig_AocComplete_RES(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_result_args * args)654 unsigned char *rose_enc_qsig_AocComplete_RES(struct pri *ctrl, unsigned char *pos,
655 	unsigned char *end, const union rose_msg_result_args *args)
656 {
657 	unsigned char *seq_len;
658 	const struct roseQsigAocCompleteRes_RES *aoc_complete;
659 
660 	aoc_complete = &args->qsig.AocComplete;
661 
662 	ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
663 
664 	ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_ENUMERATED,
665 		aoc_complete->charging_option));
666 
667 	/* No extension to encode */
668 
669 	ASN1_CONSTRUCTED_END(seq_len, pos, end);
670 
671 	return pos;
672 }
673 
674 /*!
675  * \brief Encode the Q.SIG AocDivChargeReq invoke facility ie arguments.
676  *
677  * \param ctrl D channel controller for diagnostic messages or global options.
678  * \param pos Starting position to encode ASN.1 component.
679  * \param end End of ASN.1 encoding data buffer.
680  * \param args Arguments to encode in the buffer.
681  *
682  * \retval Start of the next ASN.1 component to encode on success.
683  * \retval NULL on error.
684  */
rose_enc_qsig_AocDivChargeReq_ARG(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_invoke_args * args)685 unsigned char *rose_enc_qsig_AocDivChargeReq_ARG(struct pri *ctrl, unsigned char *pos,
686 	unsigned char *end, const union rose_msg_invoke_args *args)
687 {
688 	unsigned char *seq_len;
689 	const struct roseQsigAocDivChargeReqArg_ARG *aoc_div_charge_req;
690 
691 	aoc_div_charge_req = &args->qsig.AocDivChargeReq;
692 
693 	ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
694 
695 	ASN1_CALL(pos, rose_enc_PartyNumber(ctrl, pos, end,
696 		&aoc_div_charge_req->diverting_user_number));
697 
698 	if (aoc_div_charge_req->charging_association_present) {
699 		ASN1_CALL(pos, rose_enc_qsig_AOC_ChargingAssociation(ctrl, pos, end,
700 			&aoc_div_charge_req->charging_association));
701 	}
702 
703 	ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_ENUMERATED,
704 		aoc_div_charge_req->diversion_type));
705 
706 	/* No extension to encode */
707 
708 	ASN1_CONSTRUCTED_END(seq_len, pos, end);
709 
710 	return pos;
711 }
712 
713 /*!
714  * \internal
715  * \brief Decode the Time type.
716  *
717  * \param ctrl D channel controller for diagnostic messages or global options.
718  * \param name Field name
719  * \param tag Component tag that identified this production.
720  * \param pos Starting position of the ASN.1 component length.
721  * \param end End of ASN.1 decoding data buffer.
722  * \param time Parameter storage to fill.
723  *
724  * \retval Start of the next ASN.1 component on success.
725  * \retval NULL on error.
726  */
rose_dec_qsig_AOC_Time(struct pri * ctrl,const char * name,unsigned tag,const unsigned char * pos,const unsigned char * end,struct roseQsigAOCTime * time)727 static const unsigned char *rose_dec_qsig_AOC_Time(struct pri *ctrl, const char *name,
728 	unsigned tag, const unsigned char *pos, const unsigned char *end,
729 	struct roseQsigAOCTime *time)
730 {
731 	int32_t value;
732 	int length;
733 	int seq_offset;
734 	const unsigned char *seq_end;
735 
736 	if (ctrl->debug & PRI_DEBUG_APDU) {
737 		pri_message(ctrl, "  %s Time %s\n", name, asn1_tag2str(tag));
738 	}
739 	ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
740 	ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
741 
742 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
743 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_CLASS_CONTEXT_SPECIFIC | 1);
744 	ASN1_CALL(pos, asn1_dec_int(ctrl, "lengthOfTimeUnit", tag, pos, seq_end, &value));
745 	time->length = value;
746 
747 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
748 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_CLASS_CONTEXT_SPECIFIC | 2);
749 	ASN1_CALL(pos, asn1_dec_int(ctrl, "scale", tag, pos, seq_end, &value));
750 	time->scale = value;
751 
752 	ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
753 
754 	return pos;
755 }
756 
757 /*!
758  * \internal
759  * \brief Decode the Amount type.
760  *
761  * \param ctrl D channel controller for diagnostic messages or global options.
762  * \param name Field name
763  * \param tag Component tag that identified this production.
764  * \param pos Starting position of the ASN.1 component length.
765  * \param end End of ASN.1 decoding data buffer.
766  * \param amount Parameter storage to fill.
767  *
768  * \retval Start of the next ASN.1 component on success.
769  * \retval NULL on error.
770  */
rose_dec_qsig_AOC_Amount(struct pri * ctrl,const char * name,unsigned tag,const unsigned char * pos,const unsigned char * end,struct roseQsigAOCAmount * amount)771 static const unsigned char *rose_dec_qsig_AOC_Amount(struct pri *ctrl, const char *name,
772 	unsigned tag, const unsigned char *pos, const unsigned char *end,
773 	struct roseQsigAOCAmount *amount)
774 {
775 	int32_t value;
776 	int length;
777 	int seq_offset;
778 	const unsigned char *seq_end;
779 
780 	if (ctrl->debug & PRI_DEBUG_APDU) {
781 		pri_message(ctrl, "  %s Amount %s\n", name, asn1_tag2str(tag));
782 	}
783 	ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
784 	ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
785 
786 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
787 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_CLASS_CONTEXT_SPECIFIC | 1);
788 	ASN1_CALL(pos, asn1_dec_int(ctrl, "currencyAmount", tag, pos, seq_end, &value));
789 	amount->currency = value;
790 
791 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
792 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_CLASS_CONTEXT_SPECIFIC | 2);
793 	ASN1_CALL(pos, asn1_dec_int(ctrl, "multiplier", tag, pos, seq_end, &value));
794 	amount->multiplier = value;
795 
796 	ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
797 
798 	return pos;
799 }
800 
801 /*!
802  * \internal
803  * \brief Decode the RecordedCurrency type.
804  *
805  * \param ctrl D channel controller for diagnostic messages or global options.
806  * \param name Field name
807  * \param tag Component tag that identified this production.
808  * \param pos Starting position of the ASN.1 component length.
809  * \param end End of ASN.1 decoding data buffer.
810  * \param recorded Parameter storage to fill.
811  *
812  * \retval Start of the next ASN.1 component on success.
813  * \retval NULL on error.
814  */
rose_dec_qsig_AOC_RecordedCurrency(struct pri * ctrl,const char * name,unsigned tag,const unsigned char * pos,const unsigned char * end,struct roseQsigAOCRecordedCurrency * recorded)815 static const unsigned char *rose_dec_qsig_AOC_RecordedCurrency(struct pri *ctrl,
816 	const char *name, unsigned tag, const unsigned char *pos, const unsigned char *end,
817 	struct roseQsigAOCRecordedCurrency *recorded)
818 {
819 	int length;
820 	int seq_offset;
821 	const unsigned char *seq_end;
822 	size_t str_len;
823 
824 	if (ctrl->debug & PRI_DEBUG_APDU) {
825 		pri_message(ctrl, "  %s RecordedCurrency %s\n", name, asn1_tag2str(tag));
826 	}
827 	ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
828 	ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
829 
830 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
831 	ASN1_CHECK_TAG(ctrl, tag & ~ASN1_PC_MASK, tag, ASN1_CLASS_CONTEXT_SPECIFIC | 1);
832 	ASN1_CALL(pos, asn1_dec_string_max(ctrl, "rCurrency", tag, pos, seq_end,
833 		sizeof(recorded->currency), recorded->currency, &str_len));
834 
835 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
836 	ASN1_CHECK_TAG(ctrl, tag, tag,
837 		ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 2);
838 	ASN1_CALL(pos, rose_dec_qsig_AOC_Amount(ctrl, "rAmount", tag, pos, seq_end,
839 		&recorded->amount));
840 
841 	ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
842 
843 	return pos;
844 }
845 
846 /*!
847  * \internal
848  * \brief Decode the DurationCurrency type.
849  *
850  * \param ctrl D channel controller for diagnostic messages or global options.
851  * \param name Field name
852  * \param tag Component tag that identified this production.
853  * \param pos Starting position of the ASN.1 component length.
854  * \param end End of ASN.1 decoding data buffer.
855  * \param duration Parameter storage to fill.
856  *
857  * \retval Start of the next ASN.1 component on success.
858  * \retval NULL on error.
859  */
rose_dec_qsig_AOC_DurationCurrency(struct pri * ctrl,const char * name,unsigned tag,const unsigned char * pos,const unsigned char * end,struct roseQsigAOCDurationCurrency * duration)860 static const unsigned char *rose_dec_qsig_AOC_DurationCurrency(struct pri *ctrl,
861 	const char *name, unsigned tag, const unsigned char *pos, const unsigned char *end,
862 	struct roseQsigAOCDurationCurrency *duration)
863 {
864 	int32_t value;
865 	int length;
866 	int seq_offset;
867 	const unsigned char *seq_end;
868 	size_t str_len;
869 
870 	if (ctrl->debug & PRI_DEBUG_APDU) {
871 		pri_message(ctrl, "  %s DurationCurrency %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 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
877 	ASN1_CHECK_TAG(ctrl, tag & ~ASN1_PC_MASK, tag, ASN1_CLASS_CONTEXT_SPECIFIC | 1);
878 	ASN1_CALL(pos, asn1_dec_string_max(ctrl, "dCurrency", tag, pos, seq_end,
879 		sizeof(duration->currency), duration->currency, &str_len));
880 
881 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
882 	ASN1_CHECK_TAG(ctrl, tag, tag,
883 		ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 2);
884 	ASN1_CALL(pos, rose_dec_qsig_AOC_Amount(ctrl, "dAmount", tag, pos, seq_end,
885 		&duration->amount));
886 
887 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
888 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_CLASS_CONTEXT_SPECIFIC | 3);
889 	ASN1_CALL(pos, asn1_dec_int(ctrl, "dChargingType", tag, pos, seq_end, &value));
890 	duration->charging_type = value;
891 
892 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
893 	ASN1_CHECK_TAG(ctrl, tag, tag,
894 		ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 4);
895 	ASN1_CALL(pos, rose_dec_qsig_AOC_Time(ctrl, "dTime", tag, pos, seq_end,
896 		&duration->time));
897 
898 	if (pos < seq_end && *pos != ASN1_INDEF_TERM) {
899 		ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
900 		ASN1_CHECK_TAG(ctrl, tag, tag,
901 			ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 5);
902 		ASN1_CALL(pos, rose_dec_qsig_AOC_Time(ctrl, "dGranularity", tag, pos, seq_end,
903 			&duration->granularity));
904 		duration->granularity_present = 1;
905 	} else {
906 		duration->granularity_present = 0;
907 	}
908 
909 	ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
910 
911 	return pos;
912 }
913 
914 /*!
915  * \internal
916  * \brief Decode the FlatRateCurrency type.
917  *
918  * \param ctrl D channel controller for diagnostic messages or global options.
919  * \param name Field name
920  * \param tag Component tag that identified this production.
921  * \param pos Starting position of the ASN.1 component length.
922  * \param end End of ASN.1 decoding data buffer.
923  * \param flat_rate Parameter storage to fill.
924  *
925  * \retval Start of the next ASN.1 component on success.
926  * \retval NULL on error.
927  */
rose_dec_qsig_AOC_FlatRateCurrency(struct pri * ctrl,const char * name,unsigned tag,const unsigned char * pos,const unsigned char * end,struct roseQsigAOCFlatRateCurrency * flat_rate)928 static const unsigned char *rose_dec_qsig_AOC_FlatRateCurrency(struct pri *ctrl,
929 	const char *name, unsigned tag, const unsigned char *pos, const unsigned char *end,
930 	struct roseQsigAOCFlatRateCurrency *flat_rate)
931 {
932 	int length;
933 	int seq_offset;
934 	const unsigned char *seq_end;
935 	size_t str_len;
936 
937 	if (ctrl->debug & PRI_DEBUG_APDU) {
938 		pri_message(ctrl, "  %s FlatRateCurrency %s\n", name, asn1_tag2str(tag));
939 	}
940 	ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
941 	ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
942 
943 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
944 	ASN1_CHECK_TAG(ctrl, tag & ~ASN1_PC_MASK, tag, ASN1_CLASS_CONTEXT_SPECIFIC | 1);
945 	ASN1_CALL(pos, asn1_dec_string_max(ctrl, "fRCurrency", tag, pos, seq_end,
946 		sizeof(flat_rate->currency), flat_rate->currency, &str_len));
947 
948 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
949 	ASN1_CHECK_TAG(ctrl, tag, tag,
950 		ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 2);
951 	ASN1_CALL(pos, rose_dec_qsig_AOC_Amount(ctrl, "fRAmount", tag, pos, seq_end,
952 		&flat_rate->amount));
953 
954 	ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
955 
956 	return pos;
957 }
958 
959 /*!
960  * \internal
961  * \brief Decode the VolumeRateCurrency type.
962  *
963  * \param ctrl D channel controller for diagnostic messages or global options.
964  * \param name Field name
965  * \param tag Component tag that identified this production.
966  * \param pos Starting position of the ASN.1 component length.
967  * \param end End of ASN.1 decoding data buffer.
968  * \param volume_rate Parameter storage to fill.
969  *
970  * \retval Start of the next ASN.1 component on success.
971  * \retval NULL on error.
972  */
rose_dec_qsig_AOC_VolumeRateCurrency(struct pri * ctrl,const char * name,unsigned tag,const unsigned char * pos,const unsigned char * end,struct roseQsigAOCVolumeRateCurrency * volume_rate)973 static const unsigned char *rose_dec_qsig_AOC_VolumeRateCurrency(struct pri *ctrl,
974 	const char *name, unsigned tag, const unsigned char *pos, const unsigned char *end,
975 	struct roseQsigAOCVolumeRateCurrency *volume_rate)
976 {
977 	int32_t value;
978 	int length;
979 	int seq_offset;
980 	const unsigned char *seq_end;
981 	size_t str_len;
982 
983 	if (ctrl->debug & PRI_DEBUG_APDU) {
984 		pri_message(ctrl, "  %s VolumeRateCurrency %s\n", name, asn1_tag2str(tag));
985 	}
986 	ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
987 	ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
988 
989 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
990 	ASN1_CHECK_TAG(ctrl, tag & ~ASN1_PC_MASK, tag, ASN1_CLASS_CONTEXT_SPECIFIC | 1);
991 	ASN1_CALL(pos, asn1_dec_string_max(ctrl, "vRCurrency", tag, pos, seq_end,
992 		sizeof(volume_rate->currency), volume_rate->currency, &str_len));
993 
994 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
995 	ASN1_CHECK_TAG(ctrl, tag, tag,
996 		ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 2);
997 	ASN1_CALL(pos, rose_dec_qsig_AOC_Amount(ctrl, "vRAmount", tag, pos, seq_end,
998 		&volume_rate->amount));
999 
1000 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1001 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_CLASS_CONTEXT_SPECIFIC | 3);
1002 	ASN1_CALL(pos, asn1_dec_int(ctrl, "vRVolumeUnit", tag, pos, seq_end, &value));
1003 	volume_rate->unit = value;
1004 
1005 	ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
1006 
1007 	return pos;
1008 }
1009 
1010 /*!
1011  * \internal
1012  * \brief Decode the AOCSCurrencyInfo type.
1013  *
1014  * \param ctrl D channel controller for diagnostic messages or global options.
1015  * \param name Field name
1016  * \param tag Component tag that identified this production.
1017  * \param pos Starting position of the ASN.1 component length.
1018  * \param end End of ASN.1 decoding data buffer.
1019  * \param currency_info Parameter storage to fill.
1020  *
1021  * \retval Start of the next ASN.1 component on success.
1022  * \retval NULL on error.
1023  */
rose_dec_qsig_AOCSCurrencyInfo(struct pri * ctrl,const char * name,unsigned tag,const unsigned char * pos,const unsigned char * end,struct roseQsigAOCSCurrencyInfo * currency_info)1024 static const unsigned char *rose_dec_qsig_AOCSCurrencyInfo(struct pri *ctrl,
1025 	const char *name, unsigned tag, const unsigned char *pos, const unsigned char *end,
1026 	struct roseQsigAOCSCurrencyInfo *currency_info)
1027 {
1028 	int32_t value;
1029 	int length;
1030 	int seq_offset;
1031 	const unsigned char *seq_end;
1032 
1033 	if (ctrl->debug & PRI_DEBUG_APDU) {
1034 		pri_message(ctrl, "  %s AOCSCurrencyInfo %s\n", name, asn1_tag2str(tag));
1035 	}
1036 	ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
1037 	ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
1038 
1039 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1040 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_ENUMERATED);
1041 	ASN1_CALL(pos, asn1_dec_int(ctrl, "chargedItem", tag, pos, seq_end, &value));
1042 	currency_info->charged_item = value;
1043 
1044 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1045 	switch (tag) {
1046 	case ASN1_TYPE_INTEGER:
1047 		currency_info->currency_type = 0;	/* specialChargingCode */
1048 		ASN1_CALL(pos, asn1_dec_int(ctrl, "specialChargingCode", tag, pos, seq_end,
1049 			&value));
1050 		currency_info->u.special_charging_code = value;
1051 		break;
1052 	case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 1:
1053 		currency_info->currency_type = 1;	/* durationCurrency */
1054 		ASN1_CALL(pos, rose_dec_qsig_AOC_DurationCurrency(ctrl, "durationCurrency", tag,
1055 			pos, seq_end, &currency_info->u.duration));
1056 		break;
1057 	case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 2:
1058 		currency_info->currency_type = 2;	/* flatRateCurrency */
1059 		ASN1_CALL(pos, rose_dec_qsig_AOC_FlatRateCurrency(ctrl, "flatRateCurrency", tag,
1060 			pos, seq_end, &currency_info->u.flat_rate));
1061 		break;
1062 	case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 3:
1063 		currency_info->currency_type = 3;	/* volumeRateCurrency */
1064 		ASN1_CALL(pos, rose_dec_qsig_AOC_VolumeRateCurrency(ctrl, "volumeRateCurrency",
1065 			tag, pos, seq_end, &currency_info->u.volume_rate));
1066 		break;
1067 	case ASN1_CLASS_CONTEXT_SPECIFIC | 4:
1068 		currency_info->currency_type = 4;	/* freeOfCharge */
1069 		ASN1_CALL(pos, asn1_dec_null(ctrl, "freeOfCharge", tag, pos, seq_end));
1070 		break;
1071 	case ASN1_CLASS_CONTEXT_SPECIFIC | 5:
1072 		currency_info->currency_type = 5;	/* currencyInfoNotAvailable */
1073 		ASN1_CALL(pos, asn1_dec_null(ctrl, "currencyInfoNotAvailable", tag, pos,
1074 			seq_end));
1075 		break;
1076 	case ASN1_CLASS_CONTEXT_SPECIFIC | 6:
1077 		currency_info->currency_type = 6;	/* freeOfChargeFromBeginning */
1078 		ASN1_CALL(pos, asn1_dec_null(ctrl, "freeOfChargeFromBeginning", tag, pos,
1079 			seq_end));
1080 		break;
1081 	default:
1082 		ASN1_DID_NOT_EXPECT_TAG(ctrl, tag);
1083 		return NULL;
1084 	}
1085 
1086 	ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
1087 
1088 	return pos;
1089 }
1090 
1091 /*!
1092  * \internal
1093  * \brief Decode the AOCSCurrencyInfoList type.
1094  *
1095  * \param ctrl D channel controller for diagnostic messages or global options.
1096  * \param name Field name
1097  * \param tag Component tag that identified this production.
1098  * \param pos Starting position of the ASN.1 component length.
1099  * \param end End of ASN.1 decoding data buffer.
1100  * \param currency_info Parameter storage to fill.
1101  *
1102  * \retval Start of the next ASN.1 component on success.
1103  * \retval NULL on error.
1104  */
rose_dec_qsig_AOCSCurrencyInfoList(struct pri * ctrl,const char * name,unsigned tag,const unsigned char * pos,const unsigned char * end,struct roseQsigAOCSCurrencyInfoList * currency_info)1105 static const unsigned char *rose_dec_qsig_AOCSCurrencyInfoList(struct pri *ctrl,
1106 	const char *name, unsigned tag, const unsigned char *pos, const unsigned char *end,
1107 	struct roseQsigAOCSCurrencyInfoList *currency_info)
1108 {
1109 	int length;
1110 	int seq_offset;
1111 	const unsigned char *seq_end;
1112 
1113 	if (ctrl->debug & PRI_DEBUG_APDU) {
1114 		pri_message(ctrl, "  %s AOCSCurrencyInfoList %s\n", name, asn1_tag2str(tag));
1115 	}
1116 	ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
1117 	ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
1118 
1119 	currency_info->num_records = 0;
1120 	while (pos < seq_end && *pos != ASN1_INDEF_TERM) {
1121 		if (currency_info->num_records < ARRAY_LEN(currency_info->list)) {
1122 			ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1123 			ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
1124 			ASN1_CALL(pos, rose_dec_qsig_AOCSCurrencyInfo(ctrl, "listEntry", tag, pos,
1125 				seq_end, &currency_info->list[currency_info->num_records]));
1126 			++currency_info->num_records;
1127 		} else {
1128 			/* Too many records */
1129 			return NULL;
1130 		}
1131 	}
1132 
1133 	ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
1134 
1135 	return pos;
1136 }
1137 
1138 /*!
1139  * \internal
1140  * \brief Decode the ChargingAssociation type.
1141  *
1142  * \param ctrl D channel controller for diagnostic messages or global options.
1143  * \param name Field name
1144  * \param tag Component tag that identified this production.
1145  * \param pos Starting position of the ASN.1 component length.
1146  * \param end End of ASN.1 decoding data buffer.
1147  * \param charging Parameter storage to fill.
1148  *
1149  * \retval Start of the next ASN.1 component on success.
1150  * \retval NULL on error.
1151  */
rose_dec_qsig_AOC_ChargingAssociation(struct pri * ctrl,const char * name,unsigned tag,const unsigned char * pos,const unsigned char * end,struct roseQsigAOCChargingAssociation * charging)1152 static const unsigned char *rose_dec_qsig_AOC_ChargingAssociation(struct pri *ctrl,
1153 	const char *name, unsigned tag, const unsigned char *pos, const unsigned char *end,
1154 	struct roseQsigAOCChargingAssociation *charging)
1155 {
1156 	int32_t value;
1157 	int length;
1158 	int explicit_offset;
1159 	const unsigned char *explicit_end;
1160 
1161 	if (ctrl->debug & PRI_DEBUG_APDU) {
1162 		pri_message(ctrl, "  %s ChargingAssociation\n", name);
1163 	}
1164 	switch (tag) {
1165 	case ASN1_TYPE_INTEGER:
1166 		charging->type = 0;	/* charge_identifier */
1167 		ASN1_CALL(pos, asn1_dec_int(ctrl, "chargeIdentifier", tag, pos, end, &value));
1168 		charging->id = value;
1169 		break;
1170 	case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 0:
1171 		charging->type = 1;	/* charged_number */
1172 
1173 		/* Remove EXPLICIT tag */
1174 		if (ctrl->debug & PRI_DEBUG_APDU) {
1175 			pri_message(ctrl, "  Explicit %s\n", asn1_tag2str(tag));
1176 		}
1177 		ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
1178 		ASN1_END_SETUP(explicit_end, explicit_offset, length, pos, end);
1179 
1180 		ASN1_CALL(pos, asn1_dec_tag(pos, explicit_end, &tag));
1181 		ASN1_CALL(pos, rose_dec_PartyNumber(ctrl, "chargedNumber", tag, pos,
1182 			explicit_end, &charging->number));
1183 
1184 		ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, end);
1185 		break;
1186 	default:
1187 		ASN1_DID_NOT_EXPECT_TAG(ctrl, tag);
1188 		return NULL;
1189 	}
1190 
1191 	return pos;
1192 }
1193 
1194 /*!
1195  * \brief Decode the Q.SIG ChargeRequest invoke argument parameters.
1196  *
1197  * \param ctrl D channel controller for diagnostic messages or global options.
1198  * \param tag Component tag that identified this structure.
1199  * \param pos Starting position of the ASN.1 component length.
1200  * \param end End of ASN.1 decoding data buffer.
1201  * \param args Arguments to fill in from the decoded buffer.
1202  *
1203  * \retval Start of the next ASN.1 component on success.
1204  * \retval NULL on error.
1205  */
rose_dec_qsig_ChargeRequest_ARG(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_invoke_args * args)1206 const unsigned char *rose_dec_qsig_ChargeRequest_ARG(struct pri *ctrl, unsigned tag,
1207 	const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
1208 {
1209 	int32_t value;
1210 	int length;
1211 	int seq_offset;
1212 	int advice_offset;
1213 	const unsigned char *seq_end;
1214 	const unsigned char *advice_end;
1215 	struct roseQsigChargeRequestArg_ARG *charge_request;
1216 
1217 	charge_request = &args->qsig.ChargeRequest;
1218 
1219 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
1220 	if (ctrl->debug & PRI_DEBUG_APDU) {
1221 		pri_message(ctrl, "  ChargeRequest %s\n", asn1_tag2str(tag));
1222 	}
1223 	ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
1224 	ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
1225 
1226 	/* SEQUENCE SIZE(0..7) OF AdviceModeCombination */
1227 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1228 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
1229 	if (ctrl->debug & PRI_DEBUG_APDU) {
1230 		pri_message(ctrl, "  adviceModeCombinations %s\n", asn1_tag2str(tag));
1231 	}
1232 	ASN1_CALL(pos, asn1_dec_length(pos, seq_end, &length));
1233 	ASN1_END_SETUP(advice_end, advice_offset, length, pos, seq_end);
1234 
1235 	/* Decode SIZE(0..7) OF AdviceModeCombination */
1236 	charge_request->num_records = 0;
1237 	while (pos < advice_end && *pos != ASN1_INDEF_TERM) {
1238 		if (charge_request->num_records <
1239 			ARRAY_LEN(charge_request->advice_mode_combinations)) {
1240 			ASN1_CALL(pos, asn1_dec_tag(pos, advice_end, &tag));
1241 			ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_ENUMERATED);
1242 			ASN1_CALL(pos, asn1_dec_int(ctrl, "adviceModeCombination", tag, pos,
1243 				advice_end, &value));
1244 			charge_request->advice_mode_combinations[charge_request->num_records] =
1245 				value;
1246 			++charge_request->num_records;
1247 		} else {
1248 			/* Too many records */
1249 			return NULL;
1250 		}
1251 	}
1252 
1253 	ASN1_END_FIXUP(ctrl, pos, advice_offset, advice_end, seq_end);
1254 
1255 	/* Fixup will skip over any OPTIONAL manufacturer extension information */
1256 	ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
1257 
1258 	return pos;
1259 }
1260 
1261 /*!
1262  * \brief Decode the Q.SIG ChargeRequest result argument parameters.
1263  *
1264  * \param ctrl D channel controller for diagnostic messages or global options.
1265  * \param tag Component tag that identified this structure.
1266  * \param pos Starting position of the ASN.1 component length.
1267  * \param end End of ASN.1 decoding data buffer.
1268  * \param args Arguments to fill in from the decoded buffer.
1269  *
1270  * \retval Start of the next ASN.1 component on success.
1271  * \retval NULL on error.
1272  */
rose_dec_qsig_ChargeRequest_RES(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_result_args * args)1273 const unsigned char *rose_dec_qsig_ChargeRequest_RES(struct pri *ctrl, unsigned tag,
1274 	const unsigned char *pos, const unsigned char *end, union rose_msg_result_args *args)
1275 {
1276 	int32_t value;
1277 	int length;
1278 	int seq_offset;
1279 	const unsigned char *seq_end;
1280 	struct roseQsigChargeRequestRes_RES *charge_request;
1281 
1282 	charge_request = &args->qsig.ChargeRequest;
1283 
1284 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
1285 	if (ctrl->debug & PRI_DEBUG_APDU) {
1286 		pri_message(ctrl, "  ChargeRequest %s\n", asn1_tag2str(tag));
1287 	}
1288 	ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
1289 	ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
1290 
1291 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1292 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_ENUMERATED);
1293 	ASN1_CALL(pos, asn1_dec_int(ctrl, "adviceModeCombination", tag, pos, seq_end,
1294 		&value));
1295 	charge_request->advice_mode_combination = value;
1296 
1297 	/* Fixup will skip over any OPTIONAL manufacturer extension information */
1298 	ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
1299 
1300 	return pos;
1301 }
1302 
1303 /*!
1304  * \brief Decode the Q.SIG AocFinal invoke argument parameters.
1305  *
1306  * \param ctrl D channel controller for diagnostic messages or global options.
1307  * \param tag Component tag that identified this structure.
1308  * \param pos Starting position of the ASN.1 component length.
1309  * \param end End of ASN.1 decoding data buffer.
1310  * \param args Arguments to fill in from the decoded buffer.
1311  *
1312  * \retval Start of the next ASN.1 component on success.
1313  * \retval NULL on error.
1314  */
rose_dec_qsig_AocFinal_ARG(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_invoke_args * args)1315 const unsigned char *rose_dec_qsig_AocFinal_ARG(struct pri *ctrl, unsigned tag,
1316 	const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
1317 {
1318 	int32_t value;
1319 	int length;
1320 	int seq_offset;
1321 	int specific_offset;
1322 	const unsigned char *seq_end;
1323 	const unsigned char *specific_end;
1324 	const unsigned char *save_pos;
1325 	struct roseQsigAocFinalArg_ARG *aoc_final;
1326 
1327 	aoc_final = &args->qsig.AocFinal;
1328 
1329 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
1330 	if (ctrl->debug & PRI_DEBUG_APDU) {
1331 		pri_message(ctrl, "  AocFinal %s\n", asn1_tag2str(tag));
1332 	}
1333 	ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
1334 	ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
1335 
1336 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1337 	switch (tag) {
1338 	case ASN1_CLASS_CONTEXT_SPECIFIC | 0:
1339 		aoc_final->type = 0;	/* charge_not_available */
1340 		ASN1_CALL(pos, asn1_dec_null(ctrl, "chargeNotAvailable", tag, pos, seq_end));
1341 		break;
1342 	case ASN1_CLASS_CONTEXT_SPECIFIC | 1:
1343 		aoc_final->type = 1;	/* free_of_charge */
1344 		ASN1_CALL(pos, asn1_dec_null(ctrl, "freeOfCharge", tag, pos, seq_end));
1345 		break;
1346 	case ASN1_TAG_SEQUENCE:
1347 		aoc_final->type = 2;	/* specific_currency */
1348 		if (ctrl->debug & PRI_DEBUG_APDU) {
1349 			pri_message(ctrl, "  specificCurrency %s\n", asn1_tag2str(tag));
1350 		}
1351 		ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
1352 		ASN1_END_SETUP(specific_end, specific_offset, length, pos, seq_end);
1353 
1354 		ASN1_CALL(pos, asn1_dec_tag(pos, specific_end, &tag));
1355 		ASN1_CHECK_TAG(ctrl, tag, tag,
1356 			ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 1);
1357 		ASN1_CALL(pos, rose_dec_qsig_AOC_RecordedCurrency(ctrl, "recordedCurrency", tag,
1358 			pos, specific_end, &aoc_final->specific.recorded));
1359 
1360 		if (pos < specific_end && *pos != ASN1_INDEF_TERM) {
1361 			ASN1_CALL(pos, asn1_dec_tag(pos, specific_end, &tag));
1362 			ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_CLASS_CONTEXT_SPECIFIC | 2);
1363 			ASN1_CALL(pos, asn1_dec_int(ctrl, "finalBillingId", tag, pos, specific_end,
1364 				&value));
1365 			aoc_final->specific.billing_id = value;
1366 			aoc_final->specific.billing_id_present = 1;
1367 		} else {
1368 			aoc_final->specific.billing_id_present = 0;
1369 		}
1370 
1371 		ASN1_END_FIXUP(ctrl, pos, specific_offset, specific_end, seq_end);
1372 		break;
1373 	default:
1374 		ASN1_DID_NOT_EXPECT_TAG(ctrl, tag);
1375 		return NULL;
1376 	}
1377 
1378 	/*
1379 	 * A sequence specifies an ordered list of component types.
1380 	 * However, for simplicity we are not checking the order of
1381 	 * the remaining optional components.
1382 	 */
1383 	aoc_final->charging_association_present = 0;
1384 	while (pos < seq_end && *pos != ASN1_INDEF_TERM) {
1385 		save_pos = pos;
1386 		ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1387 		switch (tag) {
1388 		case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 0:
1389 		case ASN1_TYPE_INTEGER:
1390 			ASN1_CALL(pos, rose_dec_qsig_AOC_ChargingAssociation(ctrl,
1391 				"chargingAssociation", tag, pos, seq_end,
1392 				&aoc_final->charging_association));
1393 			aoc_final->charging_association_present = 1;
1394 			break;
1395 		case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 1:
1396 		case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 2:
1397 			if (ctrl->debug & PRI_DEBUG_APDU) {
1398 				pri_message(ctrl, "  finalArgExtension %s\n", asn1_tag2str(tag));
1399 			}
1400 			/* Fixup will skip over the manufacturer extension information */
1401 		default:
1402 			pos = save_pos;
1403 			goto cancel_options;
1404 		}
1405 	}
1406 cancel_options:;
1407 
1408 	ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
1409 
1410 	return pos;
1411 }
1412 
1413 /*!
1414  * \brief Decode the Q.SIG AocInterim invoke argument parameters.
1415  *
1416  * \param ctrl D channel controller for diagnostic messages or global options.
1417  * \param tag Component tag that identified this structure.
1418  * \param pos Starting position of the ASN.1 component length.
1419  * \param end End of ASN.1 decoding data buffer.
1420  * \param args Arguments to fill in from the decoded buffer.
1421  *
1422  * \retval Start of the next ASN.1 component on success.
1423  * \retval NULL on error.
1424  */
rose_dec_qsig_AocInterim_ARG(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_invoke_args * args)1425 const unsigned char *rose_dec_qsig_AocInterim_ARG(struct pri *ctrl, unsigned tag,
1426 	const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
1427 {
1428 	int32_t value;
1429 	int length;
1430 	int seq_offset;
1431 	int specific_offset;
1432 	const unsigned char *seq_end;
1433 	const unsigned char *specific_end;
1434 	struct roseQsigAocInterimArg_ARG *aoc_interim;
1435 
1436 	aoc_interim = &args->qsig.AocInterim;
1437 
1438 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
1439 	if (ctrl->debug & PRI_DEBUG_APDU) {
1440 		pri_message(ctrl, "  AocInterim %s\n", asn1_tag2str(tag));
1441 	}
1442 	ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
1443 	ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
1444 
1445 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1446 	switch (tag) {
1447 	case ASN1_CLASS_CONTEXT_SPECIFIC | 0:
1448 		aoc_interim->type = 0;	/* charge_not_available */
1449 		ASN1_CALL(pos, asn1_dec_null(ctrl, "chargeNotAvailable", tag, pos, seq_end));
1450 		break;
1451 	case ASN1_CLASS_CONTEXT_SPECIFIC | 1:
1452 		aoc_interim->type = 1;	/* free_of_charge */
1453 		ASN1_CALL(pos, asn1_dec_null(ctrl, "freeOfCharge", tag, pos, seq_end));
1454 		break;
1455 	case ASN1_TAG_SEQUENCE:
1456 		aoc_interim->type = 2;	/* specific_currency */
1457 		if (ctrl->debug & PRI_DEBUG_APDU) {
1458 			pri_message(ctrl, "  specificCurrency %s\n", asn1_tag2str(tag));
1459 		}
1460 		ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
1461 		ASN1_END_SETUP(specific_end, specific_offset, length, pos, seq_end);
1462 
1463 		ASN1_CALL(pos, asn1_dec_tag(pos, specific_end, &tag));
1464 		ASN1_CHECK_TAG(ctrl, tag, tag,
1465 			ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 1);
1466 		ASN1_CALL(pos, rose_dec_qsig_AOC_RecordedCurrency(ctrl, "recordedCurrency", tag,
1467 			pos, specific_end, &aoc_interim->specific.recorded));
1468 
1469 		if (pos < specific_end && *pos != ASN1_INDEF_TERM) {
1470 			ASN1_CALL(pos, asn1_dec_tag(pos, specific_end, &tag));
1471 			ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_CLASS_CONTEXT_SPECIFIC | 2);
1472 			ASN1_CALL(pos, asn1_dec_int(ctrl, "interimBillingId", tag, pos, specific_end,
1473 				&value));
1474 			aoc_interim->specific.billing_id = value;
1475 			aoc_interim->specific.billing_id_present = 1;
1476 		} else {
1477 			aoc_interim->specific.billing_id_present = 0;
1478 		}
1479 
1480 		ASN1_END_FIXUP(ctrl, pos, specific_offset, specific_end, seq_end);
1481 		break;
1482 	default:
1483 		ASN1_DID_NOT_EXPECT_TAG(ctrl, tag);
1484 		return NULL;
1485 	}
1486 
1487 	/* Fixup will skip over any OPTIONAL manufacturer extension information */
1488 	ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
1489 
1490 	return pos;
1491 }
1492 
1493 /*!
1494  * \brief Decode the Q.SIG AocRate invoke argument parameters.
1495  *
1496  * \param ctrl D channel controller for diagnostic messages or global options.
1497  * \param tag Component tag that identified this structure.
1498  * \param pos Starting position of the ASN.1 component length.
1499  * \param end End of ASN.1 decoding data buffer.
1500  * \param args Arguments to fill in from the decoded buffer.
1501  *
1502  * \retval Start of the next ASN.1 component on success.
1503  * \retval NULL on error.
1504  */
rose_dec_qsig_AocRate_ARG(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_invoke_args * args)1505 const unsigned char *rose_dec_qsig_AocRate_ARG(struct pri *ctrl, unsigned tag,
1506 	const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
1507 {
1508 	int length;
1509 	int seq_offset;
1510 	const unsigned char *seq_end;
1511 	struct roseQsigAocRateArg_ARG *aoc_rate;
1512 
1513 	aoc_rate = &args->qsig.AocRate;
1514 
1515 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
1516 	if (ctrl->debug & PRI_DEBUG_APDU) {
1517 		pri_message(ctrl, "  AocRate %s\n", asn1_tag2str(tag));
1518 	}
1519 	ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
1520 	ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
1521 
1522 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1523 	switch (tag) {
1524 	case ASN1_TYPE_NULL:
1525 		aoc_rate->type = 0;	/* charge_not_available */
1526 		ASN1_CALL(pos, asn1_dec_null(ctrl, "chargeNotAvailable", tag, pos, seq_end));
1527 		break;
1528 	case ASN1_TAG_SEQUENCE:
1529 		aoc_rate->type = 1;	/* currency_info_list */
1530 		ASN1_CALL(pos, rose_dec_qsig_AOCSCurrencyInfoList(ctrl, "aocSCurrencyInfoList",
1531 			tag, pos, seq_end, &aoc_rate->currency_info));
1532 		break;
1533 	default:
1534 		ASN1_DID_NOT_EXPECT_TAG(ctrl, tag);
1535 		return NULL;
1536 	}
1537 
1538 	/* Fixup will skip over any OPTIONAL manufacturer extension information */
1539 	ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
1540 
1541 	return pos;
1542 }
1543 
1544 /*!
1545  * \brief Decode the Q.SIG AocComplete invoke argument parameters.
1546  *
1547  * \param ctrl D channel controller for diagnostic messages or global options.
1548  * \param tag Component tag that identified this structure.
1549  * \param pos Starting position of the ASN.1 component length.
1550  * \param end End of ASN.1 decoding data buffer.
1551  * \param args Arguments to fill in from the decoded buffer.
1552  *
1553  * \retval Start of the next ASN.1 component on success.
1554  * \retval NULL on error.
1555  */
rose_dec_qsig_AocComplete_ARG(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_invoke_args * args)1556 const unsigned char *rose_dec_qsig_AocComplete_ARG(struct pri *ctrl, unsigned tag,
1557 	const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
1558 {
1559 	int length;
1560 	int seq_offset;
1561 	const unsigned char *seq_end;
1562 	const unsigned char *save_pos;
1563 	struct roseQsigAocCompleteArg_ARG *aoc_complete;
1564 
1565 	aoc_complete = &args->qsig.AocComplete;
1566 
1567 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
1568 	if (ctrl->debug & PRI_DEBUG_APDU) {
1569 		pri_message(ctrl, "  AocComplete %s\n", asn1_tag2str(tag));
1570 	}
1571 	ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
1572 	ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
1573 
1574 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1575 	ASN1_CALL(pos, rose_dec_PartyNumber(ctrl, "chargedUser", tag, pos, seq_end,
1576 		&aoc_complete->charged_user_number));
1577 
1578 	/*
1579 	 * A sequence specifies an ordered list of component types.
1580 	 * However, for simplicity we are not checking the order of
1581 	 * the remaining optional components.
1582 	 */
1583 	aoc_complete->charging_association_present = 0;
1584 	while (pos < seq_end && *pos != ASN1_INDEF_TERM) {
1585 		save_pos = pos;
1586 		ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1587 		switch (tag) {
1588 		case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 0:
1589 		case ASN1_TYPE_INTEGER:
1590 			ASN1_CALL(pos, rose_dec_qsig_AOC_ChargingAssociation(ctrl,
1591 				"chargingAssociation", tag, pos, seq_end,
1592 				&aoc_complete->charging_association));
1593 			aoc_complete->charging_association_present = 1;
1594 			break;
1595 		case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 1:
1596 		case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 2:
1597 			if (ctrl->debug & PRI_DEBUG_APDU) {
1598 				pri_message(ctrl, "  completeArgExtension %s\n", asn1_tag2str(tag));
1599 			}
1600 			/* Fixup will skip over the manufacturer extension information */
1601 		default:
1602 			pos = save_pos;
1603 			goto cancel_options;
1604 		}
1605 	}
1606 cancel_options:;
1607 
1608 	ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
1609 
1610 	return pos;
1611 }
1612 
1613 /*!
1614  * \brief Decode the Q.SIG AocComplete result argument parameters.
1615  *
1616  * \param ctrl D channel controller for diagnostic messages or global options.
1617  * \param tag Component tag that identified this structure.
1618  * \param pos Starting position of the ASN.1 component length.
1619  * \param end End of ASN.1 decoding data buffer.
1620  * \param args Arguments to fill in from the decoded buffer.
1621  *
1622  * \retval Start of the next ASN.1 component on success.
1623  * \retval NULL on error.
1624  */
rose_dec_qsig_AocComplete_RES(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_result_args * args)1625 const unsigned char *rose_dec_qsig_AocComplete_RES(struct pri *ctrl, unsigned tag,
1626 	const unsigned char *pos, const unsigned char *end, union rose_msg_result_args *args)
1627 {
1628 	int32_t value;
1629 	int length;
1630 	int seq_offset;
1631 	const unsigned char *seq_end;
1632 	struct roseQsigAocCompleteRes_RES *aoc_complete;
1633 
1634 	aoc_complete = &args->qsig.AocComplete;
1635 
1636 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
1637 	if (ctrl->debug & PRI_DEBUG_APDU) {
1638 		pri_message(ctrl, "  AocComplete %s\n", asn1_tag2str(tag));
1639 	}
1640 	ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
1641 	ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
1642 
1643 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1644 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_ENUMERATED);
1645 	ASN1_CALL(pos, asn1_dec_int(ctrl, "chargingOption", tag, pos, seq_end, &value));
1646 	aoc_complete->charging_option = value;
1647 
1648 	/* Fixup will skip over any OPTIONAL manufacturer extension information */
1649 	ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
1650 
1651 	return pos;
1652 }
1653 
1654 /*!
1655  * \brief Decode the Q.SIG AocDivChargeReq invoke argument parameters.
1656  *
1657  * \param ctrl D channel controller for diagnostic messages or global options.
1658  * \param tag Component tag that identified this structure.
1659  * \param pos Starting position of the ASN.1 component length.
1660  * \param end End of ASN.1 decoding data buffer.
1661  * \param args Arguments to fill in from the decoded buffer.
1662  *
1663  * \retval Start of the next ASN.1 component on success.
1664  * \retval NULL on error.
1665  */
rose_dec_qsig_AocDivChargeReq_ARG(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_invoke_args * args)1666 const unsigned char *rose_dec_qsig_AocDivChargeReq_ARG(struct pri *ctrl, unsigned tag,
1667 	const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
1668 {
1669 	int32_t value;
1670 	int length;
1671 	int seq_offset;
1672 	const unsigned char *seq_end;
1673 	struct roseQsigAocDivChargeReqArg_ARG *aoc_div_charge_req;
1674 
1675 	aoc_div_charge_req = &args->qsig.AocDivChargeReq;
1676 
1677 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
1678 	if (ctrl->debug & PRI_DEBUG_APDU) {
1679 		pri_message(ctrl, "  AocDivChargeReq %s\n", asn1_tag2str(tag));
1680 	}
1681 	ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
1682 	ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
1683 
1684 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1685 	ASN1_CALL(pos, rose_dec_PartyNumber(ctrl, "divertingUser", tag, pos, seq_end,
1686 		&aoc_div_charge_req->diverting_user_number));
1687 
1688 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1689 	switch (tag) {
1690 	case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 0:
1691 	case ASN1_TYPE_INTEGER:
1692 		ASN1_CALL(pos, rose_dec_qsig_AOC_ChargingAssociation(ctrl, "chargingAssociation",
1693 			tag, pos, seq_end, &aoc_div_charge_req->charging_association));
1694 		aoc_div_charge_req->charging_association_present = 1;
1695 
1696 		ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1697 		break;
1698 	default:
1699 		aoc_div_charge_req->charging_association_present = 0;
1700 		break;
1701 	}
1702 
1703 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_ENUMERATED);
1704 	ASN1_CALL(pos, asn1_dec_int(ctrl, "diversionType", tag, pos, seq_end, &value));
1705 	aoc_div_charge_req->diversion_type = value;
1706 
1707 	/* Fixup will skip over any OPTIONAL manufacturer extension information */
1708 	ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
1709 
1710 	return pos;
1711 }
1712 
1713 /* ------------------------------------------------------------------- */
1714 /* end rose_qsig_aoc.c */
1715