1 /*
2  * libpri: An implementation of Primary Rate ISDN
3  *
4  * Copyright (C) 2009 Digium, Inc.
5  *
6  * Richard Mudgett <rmudgett@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2 as published by the
16  * Free Software Foundation. See the LICENSE file included with
17  * this program for more details.
18  *
19  * In addition, when this program is distributed with Asterisk in
20  * any form that would qualify as a 'combined work' or as a
21  * 'derivative work' (but not mere aggregation), you can redistribute
22  * and/or modify the combination under the terms of the license
23  * provided with that copy of Asterisk, instead of the license
24  * terms granted here.
25  */
26 
27 /*!
28  * \file
29  * \brief ROSE Advice Of Charge (AOC) operations
30  *
31  * Advice of Charge (AOC) supplementary service EN 300 182-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_etsi_AOC_Time(struct pri * ctrl,unsigned char * pos,unsigned char * end,unsigned tag,const struct roseEtsiAOCTime * time)62 static unsigned char *rose_enc_etsi_AOC_Time(struct pri *ctrl, unsigned char *pos,
63 	unsigned char *end, unsigned tag, const struct roseEtsiAOCTime *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_etsi_AOC_Amount(struct pri * ctrl,unsigned char * pos,unsigned char * end,unsigned tag,const struct roseEtsiAOCAmount * amount)93 static unsigned char *rose_enc_etsi_AOC_Amount(struct pri *ctrl, unsigned char *pos,
94 	unsigned char *end, unsigned tag, const struct roseEtsiAOCAmount *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_etsi_AOC_RecordedCurrency(struct pri * ctrl,unsigned char * pos,unsigned char * end,unsigned tag,const struct roseEtsiAOCRecordedCurrency * recorded)125 static unsigned char *rose_enc_etsi_AOC_RecordedCurrency(struct pri *ctrl,
126 	unsigned char *pos, unsigned char *end, unsigned tag,
127 	const struct roseEtsiAOCRecordedCurrency *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_etsi_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_etsi_AOC_DurationCurrency(struct pri * ctrl,unsigned char * pos,unsigned char * end,unsigned tag,const struct roseEtsiAOCDurationCurrency * duration)158 static unsigned char *rose_enc_etsi_AOC_DurationCurrency(struct pri *ctrl,
159 	unsigned char *pos, unsigned char *end, unsigned tag,
160 	const struct roseEtsiAOCDurationCurrency *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_etsi_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_etsi_AOC_Time(ctrl, pos, end,
173 		ASN1_CLASS_CONTEXT_SPECIFIC | 4, &duration->time));
174 	if (duration->granularity_present) {
175 		ASN1_CALL(pos, rose_enc_etsi_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_etsi_AOC_FlatRateCurrency(struct pri * ctrl,unsigned char * pos,unsigned char * end,unsigned tag,const struct roseEtsiAOCFlatRateCurrency * flat_rate)199 static unsigned char *rose_enc_etsi_AOC_FlatRateCurrency(struct pri *ctrl,
200 	unsigned char *pos, unsigned char *end, unsigned tag,
201 	const struct roseEtsiAOCFlatRateCurrency *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_etsi_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_etsi_AOC_VolumeRateCurrency(struct pri * ctrl,unsigned char * pos,unsigned char * end,unsigned tag,const struct roseEtsiAOCVolumeRateCurrency * volume_rate)232 static unsigned char *rose_enc_etsi_AOC_VolumeRateCurrency(struct pri *ctrl,
233 	unsigned char *pos, unsigned char *end, unsigned tag,
234 	const struct roseEtsiAOCVolumeRateCurrency *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_etsi_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_etsi_AOCSCurrencyInfo(struct pri * ctrl,unsigned char * pos,unsigned char * end,unsigned tag,const struct roseEtsiAOCSCurrencyInfo * currency_info)267 static unsigned char *rose_enc_etsi_AOCSCurrencyInfo(struct pri *ctrl,
268 	unsigned char *pos, unsigned char *end, unsigned tag,
269 	const struct roseEtsiAOCSCurrencyInfo *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_etsi_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_etsi_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_etsi_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 	default:
302 		ASN1_ENC_ERROR(ctrl, "Unknown currency type");
303 		return NULL;
304 	}
305 
306 	ASN1_CONSTRUCTED_END(seq_len, pos, end);
307 
308 	return pos;
309 }
310 
311 /*!
312  * \internal
313  * \brief Encode the AOCSCurrencyInfoList type.
314  *
315  * \param ctrl D channel controller for diagnostic messages or global options.
316  * \param pos Starting position to encode ASN.1 component.
317  * \param end End of ASN.1 encoding data buffer.
318  * \param tag Component tag to identify the encoded component.
319  *   The tag should be ASN1_TAG_SEQUENCE unless the caller implicitly
320  *   tags it otherwise.
321  * \param currency_info Currency information list to encode.
322  *
323  * \retval Start of the next ASN.1 component to encode on success.
324  * \retval NULL on error.
325  */
rose_enc_etsi_AOCSCurrencyInfoList(struct pri * ctrl,unsigned char * pos,unsigned char * end,unsigned tag,const struct roseEtsiAOCSCurrencyInfoList * currency_info)326 static unsigned char *rose_enc_etsi_AOCSCurrencyInfoList(struct pri *ctrl,
327 	unsigned char *pos, unsigned char *end, unsigned tag,
328 	const struct roseEtsiAOCSCurrencyInfoList *currency_info)
329 {
330 	unsigned index;
331 	unsigned char *seq_len;
332 
333 	ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, tag);
334 
335 	for (index = 0; index < currency_info->num_records; ++index) {
336 		ASN1_CALL(pos, rose_enc_etsi_AOCSCurrencyInfo(ctrl, pos, end, ASN1_TAG_SEQUENCE,
337 			&currency_info->list[index]));
338 	}
339 
340 	ASN1_CONSTRUCTED_END(seq_len, pos, end);
341 
342 	return pos;
343 }
344 
345 /*!
346  * \internal
347  * \brief Encode the RecordedUnits type.
348  *
349  * \param ctrl D channel controller for diagnostic messages or global options.
350  * \param pos Starting position to encode ASN.1 component.
351  * \param end End of ASN.1 encoding data buffer.
352  * \param tag Component tag to identify the encoded component.
353  *   The tag should be ASN1_TAG_SEQUENCE unless the caller implicitly
354  *   tags it otherwise.
355  * \param recorded Recorded units information record to encode.
356  *
357  * \retval Start of the next ASN.1 component to encode on success.
358  * \retval NULL on error.
359  */
rose_enc_etsi_AOC_RecordedUnits(struct pri * ctrl,unsigned char * pos,unsigned char * end,unsigned tag,const struct roseEtsiAOCRecordedUnits * recorded)360 static unsigned char *rose_enc_etsi_AOC_RecordedUnits(struct pri *ctrl,
361 	unsigned char *pos, unsigned char *end, unsigned tag,
362 	const struct roseEtsiAOCRecordedUnits *recorded)
363 {
364 	unsigned char *seq_len;
365 
366 	ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, tag);
367 
368 	if (recorded->not_available) {
369 		ASN1_CALL(pos, asn1_enc_null(pos, end, ASN1_TYPE_NULL));
370 	} else {
371 		ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_INTEGER,
372 			recorded->number_of_units));
373 	}
374 
375 	if (recorded->type_of_unit_present) {
376 		ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_INTEGER,
377 			recorded->type_of_unit));
378 	}
379 
380 	ASN1_CONSTRUCTED_END(seq_len, pos, end);
381 
382 	return pos;
383 }
384 
385 /*!
386  * \internal
387  * \brief Encode the RecordedUnitsList type.
388  *
389  * \param ctrl D channel controller for diagnostic messages or global options.
390  * \param pos Starting position to encode ASN.1 component.
391  * \param end End of ASN.1 encoding data buffer.
392  * \param tag Component tag to identify the encoded component.
393  *   The tag should be ASN1_TAG_SEQUENCE unless the caller implicitly
394  *   tags it otherwise.
395  * \param recorded_info Recorded units information list to encode.
396  *
397  * \retval Start of the next ASN.1 component to encode on success.
398  * \retval NULL on error.
399  */
rose_enc_etsi_AOC_RecordedUnitsList(struct pri * ctrl,unsigned char * pos,unsigned char * end,unsigned tag,const struct roseEtsiAOCRecordedUnitsList * recorded_info)400 static unsigned char *rose_enc_etsi_AOC_RecordedUnitsList(struct pri *ctrl,
401 	unsigned char *pos, unsigned char *end, unsigned tag,
402 	const struct roseEtsiAOCRecordedUnitsList *recorded_info)
403 {
404 	unsigned index;
405 	unsigned char *seq_len;
406 
407 	ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, tag);
408 
409 	for (index = 0; index < recorded_info->num_records; ++index) {
410 		ASN1_CALL(pos, rose_enc_etsi_AOC_RecordedUnits(ctrl, pos, end, ASN1_TAG_SEQUENCE,
411 			&recorded_info->list[index]));
412 	}
413 
414 	ASN1_CONSTRUCTED_END(seq_len, pos, end);
415 
416 	return pos;
417 }
418 
419 /*!
420  * \internal
421  * \brief Encode the ChargingAssociation type.
422  *
423  * \param ctrl D channel controller for diagnostic messages or global options.
424  * \param pos Starting position to encode ASN.1 component.
425  * \param end End of ASN.1 encoding data buffer.
426  * \param charging Charging association information to encode.
427  *
428  * \retval Start of the next ASN.1 component to encode on success.
429  * \retval NULL on error.
430  */
rose_enc_etsi_AOC_ChargingAssociation(struct pri * ctrl,unsigned char * pos,unsigned char * end,const struct roseEtsiAOCChargingAssociation * charging)431 static unsigned char *rose_enc_etsi_AOC_ChargingAssociation(struct pri *ctrl,
432 	unsigned char *pos, unsigned char *end,
433 	const struct roseEtsiAOCChargingAssociation *charging)
434 {
435 	unsigned char *explicit_len;
436 
437 	switch (charging->type) {
438 	case 0:	/* charge_identifier */
439 		ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_INTEGER, charging->id));
440 		break;
441 	case 1:	/* charged_number */
442 		/* EXPLICIT tag */
443 		ASN1_CONSTRUCTED_BEGIN(explicit_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 0);
444 		ASN1_CALL(pos, rose_enc_PartyNumber(ctrl, pos, end, &charging->number));
445 		ASN1_CONSTRUCTED_END(explicit_len, pos, end);
446 		break;
447 	default:
448 		ASN1_ENC_ERROR(ctrl, "Unknown ChargingAssociation type");
449 		return NULL;
450 	}
451 
452 	return pos;
453 }
454 
455 /*!
456  * \internal
457  * \brief Encode the AOCECurrencyInfo type.
458  *
459  * \param ctrl D channel controller for diagnostic messages or global options.
460  * \param pos Starting position to encode ASN.1 component.
461  * \param end End of ASN.1 encoding data buffer.
462  * \param tag Component tag to identify the encoded component.
463  *   The tag should be ASN1_TAG_SEQUENCE unless the caller implicitly
464  *   tags it otherwise.
465  * \param currency_info Currency information to encode.
466  *
467  * \retval Start of the next ASN.1 component to encode on success.
468  * \retval NULL on error.
469  */
rose_enc_etsi_AOCECurrencyInfo(struct pri * ctrl,unsigned char * pos,unsigned char * end,unsigned tag,const struct roseEtsiAOCECurrencyInfo * currency_info)470 static unsigned char *rose_enc_etsi_AOCECurrencyInfo(struct pri *ctrl,
471 	unsigned char *pos, unsigned char *end, unsigned tag,
472 	const struct roseEtsiAOCECurrencyInfo *currency_info)
473 {
474 	unsigned char *seq_len;
475 	unsigned char *specific_seq_len;
476 
477 	ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, tag);
478 
479 	if (currency_info->free_of_charge) {
480 		ASN1_CALL(pos, asn1_enc_null(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 1));
481 	} else {
482 		ASN1_CONSTRUCTED_BEGIN(specific_seq_len, pos, end, ASN1_TAG_SEQUENCE);
483 
484 		ASN1_CALL(pos, rose_enc_etsi_AOC_RecordedCurrency(ctrl, pos, end,
485 			ASN1_CLASS_CONTEXT_SPECIFIC | 1, &currency_info->specific.recorded));
486 
487 		if (currency_info->specific.billing_id_present) {
488 			ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 2,
489 				currency_info->specific.billing_id));
490 		}
491 
492 		ASN1_CONSTRUCTED_END(specific_seq_len, pos, end);
493 	}
494 
495 	if (currency_info->charging_association_present) {
496 		ASN1_CALL(pos, rose_enc_etsi_AOC_ChargingAssociation(ctrl, pos, end,
497 			&currency_info->charging_association));
498 	}
499 
500 	ASN1_CONSTRUCTED_END(seq_len, pos, end);
501 
502 	return pos;
503 }
504 
505 /*!
506  * \internal
507  * \brief Encode the AOCEChargingUnitInfo type.
508  *
509  * \param ctrl D channel controller for diagnostic messages or global options.
510  * \param pos Starting position to encode ASN.1 component.
511  * \param end End of ASN.1 encoding data buffer.
512  * \param tag Component tag to identify the encoded component.
513  *   The tag should be ASN1_TAG_SEQUENCE unless the caller implicitly
514  *   tags it otherwise.
515  * \param charging_unit Charging unit information to encode.
516  *
517  * \retval Start of the next ASN.1 component to encode on success.
518  * \retval NULL on error.
519  */
rose_enc_etsi_AOCEChargingUnitInfo(struct pri * ctrl,unsigned char * pos,unsigned char * end,unsigned tag,const struct roseEtsiAOCEChargingUnitInfo * charging_unit)520 static unsigned char *rose_enc_etsi_AOCEChargingUnitInfo(struct pri *ctrl,
521 	unsigned char *pos, unsigned char *end, unsigned tag,
522 	const struct roseEtsiAOCEChargingUnitInfo *charging_unit)
523 {
524 	unsigned char *seq_len;
525 	unsigned char *specific_seq_len;
526 
527 	ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, tag);
528 
529 	if (charging_unit->free_of_charge) {
530 		ASN1_CALL(pos, asn1_enc_null(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 1));
531 	} else {
532 		ASN1_CONSTRUCTED_BEGIN(specific_seq_len, pos, end, ASN1_TAG_SEQUENCE);
533 
534 		ASN1_CALL(pos, rose_enc_etsi_AOC_RecordedUnitsList(ctrl, pos, end,
535 			ASN1_CLASS_CONTEXT_SPECIFIC | 1, &charging_unit->specific.recorded));
536 
537 		if (charging_unit->specific.billing_id_present) {
538 			ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 2,
539 				charging_unit->specific.billing_id));
540 		}
541 
542 		ASN1_CONSTRUCTED_END(specific_seq_len, pos, end);
543 	}
544 
545 	if (charging_unit->charging_association_present) {
546 		ASN1_CALL(pos, rose_enc_etsi_AOC_ChargingAssociation(ctrl, pos, end,
547 			&charging_unit->charging_association));
548 	}
549 
550 	ASN1_CONSTRUCTED_END(seq_len, pos, end);
551 
552 	return pos;
553 }
554 
555 /*!
556  * \brief Encode the ChargingRequest invoke facility ie arguments.
557  *
558  * \param ctrl D channel controller for diagnostic messages or global options.
559  * \param pos Starting position to encode ASN.1 component.
560  * \param end End of ASN.1 encoding data buffer.
561  * \param args Arguments to encode in the buffer.
562  *
563  * \retval Start of the next ASN.1 component to encode on success.
564  * \retval NULL on error.
565  */
rose_enc_etsi_ChargingRequest_ARG(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_invoke_args * args)566 unsigned char *rose_enc_etsi_ChargingRequest_ARG(struct pri *ctrl, unsigned char *pos,
567 	unsigned char *end, const union rose_msg_invoke_args *args)
568 {
569 	return asn1_enc_int(pos, end, ASN1_TYPE_ENUMERATED,
570 		args->etsi.ChargingRequest.charging_case);
571 }
572 
573 /*!
574  * \brief Encode the ChargingRequest result facility ie arguments.
575  *
576  * \param ctrl D channel controller for diagnostic messages or global options.
577  * \param pos Starting position to encode ASN.1 component.
578  * \param end End of ASN.1 encoding data buffer.
579  * \param args Arguments to encode in the buffer.
580  *
581  * \retval Start of the next ASN.1 component to encode on success.
582  * \retval NULL on error.
583  */
rose_enc_etsi_ChargingRequest_RES(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_result_args * args)584 unsigned char *rose_enc_etsi_ChargingRequest_RES(struct pri *ctrl, unsigned char *pos,
585 	unsigned char *end, const union rose_msg_result_args *args)
586 {
587 	switch (args->etsi.ChargingRequest.type) {
588 	case 0:	/* currency_info_list */
589 		ASN1_CALL(pos, rose_enc_etsi_AOCSCurrencyInfoList(ctrl, pos, end,
590 			ASN1_TAG_SEQUENCE, &args->etsi.ChargingRequest.u.currency_info));
591 		break;
592 	case 1:	/* special_arrangement_info */
593 		ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_INTEGER,
594 			args->etsi.ChargingRequest.u.special_arrangement));
595 		break;
596 	case 2:	/* charging_info_follows */
597 		ASN1_CALL(pos, asn1_enc_null(pos, end, ASN1_TYPE_NULL));
598 		break;
599 	default:
600 		ASN1_ENC_ERROR(ctrl, "Unknown ChargingRequst type");
601 		return NULL;
602 	}
603 
604 	return pos;
605 }
606 
607 /*!
608  * \brief Encode the AOCSCurrency 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_etsi_AOCSCurrency_ARG(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_invoke_args * args)618 unsigned char *rose_enc_etsi_AOCSCurrency_ARG(struct pri *ctrl, unsigned char *pos,
619 	unsigned char *end, const union rose_msg_invoke_args *args)
620 {
621 	switch (args->etsi.AOCSCurrency.type) {
622 	case 0:	/* charge_not_available */
623 		ASN1_CALL(pos, asn1_enc_null(pos, end, ASN1_TYPE_NULL));
624 		break;
625 	case 1:	/* currency_info_list */
626 		if (args->etsi.AOCSCurrency.currency_info.num_records) {
627 			ASN1_CALL(pos, rose_enc_etsi_AOCSCurrencyInfoList(ctrl, pos, end,
628 				ASN1_TAG_SEQUENCE, &args->etsi.AOCSCurrency.currency_info));
629 		} else {
630 			/* There were no records so encode as charge_not_available */
631 			ASN1_CALL(pos, asn1_enc_null(pos, end, ASN1_TYPE_NULL));
632 		}
633 		break;
634 	default:
635 		ASN1_ENC_ERROR(ctrl, "Unknown AOCSCurrency type");
636 		return NULL;
637 	}
638 
639 	return pos;
640 }
641 
642 /*!
643  * \brief Encode the AOCSSpecialArr invoke facility ie arguments.
644  *
645  * \param ctrl D channel controller for diagnostic messages or global options.
646  * \param pos Starting position to encode ASN.1 component.
647  * \param end End of ASN.1 encoding data buffer.
648  * \param args Arguments to encode in the buffer.
649  *
650  * \retval Start of the next ASN.1 component to encode on success.
651  * \retval NULL on error.
652  */
rose_enc_etsi_AOCSSpecialArr_ARG(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_invoke_args * args)653 unsigned char *rose_enc_etsi_AOCSSpecialArr_ARG(struct pri *ctrl, unsigned char *pos,
654 	unsigned char *end, const union rose_msg_invoke_args *args)
655 {
656 	switch (args->etsi.AOCSSpecialArr.type) {
657 	case 0:	/* charge_not_available */
658 		ASN1_CALL(pos, asn1_enc_null(pos, end, ASN1_TYPE_NULL));
659 		break;
660 	case 1:	/* special_arrangement_info */
661 		ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_INTEGER,
662 			args->etsi.AOCSSpecialArr.special_arrangement));
663 		break;
664 	default:
665 		ASN1_ENC_ERROR(ctrl, "Unknown AOCSSpecialArr type");
666 		return NULL;
667 	}
668 
669 	return pos;
670 }
671 
672 /*!
673  * \brief Encode the AOCDCurrency invoke facility ie arguments.
674  *
675  * \param ctrl D channel controller for diagnostic messages or global options.
676  * \param pos Starting position to encode ASN.1 component.
677  * \param end End of ASN.1 encoding data buffer.
678  * \param args Arguments to encode in the buffer.
679  *
680  * \retval Start of the next ASN.1 component to encode on success.
681  * \retval NULL on error.
682  */
rose_enc_etsi_AOCDCurrency_ARG(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_invoke_args * args)683 unsigned char *rose_enc_etsi_AOCDCurrency_ARG(struct pri *ctrl, unsigned char *pos,
684 	unsigned char *end, const union rose_msg_invoke_args *args)
685 {
686 	const struct roseEtsiAOCDCurrency_ARG *aoc_d;
687 	unsigned char *seq_len;
688 
689 	aoc_d = &args->etsi.AOCDCurrency;
690 	switch (aoc_d->type) {
691 	case 0:	/* charge_not_available */
692 		ASN1_CALL(pos, asn1_enc_null(pos, end, ASN1_TYPE_NULL));
693 		break;
694 	case 1:	/* free_of_charge */
695 		ASN1_CALL(pos, asn1_enc_null(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 1));
696 		break;
697 	case 2:	/* specific_currency */
698 		ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
699 
700 		ASN1_CALL(pos, rose_enc_etsi_AOC_RecordedCurrency(ctrl, pos, end,
701 			ASN1_CLASS_CONTEXT_SPECIFIC | 1, &aoc_d->specific.recorded));
702 		ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 2,
703 			aoc_d->specific.type_of_charging_info));
704 		if (aoc_d->specific.billing_id_present) {
705 			ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 3,
706 				aoc_d->specific.billing_id));
707 		}
708 
709 		ASN1_CONSTRUCTED_END(seq_len, pos, end);
710 		break;
711 	default:
712 		ASN1_ENC_ERROR(ctrl, "Unknown AOCDCurrency type");
713 		return NULL;
714 	}
715 
716 	return pos;
717 }
718 
719 /*!
720  * \brief Encode the AOCDChargingUnit invoke facility ie arguments.
721  *
722  * \param ctrl D channel controller for diagnostic messages or global options.
723  * \param pos Starting position to encode ASN.1 component.
724  * \param end End of ASN.1 encoding data buffer.
725  * \param args Arguments to encode in the buffer.
726  *
727  * \retval Start of the next ASN.1 component to encode on success.
728  * \retval NULL on error.
729  */
rose_enc_etsi_AOCDChargingUnit_ARG(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_invoke_args * args)730 unsigned char *rose_enc_etsi_AOCDChargingUnit_ARG(struct pri *ctrl, unsigned char *pos,
731 	unsigned char *end, const union rose_msg_invoke_args *args)
732 {
733 	const struct roseEtsiAOCDChargingUnit_ARG *aoc_d;
734 	unsigned char *seq_len;
735 
736 	aoc_d = &args->etsi.AOCDChargingUnit;
737 	switch (aoc_d->type) {
738 	case 0:	/* charge_not_available */
739 		ASN1_CALL(pos, asn1_enc_null(pos, end, ASN1_TYPE_NULL));
740 		break;
741 	case 1:	/* free_of_charge */
742 		ASN1_CALL(pos, asn1_enc_null(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 1));
743 		break;
744 	case 2:	/* specific_charging_units */
745 		ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
746 
747 		ASN1_CALL(pos, rose_enc_etsi_AOC_RecordedUnitsList(ctrl, pos, end,
748 			ASN1_CLASS_CONTEXT_SPECIFIC | 1, &aoc_d->specific.recorded));
749 		ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 2,
750 			aoc_d->specific.type_of_charging_info));
751 		if (aoc_d->specific.billing_id_present) {
752 			ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 3,
753 				aoc_d->specific.billing_id));
754 		}
755 
756 		ASN1_CONSTRUCTED_END(seq_len, pos, end);
757 		break;
758 	default:
759 		ASN1_ENC_ERROR(ctrl, "Unknown AOCDChargingUnit type");
760 		return NULL;
761 	}
762 
763 	return pos;
764 }
765 
766 /*!
767  * \brief Encode the AOCECurrency invoke facility ie arguments.
768  *
769  * \param ctrl D channel controller for diagnostic messages or global options.
770  * \param pos Starting position to encode ASN.1 component.
771  * \param end End of ASN.1 encoding data buffer.
772  * \param args Arguments to encode in the buffer.
773  *
774  * \retval Start of the next ASN.1 component to encode on success.
775  * \retval NULL on error.
776  */
rose_enc_etsi_AOCECurrency_ARG(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_invoke_args * args)777 unsigned char *rose_enc_etsi_AOCECurrency_ARG(struct pri *ctrl, unsigned char *pos,
778 	unsigned char *end, const union rose_msg_invoke_args *args)
779 {
780 	switch (args->etsi.AOCECurrency.type) {
781 	case 0:	/* charge_not_available */
782 		ASN1_CALL(pos, asn1_enc_null(pos, end, ASN1_TYPE_NULL));
783 		break;
784 	case 1:	/* currency_info */
785 		ASN1_CALL(pos, rose_enc_etsi_AOCECurrencyInfo(ctrl, pos, end, ASN1_TAG_SEQUENCE,
786 			&args->etsi.AOCECurrency.currency_info));
787 		break;
788 	default:
789 		ASN1_ENC_ERROR(ctrl, "Unknown AOCECurrency type");
790 		return NULL;
791 	}
792 
793 	return pos;
794 }
795 
796 /*!
797  * \brief Encode the AOCEChargingUnit invoke facility ie arguments.
798  *
799  * \param ctrl D channel controller for diagnostic messages or global options.
800  * \param pos Starting position to encode ASN.1 component.
801  * \param end End of ASN.1 encoding data buffer.
802  * \param args Arguments to encode in the buffer.
803  *
804  * \retval Start of the next ASN.1 component to encode on success.
805  * \retval NULL on error.
806  */
rose_enc_etsi_AOCEChargingUnit_ARG(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_invoke_args * args)807 unsigned char *rose_enc_etsi_AOCEChargingUnit_ARG(struct pri *ctrl, unsigned char *pos,
808 	unsigned char *end, const union rose_msg_invoke_args *args)
809 {
810 	switch (args->etsi.AOCEChargingUnit.type) {
811 	case 0:	/* charge_not_available */
812 		ASN1_CALL(pos, asn1_enc_null(pos, end, ASN1_TYPE_NULL));
813 		break;
814 	case 1:	/* charging_unit */
815 		ASN1_CALL(pos, rose_enc_etsi_AOCEChargingUnitInfo(ctrl, pos, end,
816 			ASN1_TAG_SEQUENCE, &args->etsi.AOCEChargingUnit.charging_unit));
817 		break;
818 	default:
819 		ASN1_ENC_ERROR(ctrl, "Unknown AOCEChargingUnit type");
820 		return NULL;
821 	}
822 
823 	return pos;
824 }
825 
826 /*!
827  * \internal
828  * \brief Decode the Time type.
829  *
830  * \param ctrl D channel controller for diagnostic messages or global options.
831  * \param name Field name
832  * \param tag Component tag that identified this production.
833  * \param pos Starting position of the ASN.1 component length.
834  * \param end End of ASN.1 decoding data buffer.
835  * \param time Parameter storage to fill.
836  *
837  * \retval Start of the next ASN.1 component on success.
838  * \retval NULL on error.
839  */
rose_dec_etsi_AOC_Time(struct pri * ctrl,const char * name,unsigned tag,const unsigned char * pos,const unsigned char * end,struct roseEtsiAOCTime * time)840 static const unsigned char *rose_dec_etsi_AOC_Time(struct pri *ctrl, const char *name,
841 	unsigned tag, const unsigned char *pos, const unsigned char *end,
842 	struct roseEtsiAOCTime *time)
843 {
844 	int32_t value;
845 	int length;
846 	int seq_offset;
847 	const unsigned char *seq_end;
848 
849 	if (ctrl->debug & PRI_DEBUG_APDU) {
850 		pri_message(ctrl, "  %s Time %s\n", name, asn1_tag2str(tag));
851 	}
852 	ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
853 	ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
854 
855 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
856 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_CLASS_CONTEXT_SPECIFIC | 1);
857 	ASN1_CALL(pos, asn1_dec_int(ctrl, "lengthOfTimeUnit", tag, pos, seq_end, &value));
858 	time->length = value;
859 
860 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
861 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_CLASS_CONTEXT_SPECIFIC | 2);
862 	ASN1_CALL(pos, asn1_dec_int(ctrl, "scale", tag, pos, seq_end, &value));
863 	time->scale = value;
864 
865 	ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
866 
867 	return pos;
868 }
869 
870 /*!
871  * \internal
872  * \brief Decode the Amount type.
873  *
874  * \param ctrl D channel controller for diagnostic messages or global options.
875  * \param name Field name
876  * \param tag Component tag that identified this production.
877  * \param pos Starting position of the ASN.1 component length.
878  * \param end End of ASN.1 decoding data buffer.
879  * \param amount Parameter storage to fill.
880  *
881  * \retval Start of the next ASN.1 component on success.
882  * \retval NULL on error.
883  */
rose_dec_etsi_AOC_Amount(struct pri * ctrl,const char * name,unsigned tag,const unsigned char * pos,const unsigned char * end,struct roseEtsiAOCAmount * amount)884 static const unsigned char *rose_dec_etsi_AOC_Amount(struct pri *ctrl, const char *name,
885 	unsigned tag, const unsigned char *pos, const unsigned char *end,
886 	struct roseEtsiAOCAmount *amount)
887 {
888 	int32_t value;
889 	int length;
890 	int seq_offset;
891 	const unsigned char *seq_end;
892 
893 	if (ctrl->debug & PRI_DEBUG_APDU) {
894 		pri_message(ctrl, "  %s Amount %s\n", name, asn1_tag2str(tag));
895 	}
896 	ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
897 	ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
898 
899 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
900 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_CLASS_CONTEXT_SPECIFIC | 1);
901 	ASN1_CALL(pos, asn1_dec_int(ctrl, "currencyAmount", tag, pos, seq_end, &value));
902 	amount->currency = value;
903 
904 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
905 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_CLASS_CONTEXT_SPECIFIC | 2);
906 	ASN1_CALL(pos, asn1_dec_int(ctrl, "multiplier", tag, pos, seq_end, &value));
907 	amount->multiplier = value;
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 RecordedCurrency 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 recorded Parameter storage to fill.
924  *
925  * \retval Start of the next ASN.1 component on success.
926  * \retval NULL on error.
927  */
rose_dec_etsi_AOC_RecordedCurrency(struct pri * ctrl,const char * name,unsigned tag,const unsigned char * pos,const unsigned char * end,struct roseEtsiAOCRecordedCurrency * recorded)928 static const unsigned char *rose_dec_etsi_AOC_RecordedCurrency(struct pri *ctrl,
929 	const char *name, unsigned tag, const unsigned char *pos, const unsigned char *end,
930 	struct roseEtsiAOCRecordedCurrency *recorded)
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 RecordedCurrency %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, "rCurrency", tag, pos, seq_end,
946 		sizeof(recorded->currency), recorded->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_etsi_AOC_Amount(ctrl, "rAmount", tag, pos, seq_end,
952 		&recorded->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 DurationCurrency 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 duration Parameter storage to fill.
969  *
970  * \retval Start of the next ASN.1 component on success.
971  * \retval NULL on error.
972  */
rose_dec_etsi_AOC_DurationCurrency(struct pri * ctrl,const char * name,unsigned tag,const unsigned char * pos,const unsigned char * end,struct roseEtsiAOCDurationCurrency * duration)973 static const unsigned char *rose_dec_etsi_AOC_DurationCurrency(struct pri *ctrl,
974 	const char *name, unsigned tag, const unsigned char *pos, const unsigned char *end,
975 	struct roseEtsiAOCDurationCurrency *duration)
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 DurationCurrency %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, "dCurrency", tag, pos, seq_end,
992 		sizeof(duration->currency), duration->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_etsi_AOC_Amount(ctrl, "dAmount", tag, pos, seq_end,
998 		&duration->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, "dChargingType", tag, pos, seq_end, &value));
1003 	duration->charging_type = value;
1004 
1005 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1006 	ASN1_CHECK_TAG(ctrl, tag, tag,
1007 		ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 4);
1008 	ASN1_CALL(pos, rose_dec_etsi_AOC_Time(ctrl, "dTime", tag, pos, seq_end,
1009 		&duration->time));
1010 
1011 	if (pos < seq_end && *pos != ASN1_INDEF_TERM) {
1012 		ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1013 		ASN1_CHECK_TAG(ctrl, tag, tag,
1014 			ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 5);
1015 		ASN1_CALL(pos, rose_dec_etsi_AOC_Time(ctrl, "dGranularity", tag, pos, seq_end,
1016 			&duration->granularity));
1017 		duration->granularity_present = 1;
1018 	} else {
1019 		duration->granularity_present = 0;
1020 	}
1021 
1022 	ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
1023 
1024 	return pos;
1025 }
1026 
1027 /*!
1028  * \internal
1029  * \brief Decode the FlatRateCurrency type.
1030  *
1031  * \param ctrl D channel controller for diagnostic messages or global options.
1032  * \param name Field name
1033  * \param tag Component tag that identified this production.
1034  * \param pos Starting position of the ASN.1 component length.
1035  * \param end End of ASN.1 decoding data buffer.
1036  * \param flat_rate Parameter storage to fill.
1037  *
1038  * \retval Start of the next ASN.1 component on success.
1039  * \retval NULL on error.
1040  */
rose_dec_etsi_AOC_FlatRateCurrency(struct pri * ctrl,const char * name,unsigned tag,const unsigned char * pos,const unsigned char * end,struct roseEtsiAOCFlatRateCurrency * flat_rate)1041 static const unsigned char *rose_dec_etsi_AOC_FlatRateCurrency(struct pri *ctrl,
1042 	const char *name, unsigned tag, const unsigned char *pos, const unsigned char *end,
1043 	struct roseEtsiAOCFlatRateCurrency *flat_rate)
1044 {
1045 	int length;
1046 	int seq_offset;
1047 	const unsigned char *seq_end;
1048 	size_t str_len;
1049 
1050 	if (ctrl->debug & PRI_DEBUG_APDU) {
1051 		pri_message(ctrl, "  %s FlatRateCurrency %s\n", name, asn1_tag2str(tag));
1052 	}
1053 	ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
1054 	ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
1055 
1056 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1057 	ASN1_CHECK_TAG(ctrl, tag & ~ASN1_PC_MASK, tag, ASN1_CLASS_CONTEXT_SPECIFIC | 1);
1058 	ASN1_CALL(pos, asn1_dec_string_max(ctrl, "fRCurrency", tag, pos, seq_end,
1059 		sizeof(flat_rate->currency), flat_rate->currency, &str_len));
1060 
1061 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1062 	ASN1_CHECK_TAG(ctrl, tag, tag,
1063 		ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 2);
1064 	ASN1_CALL(pos, rose_dec_etsi_AOC_Amount(ctrl, "fRAmount", tag, pos, seq_end,
1065 		&flat_rate->amount));
1066 
1067 	ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
1068 
1069 	return pos;
1070 }
1071 
1072 /*!
1073  * \internal
1074  * \brief Decode the VolumeRateCurrency type.
1075  *
1076  * \param ctrl D channel controller for diagnostic messages or global options.
1077  * \param name Field name
1078  * \param tag Component tag that identified this production.
1079  * \param pos Starting position of the ASN.1 component length.
1080  * \param end End of ASN.1 decoding data buffer.
1081  * \param volume_rate Parameter storage to fill.
1082  *
1083  * \retval Start of the next ASN.1 component on success.
1084  * \retval NULL on error.
1085  */
rose_dec_etsi_AOC_VolumeRateCurrency(struct pri * ctrl,const char * name,unsigned tag,const unsigned char * pos,const unsigned char * end,struct roseEtsiAOCVolumeRateCurrency * volume_rate)1086 static const unsigned char *rose_dec_etsi_AOC_VolumeRateCurrency(struct pri *ctrl,
1087 	const char *name, unsigned tag, const unsigned char *pos, const unsigned char *end,
1088 	struct roseEtsiAOCVolumeRateCurrency *volume_rate)
1089 {
1090 	int32_t value;
1091 	int length;
1092 	int seq_offset;
1093 	const unsigned char *seq_end;
1094 	size_t str_len;
1095 
1096 	if (ctrl->debug & PRI_DEBUG_APDU) {
1097 		pri_message(ctrl, "  %s VolumeRateCurrency %s\n", name, asn1_tag2str(tag));
1098 	}
1099 	ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
1100 	ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
1101 
1102 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1103 	ASN1_CHECK_TAG(ctrl, tag & ~ASN1_PC_MASK, tag, ASN1_CLASS_CONTEXT_SPECIFIC | 1);
1104 	ASN1_CALL(pos, asn1_dec_string_max(ctrl, "vRCurrency", tag, pos, seq_end,
1105 		sizeof(volume_rate->currency), volume_rate->currency, &str_len));
1106 
1107 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1108 	ASN1_CHECK_TAG(ctrl, tag, tag,
1109 		ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 2);
1110 	ASN1_CALL(pos, rose_dec_etsi_AOC_Amount(ctrl, "vRAmount", tag, pos, seq_end,
1111 		&volume_rate->amount));
1112 
1113 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1114 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_CLASS_CONTEXT_SPECIFIC | 3);
1115 	ASN1_CALL(pos, asn1_dec_int(ctrl, "vRVolumeUnit", tag, pos, seq_end, &value));
1116 	volume_rate->unit = value;
1117 
1118 	ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
1119 
1120 	return pos;
1121 }
1122 
1123 /*!
1124  * \internal
1125  * \brief Decode the AOCSCurrencyInfo type.
1126  *
1127  * \param ctrl D channel controller for diagnostic messages or global options.
1128  * \param name Field name
1129  * \param tag Component tag that identified this production.
1130  * \param pos Starting position of the ASN.1 component length.
1131  * \param end End of ASN.1 decoding data buffer.
1132  * \param currency_info Parameter storage to fill.
1133  *
1134  * \retval Start of the next ASN.1 component on success.
1135  * \retval NULL on error.
1136  */
rose_dec_etsi_AOCSCurrencyInfo(struct pri * ctrl,const char * name,unsigned tag,const unsigned char * pos,const unsigned char * end,struct roseEtsiAOCSCurrencyInfo * currency_info)1137 static const unsigned char *rose_dec_etsi_AOCSCurrencyInfo(struct pri *ctrl,
1138 	const char *name, unsigned tag, const unsigned char *pos, const unsigned char *end,
1139 	struct roseEtsiAOCSCurrencyInfo *currency_info)
1140 {
1141 	int32_t value;
1142 	int length;
1143 	int seq_offset;
1144 	const unsigned char *seq_end;
1145 
1146 	if (ctrl->debug & PRI_DEBUG_APDU) {
1147 		pri_message(ctrl, "  %s AOCSCurrencyInfo %s\n", name, asn1_tag2str(tag));
1148 	}
1149 	ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
1150 	ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
1151 
1152 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1153 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_ENUMERATED);
1154 	ASN1_CALL(pos, asn1_dec_int(ctrl, "chargedItem", tag, pos, seq_end, &value));
1155 	currency_info->charged_item = value;
1156 
1157 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1158 	switch (tag) {
1159 	case ASN1_TYPE_INTEGER:
1160 		currency_info->currency_type = 0;	/* specialChargingCode */
1161 		ASN1_CALL(pos, asn1_dec_int(ctrl, "specialChargingCode", tag, pos, seq_end,
1162 			&value));
1163 		currency_info->u.special_charging_code = value;
1164 		break;
1165 	case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 1:
1166 		currency_info->currency_type = 1;	/* durationCurrency */
1167 		ASN1_CALL(pos, rose_dec_etsi_AOC_DurationCurrency(ctrl, "durationCurrency", tag,
1168 			pos, seq_end, &currency_info->u.duration));
1169 		break;
1170 	case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 2:
1171 		currency_info->currency_type = 2;	/* flatRateCurrency */
1172 		ASN1_CALL(pos, rose_dec_etsi_AOC_FlatRateCurrency(ctrl, "flatRateCurrency", tag,
1173 			pos, seq_end, &currency_info->u.flat_rate));
1174 		break;
1175 	case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 3:
1176 		currency_info->currency_type = 3;	/* volumeRateCurrency */
1177 		ASN1_CALL(pos, rose_dec_etsi_AOC_VolumeRateCurrency(ctrl, "volumeRateCurrency",
1178 			tag, pos, seq_end, &currency_info->u.volume_rate));
1179 		break;
1180 	case ASN1_CLASS_CONTEXT_SPECIFIC | 4:
1181 		currency_info->currency_type = 4;	/* freeOfCharge */
1182 		ASN1_CALL(pos, asn1_dec_null(ctrl, "freeOfCharge", tag, pos, seq_end));
1183 		break;
1184 	case ASN1_CLASS_CONTEXT_SPECIFIC | 5:
1185 		currency_info->currency_type = 5;	/* currencyInfoNotAvailable */
1186 		ASN1_CALL(pos, asn1_dec_null(ctrl, "currencyInfoNotAvailable", tag, pos,
1187 			seq_end));
1188 		break;
1189 	default:
1190 		ASN1_DID_NOT_EXPECT_TAG(ctrl, tag);
1191 		return NULL;
1192 	}
1193 
1194 	ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
1195 
1196 	return pos;
1197 }
1198 
1199 /*!
1200  * \internal
1201  * \brief Decode the AOCSCurrencyInfoList type.
1202  *
1203  * \param ctrl D channel controller for diagnostic messages or global options.
1204  * \param name Field name
1205  * \param tag Component tag that identified this production.
1206  * \param pos Starting position of the ASN.1 component length.
1207  * \param end End of ASN.1 decoding data buffer.
1208  * \param currency_info Parameter storage to fill.
1209  *
1210  * \retval Start of the next ASN.1 component on success.
1211  * \retval NULL on error.
1212  */
rose_dec_etsi_AOCSCurrencyInfoList(struct pri * ctrl,const char * name,unsigned tag,const unsigned char * pos,const unsigned char * end,struct roseEtsiAOCSCurrencyInfoList * currency_info)1213 static const unsigned char *rose_dec_etsi_AOCSCurrencyInfoList(struct pri *ctrl,
1214 	const char *name, unsigned tag, const unsigned char *pos, const unsigned char *end,
1215 	struct roseEtsiAOCSCurrencyInfoList *currency_info)
1216 {
1217 	int length;
1218 	int seq_offset;
1219 	const unsigned char *seq_end;
1220 
1221 	if (ctrl->debug & PRI_DEBUG_APDU) {
1222 		pri_message(ctrl, "  %s AOCSCurrencyInfoList %s\n", name, asn1_tag2str(tag));
1223 	}
1224 	ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
1225 	ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
1226 
1227 	currency_info->num_records = 0;
1228 	while (pos < seq_end && *pos != ASN1_INDEF_TERM) {
1229 		if (currency_info->num_records < ARRAY_LEN(currency_info->list)) {
1230 			ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1231 			ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
1232 			ASN1_CALL(pos, rose_dec_etsi_AOCSCurrencyInfo(ctrl, "listEntry", tag, pos,
1233 				seq_end, &currency_info->list[currency_info->num_records]));
1234 			++currency_info->num_records;
1235 		} else {
1236 			/* Too many records */
1237 			return NULL;
1238 		}
1239 	}
1240 
1241 	ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
1242 
1243 	return pos;
1244 }
1245 
1246 /*!
1247  * \internal
1248  * \brief Decode the RecordedUnits type.
1249  *
1250  * \param ctrl D channel controller for diagnostic messages or global options.
1251  * \param name Field name
1252  * \param tag Component tag that identified this production.
1253  * \param pos Starting position of the ASN.1 component length.
1254  * \param end End of ASN.1 decoding data buffer.
1255  * \param recorded Parameter storage to fill.
1256  *
1257  * \retval Start of the next ASN.1 component on success.
1258  * \retval NULL on error.
1259  */
rose_dec_etsi_AOC_RecordedUnits(struct pri * ctrl,const char * name,unsigned tag,const unsigned char * pos,const unsigned char * end,struct roseEtsiAOCRecordedUnits * recorded)1260 static const unsigned char *rose_dec_etsi_AOC_RecordedUnits(struct pri *ctrl,
1261 	const char *name, unsigned tag, const unsigned char *pos, const unsigned char *end,
1262 	struct roseEtsiAOCRecordedUnits *recorded)
1263 {
1264 	int32_t value;
1265 	int length;
1266 	int seq_offset;
1267 	const unsigned char *seq_end;
1268 
1269 	if (ctrl->debug & PRI_DEBUG_APDU) {
1270 		pri_message(ctrl, "  %s RecordedUnits %s\n", name, asn1_tag2str(tag));
1271 	}
1272 	ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
1273 	ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
1274 
1275 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1276 	switch (tag) {
1277 	case ASN1_TYPE_INTEGER:
1278 		recorded->not_available = 0;
1279 		ASN1_CALL(pos, asn1_dec_int(ctrl, "recordedNumberOfUnits", tag, pos, seq_end,
1280 			&value));
1281 		recorded->number_of_units = value;
1282 		break;
1283 	case ASN1_TYPE_NULL:
1284 		recorded->not_available = 1;
1285 		recorded->number_of_units = 0;
1286 		ASN1_CALL(pos, asn1_dec_null(ctrl, "notAvailable", tag, pos, seq_end));
1287 		break;
1288 	default:
1289 		ASN1_DID_NOT_EXPECT_TAG(ctrl, tag);
1290 		return NULL;
1291 	}
1292 
1293 	if (pos < seq_end && *pos != ASN1_INDEF_TERM) {
1294 		ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1295 		ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_INTEGER);
1296 		ASN1_CALL(pos, asn1_dec_int(ctrl, "recordedTypeOfUnits", tag, pos, seq_end,
1297 			&value));
1298 		recorded->type_of_unit = value;
1299 		recorded->type_of_unit_present = 1;
1300 	} else {
1301 		recorded->type_of_unit_present = 0;
1302 	}
1303 
1304 	ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
1305 
1306 	return pos;
1307 }
1308 
1309 /*!
1310  * \internal
1311  * \brief Decode the RecordedUnitsList type.
1312  *
1313  * \param ctrl D channel controller for diagnostic messages or global options.
1314  * \param name Field name
1315  * \param tag Component tag that identified this production.
1316  * \param pos Starting position of the ASN.1 component length.
1317  * \param end End of ASN.1 decoding data buffer.
1318  * \param recorded_info Parameter storage to fill.
1319  *
1320  * \retval Start of the next ASN.1 component on success.
1321  * \retval NULL on error.
1322  */
rose_dec_etsi_AOC_RecordedUnitsList(struct pri * ctrl,const char * name,unsigned tag,const unsigned char * pos,const unsigned char * end,struct roseEtsiAOCRecordedUnitsList * recorded_info)1323 static const unsigned char *rose_dec_etsi_AOC_RecordedUnitsList(struct pri *ctrl,
1324 	const char *name, unsigned tag, const unsigned char *pos, const unsigned char *end,
1325 	struct roseEtsiAOCRecordedUnitsList *recorded_info)
1326 {
1327 	int length;
1328 	int seq_offset;
1329 	const unsigned char *seq_end;
1330 
1331 	if (ctrl->debug & PRI_DEBUG_APDU) {
1332 		pri_message(ctrl, "  %s RecordedUnitsList %s\n", name, asn1_tag2str(tag));
1333 	}
1334 	ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
1335 	ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
1336 
1337 	recorded_info->num_records = 0;
1338 	while (pos < seq_end && *pos != ASN1_INDEF_TERM) {
1339 		if (recorded_info->num_records < ARRAY_LEN(recorded_info->list)) {
1340 			ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1341 			ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
1342 			ASN1_CALL(pos, rose_dec_etsi_AOC_RecordedUnits(ctrl, "listEntry", tag, pos,
1343 				seq_end, &recorded_info->list[recorded_info->num_records]));
1344 			++recorded_info->num_records;
1345 		} else {
1346 			/* Too many records */
1347 			return NULL;
1348 		}
1349 	}
1350 
1351 	ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
1352 
1353 	return pos;
1354 }
1355 
1356 /*!
1357  * \internal
1358  * \brief Decode the ChargingAssociation type.
1359  *
1360  * \param ctrl D channel controller for diagnostic messages or global options.
1361  * \param name Field name
1362  * \param tag Component tag that identified this production.
1363  * \param pos Starting position of the ASN.1 component length.
1364  * \param end End of ASN.1 decoding data buffer.
1365  * \param charging Parameter storage to fill.
1366  *
1367  * \retval Start of the next ASN.1 component on success.
1368  * \retval NULL on error.
1369  */
rose_dec_etsi_AOC_ChargingAssociation(struct pri * ctrl,const char * name,unsigned tag,const unsigned char * pos,const unsigned char * end,struct roseEtsiAOCChargingAssociation * charging)1370 static const unsigned char *rose_dec_etsi_AOC_ChargingAssociation(struct pri *ctrl,
1371 	const char *name, unsigned tag, const unsigned char *pos, const unsigned char *end,
1372 	struct roseEtsiAOCChargingAssociation *charging)
1373 {
1374 	int32_t value;
1375 	int length;
1376 	int explicit_offset;
1377 	const unsigned char *explicit_end;
1378 
1379 	if (ctrl->debug & PRI_DEBUG_APDU) {
1380 		pri_message(ctrl, "  %s ChargingAssociation\n", name);
1381 	}
1382 	switch (tag) {
1383 	case ASN1_TYPE_INTEGER:
1384 		charging->type = 0;	/* charge_identifier */
1385 		ASN1_CALL(pos, asn1_dec_int(ctrl, "chargeIdentifier", tag, pos, end, &value));
1386 		charging->id = value;
1387 		break;
1388 	case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 0:
1389 		charging->type = 1;	/* charged_number */
1390 
1391 		/* Remove EXPLICIT tag */
1392 		if (ctrl->debug & PRI_DEBUG_APDU) {
1393 			pri_message(ctrl, "  Explicit %s\n", asn1_tag2str(tag));
1394 		}
1395 		ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
1396 		ASN1_END_SETUP(explicit_end, explicit_offset, length, pos, end);
1397 
1398 		ASN1_CALL(pos, asn1_dec_tag(pos, explicit_end, &tag));
1399 		ASN1_CALL(pos, rose_dec_PartyNumber(ctrl, "chargedNumber", tag, pos,
1400 			explicit_end, &charging->number));
1401 
1402 		ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, end);
1403 		break;
1404 	default:
1405 		ASN1_DID_NOT_EXPECT_TAG(ctrl, tag);
1406 		return NULL;
1407 	}
1408 
1409 	return pos;
1410 }
1411 
1412 /*!
1413  * \internal
1414  * \brief Decode the AOCECurrencyInfo type.
1415  *
1416  * \param ctrl D channel controller for diagnostic messages or global options.
1417  * \param name Field name
1418  * \param tag Component tag that identified this production.
1419  * \param pos Starting position of the ASN.1 component length.
1420  * \param end End of ASN.1 decoding data buffer.
1421  * \param currency_info Parameter storage to fill.
1422  *
1423  * \retval Start of the next ASN.1 component on success.
1424  * \retval NULL on error.
1425  */
rose_dec_etsi_AOCECurrencyInfo(struct pri * ctrl,const char * name,unsigned tag,const unsigned char * pos,const unsigned char * end,struct roseEtsiAOCECurrencyInfo * currency_info)1426 static const unsigned char *rose_dec_etsi_AOCECurrencyInfo(struct pri *ctrl,
1427 	const char *name, unsigned tag, const unsigned char *pos, const unsigned char *end,
1428 	struct roseEtsiAOCECurrencyInfo *currency_info)
1429 {
1430 	int32_t value;
1431 	int length;
1432 	int seq_offset;
1433 	int specific_offset;
1434 	const unsigned char *seq_end;
1435 	const unsigned char *specific_end;
1436 
1437 	if (ctrl->debug & PRI_DEBUG_APDU) {
1438 		pri_message(ctrl, "  %s AOCECurrencyInfo %s\n", name, asn1_tag2str(tag));
1439 	}
1440 	ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
1441 	ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
1442 
1443 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1444 	switch (tag) {
1445 	case ASN1_CLASS_CONTEXT_SPECIFIC | 1:
1446 		currency_info->free_of_charge = 1;
1447 		ASN1_CALL(pos, asn1_dec_null(ctrl, "freeOfCharge", tag, pos, seq_end));
1448 		break;
1449 	case ASN1_TAG_SEQUENCE:
1450 		currency_info->free_of_charge = 0;
1451 		if (ctrl->debug & PRI_DEBUG_APDU) {
1452 			pri_message(ctrl, "  specificCurrency %s\n", asn1_tag2str(tag));
1453 		}
1454 		ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
1455 		ASN1_END_SETUP(specific_end, specific_offset, length, pos, seq_end);
1456 
1457 		ASN1_CALL(pos, asn1_dec_tag(pos, specific_end, &tag));
1458 		ASN1_CHECK_TAG(ctrl, tag, tag,
1459 			ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 1);
1460 		ASN1_CALL(pos, rose_dec_etsi_AOC_RecordedCurrency(ctrl, "recordedCurrency", tag,
1461 			pos, specific_end, &currency_info->specific.recorded));
1462 
1463 		if (pos < specific_end && *pos != ASN1_INDEF_TERM) {
1464 			ASN1_CALL(pos, asn1_dec_tag(pos, specific_end, &tag));
1465 			ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_CLASS_CONTEXT_SPECIFIC | 2);
1466 			ASN1_CALL(pos, asn1_dec_int(ctrl, "billingId", tag, pos, specific_end,
1467 				&value));
1468 			currency_info->specific.billing_id = value;
1469 			currency_info->specific.billing_id_present = 1;
1470 		} else {
1471 			currency_info->specific.billing_id_present = 0;
1472 		}
1473 
1474 		ASN1_END_FIXUP(ctrl, pos, specific_offset, specific_end, seq_end);
1475 		break;
1476 	default:
1477 		ASN1_DID_NOT_EXPECT_TAG(ctrl, tag);
1478 		return NULL;
1479 	}
1480 
1481 	if (pos < seq_end && *pos != ASN1_INDEF_TERM) {
1482 		ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1483 		ASN1_CALL(pos, rose_dec_etsi_AOC_ChargingAssociation(ctrl, "chargingAssociation",
1484 			tag, pos, seq_end, &currency_info->charging_association));
1485 		currency_info->charging_association_present = 1;
1486 	} else {
1487 		currency_info->charging_association_present = 0;
1488 	}
1489 
1490 	ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
1491 
1492 	return pos;
1493 }
1494 
1495 /*!
1496  * \internal
1497  * \brief Decode the AOCEChargingUnitInfo type.
1498  *
1499  * \param ctrl D channel controller for diagnostic messages or global options.
1500  * \param name Field name
1501  * \param tag Component tag that identified this production.
1502  * \param pos Starting position of the ASN.1 component length.
1503  * \param end End of ASN.1 decoding data buffer.
1504  * \param charging_unit Parameter storage to fill.
1505  *
1506  * \retval Start of the next ASN.1 component on success.
1507  * \retval NULL on error.
1508  */
rose_dec_etsi_AOCEChargingUnitInfo(struct pri * ctrl,const char * name,unsigned tag,const unsigned char * pos,const unsigned char * end,struct roseEtsiAOCEChargingUnitInfo * charging_unit)1509 static const unsigned char *rose_dec_etsi_AOCEChargingUnitInfo(struct pri *ctrl,
1510 	const char *name, unsigned tag, const unsigned char *pos, const unsigned char *end,
1511 	struct roseEtsiAOCEChargingUnitInfo *charging_unit)
1512 {
1513 	int32_t value;
1514 	int length;
1515 	int seq_offset;
1516 	int specific_offset;
1517 	const unsigned char *seq_end;
1518 	const unsigned char *specific_end;
1519 
1520 	if (ctrl->debug & PRI_DEBUG_APDU) {
1521 		pri_message(ctrl, "  %s AOCEChargingUnitInfo %s\n", name, asn1_tag2str(tag));
1522 	}
1523 	ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
1524 	ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
1525 
1526 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1527 	switch (tag) {
1528 	case ASN1_CLASS_CONTEXT_SPECIFIC | 1:
1529 		charging_unit->free_of_charge = 1;
1530 		ASN1_CALL(pos, asn1_dec_null(ctrl, "freeOfCharge", tag, pos, seq_end));
1531 		break;
1532 	case ASN1_TAG_SEQUENCE:
1533 		charging_unit->free_of_charge = 0;
1534 		if (ctrl->debug & PRI_DEBUG_APDU) {
1535 			pri_message(ctrl, "  specificChargingUnits %s\n", asn1_tag2str(tag));
1536 		}
1537 		ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
1538 		ASN1_END_SETUP(specific_end, specific_offset, length, pos, seq_end);
1539 
1540 		ASN1_CALL(pos, asn1_dec_tag(pos, specific_end, &tag));
1541 		ASN1_CHECK_TAG(ctrl, tag, tag,
1542 			ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 1);
1543 		ASN1_CALL(pos, rose_dec_etsi_AOC_RecordedUnitsList(ctrl, "recordedUnitsList",
1544 			tag, pos, specific_end, &charging_unit->specific.recorded));
1545 
1546 		if (pos < specific_end && *pos != ASN1_INDEF_TERM) {
1547 			ASN1_CALL(pos, asn1_dec_tag(pos, specific_end, &tag));
1548 			ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_CLASS_CONTEXT_SPECIFIC | 2);
1549 			ASN1_CALL(pos, asn1_dec_int(ctrl, "billingId", tag, pos, specific_end,
1550 				&value));
1551 			charging_unit->specific.billing_id = value;
1552 			charging_unit->specific.billing_id_present = 1;
1553 		} else {
1554 			charging_unit->specific.billing_id_present = 0;
1555 		}
1556 
1557 		ASN1_END_FIXUP(ctrl, pos, specific_offset, specific_end, seq_end);
1558 		break;
1559 	default:
1560 		ASN1_DID_NOT_EXPECT_TAG(ctrl, tag);
1561 		return NULL;
1562 	}
1563 
1564 	if (pos < seq_end && *pos != ASN1_INDEF_TERM) {
1565 		ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1566 		ASN1_CALL(pos, rose_dec_etsi_AOC_ChargingAssociation(ctrl, "chargingAssociation",
1567 			tag, pos, seq_end, &charging_unit->charging_association));
1568 		charging_unit->charging_association_present = 1;
1569 	} else {
1570 		charging_unit->charging_association_present = 0;
1571 	}
1572 
1573 	ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
1574 
1575 	return pos;
1576 }
1577 
1578 /*!
1579  * \brief Decode the ChargingRequest invoke argument parameters.
1580  *
1581  * \param ctrl D channel controller for diagnostic messages or global options.
1582  * \param tag Component tag that identified this structure.
1583  * \param pos Starting position of the ASN.1 component length.
1584  * \param end End of ASN.1 decoding data buffer.
1585  * \param args Arguments to fill in from the decoded buffer.
1586  *
1587  * \retval Start of the next ASN.1 component on success.
1588  * \retval NULL on error.
1589  */
rose_dec_etsi_ChargingRequest_ARG(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_invoke_args * args)1590 const unsigned char *rose_dec_etsi_ChargingRequest_ARG(struct pri *ctrl, unsigned tag,
1591 	const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
1592 {
1593 	int32_t value;
1594 
1595 	ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_ENUMERATED);
1596 	ASN1_CALL(pos, asn1_dec_int(ctrl, "chargingCase", tag, pos, end, &value));
1597 	args->etsi.ChargingRequest.charging_case = value;
1598 
1599 	return pos;
1600 }
1601 
1602 /*!
1603  * \brief Decode the ChargingRequest result parameters.
1604  *
1605  * \param ctrl D channel controller for diagnostic messages or global options.
1606  * \param tag Component tag that identified this structure.
1607  * \param pos Starting position of the ASN.1 component length.
1608  * \param end End of ASN.1 decoding data buffer.
1609  * \param args Arguments to fill in from the decoded buffer.
1610  *
1611  * \retval Start of the next ASN.1 component on success.
1612  * \retval NULL on error.
1613  */
rose_dec_etsi_ChargingRequest_RES(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_result_args * args)1614 const unsigned char *rose_dec_etsi_ChargingRequest_RES(struct pri *ctrl, unsigned tag,
1615 	const unsigned char *pos, const unsigned char *end, union rose_msg_result_args *args)
1616 {
1617 	struct roseEtsiChargingRequest_RES *charging_request;
1618 	int32_t value;
1619 
1620 	charging_request = &args->etsi.ChargingRequest;
1621 	switch (tag) {
1622 	case ASN1_TAG_SEQUENCE:
1623 		charging_request->type = 0;	/* currency_info_list */
1624 		ASN1_CALL(pos, rose_dec_etsi_AOCSCurrencyInfoList(ctrl, "currencyList", tag, pos,
1625 			end, &charging_request->u.currency_info));
1626 		break;
1627 	case ASN1_TYPE_INTEGER:
1628 		charging_request->type = 1;	/* special_arrangement_info */
1629 		ASN1_CALL(pos, asn1_dec_int(ctrl, "specialArrangement", tag, pos, end, &value));
1630 		charging_request->u.special_arrangement = value;
1631 		break;
1632 	case ASN1_TYPE_NULL:
1633 		charging_request->type = 2;	/* charging_info_follows */
1634 		ASN1_CALL(pos, asn1_dec_null(ctrl, "chargingInfoFollows", tag, pos, end));
1635 		break;
1636 	default:
1637 		ASN1_DID_NOT_EXPECT_TAG(ctrl, tag);
1638 		return NULL;
1639 	}
1640 
1641 	return pos;
1642 }
1643 
1644 /*!
1645  * \brief Decode the AOCSCurrency invoke argument parameters.
1646  *
1647  * \param ctrl D channel controller for diagnostic messages or global options.
1648  * \param tag Component tag that identified this structure.
1649  * \param pos Starting position of the ASN.1 component length.
1650  * \param end End of ASN.1 decoding data buffer.
1651  * \param args Arguments to fill in from the decoded buffer.
1652  *
1653  * \retval Start of the next ASN.1 component on success.
1654  * \retval NULL on error.
1655  */
rose_dec_etsi_AOCSCurrency_ARG(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_invoke_args * args)1656 const unsigned char *rose_dec_etsi_AOCSCurrency_ARG(struct pri *ctrl, unsigned tag,
1657 	const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
1658 {
1659 	struct roseEtsiAOCSCurrency_ARG *aoc_s;
1660 
1661 	aoc_s = &args->etsi.AOCSCurrency;
1662 	switch (tag) {
1663 	case ASN1_TYPE_NULL:
1664 		aoc_s->type = 0;	/* charge_not_available */
1665 		ASN1_CALL(pos, asn1_dec_null(ctrl, "chargeNotAvailable", tag, pos, end));
1666 		break;
1667 	case ASN1_TAG_SEQUENCE:
1668 		aoc_s->type = 1;	/* currency_info_list */
1669 		ASN1_CALL(pos, rose_dec_etsi_AOCSCurrencyInfoList(ctrl, "currencyInfo", tag, pos,
1670 			end, &aoc_s->currency_info));
1671 		break;
1672 	default:
1673 		ASN1_DID_NOT_EXPECT_TAG(ctrl, tag);
1674 		return NULL;
1675 	}
1676 
1677 	return pos;
1678 }
1679 
1680 /*!
1681  * \brief Decode the AOCSSpecialArr invoke argument parameters.
1682  *
1683  * \param ctrl D channel controller for diagnostic messages or global options.
1684  * \param tag Component tag that identified this structure.
1685  * \param pos Starting position of the ASN.1 component length.
1686  * \param end End of ASN.1 decoding data buffer.
1687  * \param args Arguments to fill in from the decoded buffer.
1688  *
1689  * \retval Start of the next ASN.1 component on success.
1690  * \retval NULL on error.
1691  */
rose_dec_etsi_AOCSSpecialArr_ARG(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_invoke_args * args)1692 const unsigned char *rose_dec_etsi_AOCSSpecialArr_ARG(struct pri *ctrl, unsigned tag,
1693 	const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
1694 {
1695 	struct roseEtsiAOCSSpecialArr_ARG *aoc_s;
1696 	int32_t value;
1697 
1698 	aoc_s = &args->etsi.AOCSSpecialArr;
1699 	switch (tag) {
1700 	case ASN1_TYPE_NULL:
1701 		aoc_s->type = 0;	/* charge_not_available */
1702 		ASN1_CALL(pos, asn1_dec_null(ctrl, "chargeNotAvailable", tag, pos, end));
1703 		break;
1704 	case ASN1_TYPE_INTEGER:
1705 		aoc_s->type = 1;	/* special_arrangement_info */
1706 		ASN1_CALL(pos, asn1_dec_int(ctrl, "specialArrangement", tag, pos, end, &value));
1707 		aoc_s->special_arrangement = value;
1708 		break;
1709 	default:
1710 		ASN1_DID_NOT_EXPECT_TAG(ctrl, tag);
1711 		return NULL;
1712 	}
1713 
1714 	return pos;
1715 }
1716 
1717 /*!
1718  * \brief Decode the AOCDCurrency invoke argument parameters.
1719  *
1720  * \param ctrl D channel controller for diagnostic messages or global options.
1721  * \param tag Component tag that identified this structure.
1722  * \param pos Starting position of the ASN.1 component length.
1723  * \param end End of ASN.1 decoding data buffer.
1724  * \param args Arguments to fill in from the decoded buffer.
1725  *
1726  * \retval Start of the next ASN.1 component on success.
1727  * \retval NULL on error.
1728  */
rose_dec_etsi_AOCDCurrency_ARG(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_invoke_args * args)1729 const unsigned char *rose_dec_etsi_AOCDCurrency_ARG(struct pri *ctrl, unsigned tag,
1730 	const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
1731 {
1732 	struct roseEtsiAOCDCurrency_ARG *aoc_d;
1733 	int length;
1734 	int seq_offset;
1735 	const unsigned char *seq_end;
1736 	int32_t value;
1737 
1738 	aoc_d = &args->etsi.AOCDCurrency;
1739 	switch (tag) {
1740 	case ASN1_TYPE_NULL:
1741 		aoc_d->type = 0;	/* charge_not_available */
1742 		ASN1_CALL(pos, asn1_dec_null(ctrl, "chargeNotAvailable", tag, pos, end));
1743 		break;
1744 	case ASN1_CLASS_CONTEXT_SPECIFIC | 1:
1745 		aoc_d->type = 1;	/* free_of_charge */
1746 		ASN1_CALL(pos, asn1_dec_null(ctrl, "freeOfCharge", tag, pos, end));
1747 		break;
1748 	case ASN1_TAG_SEQUENCE:
1749 		aoc_d->type = 2;	/* specific_currency */
1750 
1751 		if (ctrl->debug & PRI_DEBUG_APDU) {
1752 			pri_message(ctrl, "  specificCurrency %s\n", asn1_tag2str(tag));
1753 		}
1754 		ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
1755 		ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
1756 
1757 		ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1758 		ASN1_CHECK_TAG(ctrl, tag, tag,
1759 			ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 1);
1760 		ASN1_CALL(pos, rose_dec_etsi_AOC_RecordedCurrency(ctrl, "recordedCurrency", tag,
1761 			pos, seq_end, &aoc_d->specific.recorded));
1762 
1763 		ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1764 		ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_CLASS_CONTEXT_SPECIFIC | 2);
1765 		ASN1_CALL(pos, asn1_dec_int(ctrl, "typeOfChargingInfo", tag, pos, seq_end,
1766 			&value));
1767 		aoc_d->specific.type_of_charging_info = value;
1768 
1769 		if (pos < seq_end && *pos != ASN1_INDEF_TERM) {
1770 			ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1771 			ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_CLASS_CONTEXT_SPECIFIC | 3);
1772 			ASN1_CALL(pos, asn1_dec_int(ctrl, "billingId", tag, pos, seq_end, &value));
1773 			aoc_d->specific.billing_id = value;
1774 			aoc_d->specific.billing_id_present = 1;
1775 		} else {
1776 			aoc_d->specific.billing_id_present = 0;
1777 		}
1778 
1779 		ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
1780 		break;
1781 	default:
1782 		ASN1_DID_NOT_EXPECT_TAG(ctrl, tag);
1783 		return NULL;
1784 	}
1785 
1786 	return pos;
1787 }
1788 
1789 /*!
1790  * \brief Decode the AOCDChargingUnit invoke argument parameters.
1791  *
1792  * \param ctrl D channel controller for diagnostic messages or global options.
1793  * \param tag Component tag that identified this structure.
1794  * \param pos Starting position of the ASN.1 component length.
1795  * \param end End of ASN.1 decoding data buffer.
1796  * \param args Arguments to fill in from the decoded buffer.
1797  *
1798  * \retval Start of the next ASN.1 component on success.
1799  * \retval NULL on error.
1800  */
rose_dec_etsi_AOCDChargingUnit_ARG(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_invoke_args * args)1801 const unsigned char *rose_dec_etsi_AOCDChargingUnit_ARG(struct pri *ctrl, unsigned tag,
1802 	const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
1803 {
1804 	struct roseEtsiAOCDChargingUnit_ARG *aoc_d;
1805 	int length;
1806 	int seq_offset;
1807 	const unsigned char *seq_end;
1808 	int32_t value;
1809 
1810 	aoc_d = &args->etsi.AOCDChargingUnit;
1811 	switch (tag) {
1812 	case ASN1_TYPE_NULL:
1813 		aoc_d->type = 0;	/* charge_not_available */
1814 		ASN1_CALL(pos, asn1_dec_null(ctrl, "chargeNotAvailable", tag, pos, end));
1815 		break;
1816 	case ASN1_CLASS_CONTEXT_SPECIFIC | 1:
1817 		aoc_d->type = 1;	/* free_of_charge */
1818 		ASN1_CALL(pos, asn1_dec_null(ctrl, "freeOfCharge", tag, pos, end));
1819 		break;
1820 	case ASN1_TAG_SEQUENCE:
1821 		aoc_d->type = 2;	/* specific_charging_units */
1822 
1823 		if (ctrl->debug & PRI_DEBUG_APDU) {
1824 			pri_message(ctrl, "  specificChargingUnits %s\n", asn1_tag2str(tag));
1825 		}
1826 		ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
1827 		ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
1828 
1829 		ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1830 		ASN1_CHECK_TAG(ctrl, tag, tag,
1831 			ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 1);
1832 		ASN1_CALL(pos, rose_dec_etsi_AOC_RecordedUnitsList(ctrl, "recordedUnitsList",
1833 			tag, pos, seq_end, &aoc_d->specific.recorded));
1834 
1835 		ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1836 		ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_CLASS_CONTEXT_SPECIFIC | 2);
1837 		ASN1_CALL(pos, asn1_dec_int(ctrl, "typeOfChargingInfo", tag, pos, seq_end,
1838 			&value));
1839 		aoc_d->specific.type_of_charging_info = value;
1840 
1841 		if (pos < seq_end && *pos != ASN1_INDEF_TERM) {
1842 			ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
1843 			ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_CLASS_CONTEXT_SPECIFIC | 3);
1844 			ASN1_CALL(pos, asn1_dec_int(ctrl, "billingId", tag, pos, seq_end, &value));
1845 			aoc_d->specific.billing_id = value;
1846 			aoc_d->specific.billing_id_present = 1;
1847 		} else {
1848 			aoc_d->specific.billing_id_present = 0;
1849 		}
1850 
1851 		ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
1852 		break;
1853 	default:
1854 		ASN1_DID_NOT_EXPECT_TAG(ctrl, tag);
1855 		return NULL;
1856 	}
1857 
1858 	return pos;
1859 }
1860 
1861 /*!
1862  * \brief Decode the AOCECurrency invoke argument parameters.
1863  *
1864  * \param ctrl D channel controller for diagnostic messages or global options.
1865  * \param tag Component tag that identified this structure.
1866  * \param pos Starting position of the ASN.1 component length.
1867  * \param end End of ASN.1 decoding data buffer.
1868  * \param args Arguments to fill in from the decoded buffer.
1869  *
1870  * \retval Start of the next ASN.1 component on success.
1871  * \retval NULL on error.
1872  */
rose_dec_etsi_AOCECurrency_ARG(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_invoke_args * args)1873 const unsigned char *rose_dec_etsi_AOCECurrency_ARG(struct pri *ctrl, unsigned tag,
1874 	const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
1875 {
1876 	struct roseEtsiAOCECurrency_ARG *aoc_e;
1877 
1878 	aoc_e = &args->etsi.AOCECurrency;
1879 	switch (tag) {
1880 	case ASN1_TYPE_NULL:
1881 		aoc_e->type = 0;	/* charge_not_available */
1882 		ASN1_CALL(pos, asn1_dec_null(ctrl, "chargeNotAvailable", tag, pos, end));
1883 		break;
1884 	case ASN1_TAG_SEQUENCE:
1885 		aoc_e->type = 1;	/* currency_info */
1886 		ASN1_CALL(pos, rose_dec_etsi_AOCECurrencyInfo(ctrl, "currencyInfo", tag, pos,
1887 			end, &aoc_e->currency_info));
1888 		break;
1889 	default:
1890 		ASN1_DID_NOT_EXPECT_TAG(ctrl, tag);
1891 		return NULL;
1892 	}
1893 
1894 	return pos;
1895 }
1896 
1897 /*!
1898  * \brief Decode the AOCEChargingUnit invoke argument parameters.
1899  *
1900  * \param ctrl D channel controller for diagnostic messages or global options.
1901  * \param tag Component tag that identified this structure.
1902  * \param pos Starting position of the ASN.1 component length.
1903  * \param end End of ASN.1 decoding data buffer.
1904  * \param args Arguments to fill in from the decoded buffer.
1905  *
1906  * \retval Start of the next ASN.1 component on success.
1907  * \retval NULL on error.
1908  */
rose_dec_etsi_AOCEChargingUnit_ARG(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_invoke_args * args)1909 const unsigned char *rose_dec_etsi_AOCEChargingUnit_ARG(struct pri *ctrl, unsigned tag,
1910 	const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
1911 {
1912 	struct roseEtsiAOCEChargingUnit_ARG *aoc_e;
1913 
1914 	aoc_e = &args->etsi.AOCEChargingUnit;
1915 	switch (tag) {
1916 	case ASN1_TYPE_NULL:
1917 		aoc_e->type = 0;	/* charge_not_available */
1918 		ASN1_CALL(pos, asn1_dec_null(ctrl, "chargeNotAvailable", tag, pos, end));
1919 		break;
1920 	case ASN1_TAG_SEQUENCE:
1921 		aoc_e->type = 1;	/* charging_unit */
1922 		ASN1_CALL(pos, rose_dec_etsi_AOCEChargingUnitInfo(ctrl, "chargingUnitInfo", tag,
1923 			pos, end, &aoc_e->charging_unit));
1924 		break;
1925 	default:
1926 		ASN1_DID_NOT_EXPECT_TAG(ctrl, tag);
1927 		return NULL;
1928 	}
1929 
1930 	return pos;
1931 }
1932 
1933 /* ------------------------------------------------------------------- */
1934 /* end rose_etsi_aoc.c */
1935