~ubuntu-branches/ubuntu/trusty/libpri/trusty

« back to all changes in this revision

Viewing changes to rose_etsi_mwi.c

  • Committer: Package Import Robot
  • Author(s): Faidon Liambotis
  • Date: 2011-11-26 17:25:59 UTC
  • mfrom: (1.3.11)
  • Revision ID: package-import@ubuntu.com-20111126172559-f6c5r81fgkn0krlb
Tags: 1.4.12-1
* New upstream release. 
  - Drop patch gcc-4.6-werror, not needed anymore.
  - Adapt patch enable-gcc-optimizations.
  - Updated symbols file with (a lot of) new symbols.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * libpri: An implementation of Primary Rate ISDN
 
3
 *
 
4
 * Copyright (C) 2010 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 Message Waiting Indication (MWI) operations
 
30
 *
 
31
 * Message Waiting Indication (MWI) supplementary service EN 300 745-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 MessageID 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 msg_id
 
55
 *
 
56
 * \retval Start of the next ASN.1 component to encode on success.
 
57
 * \retval NULL on error.
 
58
 */
 
59
static unsigned char *rose_enc_etsi_message_id(struct pri *ctrl, unsigned char *pos,
 
60
        unsigned char *end, const struct roseEtsiMessageID *msg_id)
 
61
{
 
62
        unsigned char *seq_len;
 
63
 
 
64
        ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
 
65
 
 
66
        ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_INTEGER, msg_id->reference_number));
 
67
        ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_ENUMERATED, msg_id->status));
 
68
 
 
69
        ASN1_CONSTRUCTED_END(seq_len, pos, end);
 
70
 
 
71
        return pos;
 
72
}
 
73
 
 
74
/*!
 
75
 * \brief Encode the MWIActivate invoke facility ie arguments.
 
76
 *
 
77
 * \param ctrl D channel controller for diagnostic messages or global options.
 
78
 * \param pos Starting position to encode ASN.1 component.
 
79
 * \param end End of ASN.1 encoding data buffer.
 
80
 * \param args Arguments to encode in the buffer.
 
81
 *
 
82
 * \retval Start of the next ASN.1 component to encode on success.
 
83
 * \retval NULL on error.
 
84
 */
 
85
unsigned char *rose_enc_etsi_MWIActivate_ARG(struct pri *ctrl, unsigned char *pos,
 
86
        unsigned char *end, const union rose_msg_invoke_args *args)
 
87
{
 
88
        const struct roseEtsiMWIActivate_ARG *mwi_activate;
 
89
        unsigned char *seq_len;
 
90
        unsigned char *explicit_len;
 
91
 
 
92
        ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
 
93
 
 
94
        mwi_activate = &args->etsi.MWIActivate;
 
95
        ASN1_CALL(pos, rose_enc_PartyNumber(ctrl, pos, end,
 
96
                &mwi_activate->receiving_user_number));
 
97
        ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_ENUMERATED,
 
98
                mwi_activate->basic_service));
 
99
        if (mwi_activate->controlling_user_number.length) {
 
100
                /* EXPLICIT tag */
 
101
                ASN1_CONSTRUCTED_BEGIN(explicit_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 1);
 
102
                ASN1_CALL(pos, rose_enc_PartyNumber(ctrl, pos, end,
 
103
                        &mwi_activate->controlling_user_number));
 
104
                ASN1_CONSTRUCTED_END(explicit_len, pos, end);
 
105
        }
 
106
        if (mwi_activate->number_of_messages_present) {
 
107
                /* EXPLICIT tag */
 
108
                ASN1_CONSTRUCTED_BEGIN(explicit_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 2);
 
109
                ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_INTEGER,
 
110
                        mwi_activate->number_of_messages));
 
111
                ASN1_CONSTRUCTED_END(explicit_len, pos, end);
 
112
        }
 
113
        if (mwi_activate->controlling_user_provided_number.length) {
 
114
                /* EXPLICIT tag */
 
115
                ASN1_CONSTRUCTED_BEGIN(explicit_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 3);
 
116
                ASN1_CALL(pos, rose_enc_PartyNumber(ctrl, pos, end,
 
117
                        &mwi_activate->controlling_user_provided_number));
 
118
                ASN1_CONSTRUCTED_END(explicit_len, pos, end);
 
119
        }
 
120
        if (mwi_activate->time_present) {
 
121
                /* EXPLICIT tag */
 
122
                ASN1_CONSTRUCTED_BEGIN(explicit_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 4);
 
123
                ASN1_CALL(pos, asn1_enc_string_max(pos, end, ASN1_TYPE_GENERALIZED_TIME,
 
124
                        mwi_activate->time.str, sizeof(mwi_activate->time.str) - 1));
 
125
                ASN1_CONSTRUCTED_END(explicit_len, pos, end);
 
126
        }
 
127
        if (mwi_activate->message_id_present) {
 
128
                /* EXPLICIT tag */
 
129
                ASN1_CONSTRUCTED_BEGIN(explicit_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 5);
 
130
                ASN1_CALL(pos, rose_enc_etsi_message_id(ctrl, pos, end,
 
131
                        &mwi_activate->message_id));
 
132
                ASN1_CONSTRUCTED_END(explicit_len, pos, end);
 
133
        }
 
134
        if (mwi_activate->mode_present) {
 
135
                /* EXPLICIT tag */
 
136
                ASN1_CONSTRUCTED_BEGIN(explicit_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 6);
 
137
                ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_ENUMERATED,
 
138
                        mwi_activate->mode));
 
139
                ASN1_CONSTRUCTED_END(explicit_len, pos, end);
 
140
        }
 
141
 
 
142
        ASN1_CONSTRUCTED_END(seq_len, pos, end);
 
143
 
 
144
        return pos;
 
145
}
 
146
 
 
147
/*!
 
148
 * \brief Encode the MWIDeactivate invoke facility ie arguments.
 
149
 *
 
150
 * \param ctrl D channel controller for diagnostic messages or global options.
 
151
 * \param pos Starting position to encode ASN.1 component.
 
152
 * \param end End of ASN.1 encoding data buffer.
 
153
 * \param args Arguments to encode in the buffer.
 
154
 *
 
155
 * \retval Start of the next ASN.1 component to encode on success.
 
156
 * \retval NULL on error.
 
157
 */
 
158
unsigned char *rose_enc_etsi_MWIDeactivate_ARG(struct pri *ctrl, unsigned char *pos,
 
159
        unsigned char *end, const union rose_msg_invoke_args *args)
 
160
{
 
161
        const struct roseEtsiMWIDeactivate_ARG *mwi_deactivate;
 
162
        unsigned char *seq_len;
 
163
 
 
164
        ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
 
165
 
 
166
        mwi_deactivate = &args->etsi.MWIDeactivate;
 
167
        ASN1_CALL(pos, rose_enc_PartyNumber(ctrl, pos, end,
 
168
                &mwi_deactivate->receiving_user_number));
 
169
        ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_ENUMERATED,
 
170
                mwi_deactivate->basic_service));
 
171
        if (mwi_deactivate->controlling_user_number.length) {
 
172
                ASN1_CALL(pos, rose_enc_PartyNumber(ctrl, pos, end,
 
173
                        &mwi_deactivate->controlling_user_number));
 
174
        }
 
175
        if (mwi_deactivate->mode_present) {
 
176
                ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_ENUMERATED,
 
177
                        mwi_deactivate->mode));
 
178
        }
 
179
 
 
180
        ASN1_CONSTRUCTED_END(seq_len, pos, end);
 
181
 
 
182
        return pos;
 
183
}
 
184
 
 
185
/*!
 
186
 * \brief Encode the MWIIndicate invoke facility ie arguments.
 
187
 *
 
188
 * \param ctrl D channel controller for diagnostic messages or global options.
 
189
 * \param pos Starting position to encode ASN.1 component.
 
190
 * \param end End of ASN.1 encoding data buffer.
 
191
 * \param args Arguments to encode in the buffer.
 
192
 *
 
193
 * \retval Start of the next ASN.1 component to encode on success.
 
194
 * \retval NULL on error.
 
195
 */
 
196
unsigned char *rose_enc_etsi_MWIIndicate_ARG(struct pri *ctrl, unsigned char *pos,
 
197
        unsigned char *end, const union rose_msg_invoke_args *args)
 
198
{
 
199
        const struct roseEtsiMWIIndicate_ARG *mwi_indicate;
 
200
        unsigned char *seq_len;
 
201
        unsigned char *explicit_len;
 
202
 
 
203
        ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
 
204
 
 
205
        mwi_indicate = &args->etsi.MWIIndicate;
 
206
        if (mwi_indicate->controlling_user_number.length) {
 
207
                /* EXPLICIT tag */
 
208
                ASN1_CONSTRUCTED_BEGIN(explicit_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 1);
 
209
                ASN1_CALL(pos, rose_enc_PartyNumber(ctrl, pos, end,
 
210
                        &mwi_indicate->controlling_user_number));
 
211
                ASN1_CONSTRUCTED_END(explicit_len, pos, end);
 
212
        }
 
213
        if (mwi_indicate->basic_service_present) {
 
214
                /* EXPLICIT tag */
 
215
                ASN1_CONSTRUCTED_BEGIN(explicit_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 2);
 
216
                ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_ENUMERATED,
 
217
                        mwi_indicate->basic_service));
 
218
                ASN1_CONSTRUCTED_END(explicit_len, pos, end);
 
219
        }
 
220
        if (mwi_indicate->number_of_messages_present) {
 
221
                /* EXPLICIT tag */
 
222
                ASN1_CONSTRUCTED_BEGIN(explicit_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 3);
 
223
                ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_INTEGER,
 
224
                        mwi_indicate->number_of_messages));
 
225
                ASN1_CONSTRUCTED_END(explicit_len, pos, end);
 
226
        }
 
227
        if (mwi_indicate->controlling_user_provided_number.length) {
 
228
                /* EXPLICIT tag */
 
229
                ASN1_CONSTRUCTED_BEGIN(explicit_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 4);
 
230
                ASN1_CALL(pos, rose_enc_PartyNumber(ctrl, pos, end,
 
231
                        &mwi_indicate->controlling_user_provided_number));
 
232
                ASN1_CONSTRUCTED_END(explicit_len, pos, end);
 
233
        }
 
234
        if (mwi_indicate->time_present) {
 
235
                /* EXPLICIT tag */
 
236
                ASN1_CONSTRUCTED_BEGIN(explicit_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 5);
 
237
                ASN1_CALL(pos, asn1_enc_string_max(pos, end, ASN1_TYPE_GENERALIZED_TIME,
 
238
                        mwi_indicate->time.str, sizeof(mwi_indicate->time.str) - 1));
 
239
                ASN1_CONSTRUCTED_END(explicit_len, pos, end);
 
240
        }
 
241
        if (mwi_indicate->message_id_present) {
 
242
                /* EXPLICIT tag */
 
243
                ASN1_CONSTRUCTED_BEGIN(explicit_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 6);
 
244
                ASN1_CALL(pos, rose_enc_etsi_message_id(ctrl, pos, end,
 
245
                        &mwi_indicate->message_id));
 
246
                ASN1_CONSTRUCTED_END(explicit_len, pos, end);
 
247
        }
 
248
 
 
249
        ASN1_CONSTRUCTED_END(seq_len, pos, end);
 
250
 
 
251
        return pos;
 
252
}
 
253
 
 
254
/*!
 
255
 * \internal
 
256
 * \brief Decode the MessageID argument parameters.
 
257
 *
 
258
 * \param ctrl D channel controller for any diagnostic messages.
 
259
 * \param name Field name
 
260
 * \param tag Component tag that identified this production.
 
261
 * \param pos Starting position of the ASN.1 component length.
 
262
 * \param end End of ASN.1 decoding data buffer.
 
263
 * \param msg_id Parameter storage to fill.
 
264
 *
 
265
 * \retval Start of the next ASN.1 component on success.
 
266
 * \retval NULL on error.
 
267
 */
 
268
static const unsigned char *rose_dec_etsi_message_id(struct pri *ctrl, const char *name,
 
269
        unsigned tag, const unsigned char *pos, const unsigned char *end,
 
270
        struct roseEtsiMessageID *msg_id)
 
271
{
 
272
        int32_t value;
 
273
        int length;
 
274
        int seq_offset;
 
275
        const unsigned char *seq_end;
 
276
 
 
277
        ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
 
278
        if (ctrl->debug & PRI_DEBUG_APDU) {
 
279
                pri_message(ctrl, "  %s MessageID %s\n", name, asn1_tag2str(tag));
 
280
        }
 
281
        ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
 
282
        ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
 
283
 
 
284
        ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
 
285
        ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_INTEGER);
 
286
        ASN1_CALL(pos, asn1_dec_int(ctrl, "messageRef", tag, pos, seq_end, &value));
 
287
        msg_id->reference_number = value;
 
288
 
 
289
        ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
 
290
        ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_ENUMERATED);
 
291
        ASN1_CALL(pos, asn1_dec_int(ctrl, "status", tag, pos, seq_end, &value));
 
292
        msg_id->status = value;
 
293
 
 
294
        ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
 
295
 
 
296
        return pos;
 
297
}
 
298
 
 
299
/*!
 
300
 * \brief Decode the MWIActivate invoke argument parameters.
 
301
 *
 
302
 * \param ctrl D channel controller for diagnostic messages or global options.
 
303
 * \param tag Component tag that identified this structure.
 
304
 * \param pos Starting position of the ASN.1 component length.
 
305
 * \param end End of ASN.1 decoding data buffer.
 
306
 * \param args Arguments to fill in from the decoded buffer.
 
307
 *
 
308
 * \retval Start of the next ASN.1 component on success.
 
309
 * \retval NULL on error.
 
310
 */
 
311
const unsigned char *rose_dec_etsi_MWIActivate_ARG(struct pri *ctrl, unsigned tag,
 
312
        const unsigned char *pos, const unsigned char *end,
 
313
        union rose_msg_invoke_args *args)
 
314
{
 
315
        int32_t value;
 
316
        size_t str_len;
 
317
        int length;
 
318
        int seq_offset;
 
319
        int explicit_offset;
 
320
        const unsigned char *explicit_end;
 
321
        const unsigned char *seq_end;
 
322
        const unsigned char *save_pos;
 
323
        struct roseEtsiMWIActivate_ARG *mwi_activate;
 
324
 
 
325
        mwi_activate = &args->etsi.MWIActivate;
 
326
 
 
327
        ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
 
328
        if (ctrl->debug & PRI_DEBUG_APDU) {
 
329
                pri_message(ctrl, "  MWIActivate %s\n", asn1_tag2str(tag));
 
330
        }
 
331
        ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
 
332
        ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
 
333
 
 
334
        ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
 
335
        ASN1_CALL(pos, rose_dec_PartyNumber(ctrl, "receivingUserNr", tag, pos, seq_end,
 
336
                &mwi_activate->receiving_user_number));
 
337
 
 
338
        ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
 
339
        ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_ENUMERATED);
 
340
        ASN1_CALL(pos, asn1_dec_int(ctrl, "basicService", tag, pos, seq_end, &value));
 
341
        mwi_activate->basic_service = value;
 
342
 
 
343
        /*
 
344
         * A sequence specifies an ordered list of component types.
 
345
         * However, for simplicity we are not checking the order of
 
346
         * the remaining optional components.
 
347
         */
 
348
        mwi_activate->controlling_user_number.length = 0;
 
349
        mwi_activate->number_of_messages_present = 0;
 
350
        mwi_activate->controlling_user_provided_number.length = 0;
 
351
        mwi_activate->time_present = 0;
 
352
        mwi_activate->message_id_present = 0;
 
353
        mwi_activate->mode_present = 0;
 
354
        while (pos < seq_end && *pos != ASN1_INDEF_TERM) {
 
355
                save_pos = pos;
 
356
                ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
 
357
                switch (tag) {
 
358
                case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 1:
 
359
                        /* Remove EXPLICIT tag */
 
360
                        if (ctrl->debug & PRI_DEBUG_APDU) {
 
361
                                pri_message(ctrl, "  Explicit %s\n", asn1_tag2str(tag));
 
362
                        }
 
363
                        ASN1_CALL(pos, asn1_dec_length(pos, seq_end, &length));
 
364
                        ASN1_END_SETUP(explicit_end, explicit_offset, length, pos, seq_end);
 
365
 
 
366
                        ASN1_CALL(pos, asn1_dec_tag(pos, explicit_end, &tag));
 
367
                        ASN1_CALL(pos, rose_dec_PartyNumber(ctrl, "controllingUserNr", tag, pos,
 
368
                                explicit_end, &mwi_activate->controlling_user_number));
 
369
 
 
370
                        ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
 
371
                        break;
 
372
                case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 2:
 
373
                        /* Remove EXPLICIT tag */
 
374
                        if (ctrl->debug & PRI_DEBUG_APDU) {
 
375
                                pri_message(ctrl, "  Explicit %s\n", asn1_tag2str(tag));
 
376
                        }
 
377
                        ASN1_CALL(pos, asn1_dec_length(pos, seq_end, &length));
 
378
                        ASN1_END_SETUP(explicit_end, explicit_offset, length, pos, seq_end);
 
379
 
 
380
                        ASN1_CALL(pos, asn1_dec_tag(pos, explicit_end, &tag));
 
381
                        ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_INTEGER);
 
382
                        ASN1_CALL(pos, asn1_dec_int(ctrl, "numberOfMessages", tag, pos, explicit_end,
 
383
                                &value));
 
384
                        mwi_activate->number_of_messages = value;
 
385
                        mwi_activate->number_of_messages_present = 1;
 
386
 
 
387
                        ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
 
388
                        break;
 
389
                case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 3:
 
390
                        /* Remove EXPLICIT tag */
 
391
                        if (ctrl->debug & PRI_DEBUG_APDU) {
 
392
                                pri_message(ctrl, "  Explicit %s\n", asn1_tag2str(tag));
 
393
                        }
 
394
                        ASN1_CALL(pos, asn1_dec_length(pos, seq_end, &length));
 
395
                        ASN1_END_SETUP(explicit_end, explicit_offset, length, pos, seq_end);
 
396
 
 
397
                        ASN1_CALL(pos, asn1_dec_tag(pos, explicit_end, &tag));
 
398
                        ASN1_CALL(pos, rose_dec_PartyNumber(ctrl, "controllingUserProvidedNr", tag,
 
399
                                pos, explicit_end, &mwi_activate->controlling_user_provided_number));
 
400
 
 
401
                        ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
 
402
                        break;
 
403
                case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 4:
 
404
                        /* Remove EXPLICIT tag */
 
405
                        if (ctrl->debug & PRI_DEBUG_APDU) {
 
406
                                pri_message(ctrl, "  Explicit %s\n", asn1_tag2str(tag));
 
407
                        }
 
408
                        ASN1_CALL(pos, asn1_dec_length(pos, seq_end, &length));
 
409
                        ASN1_END_SETUP(explicit_end, explicit_offset, length, pos, seq_end);
 
410
 
 
411
                        ASN1_CALL(pos, asn1_dec_tag(pos, explicit_end, &tag));
 
412
                        ASN1_CHECK_TAG(ctrl, tag & ~ASN1_PC_MASK, tag, ASN1_TYPE_GENERALIZED_TIME);
 
413
                        ASN1_CALL(pos, asn1_dec_string_max(ctrl, "time", tag, pos, explicit_end,
 
414
                                sizeof(mwi_activate->time.str), mwi_activate->time.str, &str_len));
 
415
                        mwi_activate->time_present = 1;
 
416
 
 
417
                        ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
 
418
                        break;
 
419
                case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 5:
 
420
                        /* Remove EXPLICIT tag */
 
421
                        if (ctrl->debug & PRI_DEBUG_APDU) {
 
422
                                pri_message(ctrl, "  Explicit %s\n", asn1_tag2str(tag));
 
423
                        }
 
424
                        ASN1_CALL(pos, asn1_dec_length(pos, seq_end, &length));
 
425
                        ASN1_END_SETUP(explicit_end, explicit_offset, length, pos, seq_end);
 
426
 
 
427
                        ASN1_CALL(pos, asn1_dec_tag(pos, explicit_end, &tag));
 
428
                        ASN1_CALL(pos, rose_dec_etsi_message_id(ctrl, "messageId", tag, pos,
 
429
                                explicit_end, &mwi_activate->message_id));
 
430
                        mwi_activate->message_id_present = 1;
 
431
 
 
432
                        ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
 
433
                        break;
 
434
                case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 6:
 
435
                        /* Remove EXPLICIT tag */
 
436
                        if (ctrl->debug & PRI_DEBUG_APDU) {
 
437
                                pri_message(ctrl, "  Explicit %s\n", asn1_tag2str(tag));
 
438
                        }
 
439
                        ASN1_CALL(pos, asn1_dec_length(pos, seq_end, &length));
 
440
                        ASN1_END_SETUP(explicit_end, explicit_offset, length, pos, seq_end);
 
441
 
 
442
                        ASN1_CALL(pos, asn1_dec_tag(pos, explicit_end, &tag));
 
443
                        ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_ENUMERATED);
 
444
                        ASN1_CALL(pos, asn1_dec_int(ctrl, "mode", tag, pos, explicit_end, &value));
 
445
                        mwi_activate->mode = value;
 
446
                        mwi_activate->mode_present = 1;
 
447
 
 
448
                        ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
 
449
                        break;
 
450
                default:
 
451
                        pos = save_pos;
 
452
                        goto cancel_options;
 
453
                }
 
454
        }
 
455
cancel_options:;
 
456
 
 
457
        ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
 
458
 
 
459
        return pos;
 
460
}
 
461
 
 
462
/*!
 
463
 * \brief Decode the MWIDeactivate invoke argument parameters.
 
464
 *
 
465
 * \param ctrl D channel controller for diagnostic messages or global options.
 
466
 * \param tag Component tag that identified this structure.
 
467
 * \param pos Starting position of the ASN.1 component length.
 
468
 * \param end End of ASN.1 decoding data buffer.
 
469
 * \param args Arguments to fill in from the decoded buffer.
 
470
 *
 
471
 * \retval Start of the next ASN.1 component on success.
 
472
 * \retval NULL on error.
 
473
 */
 
474
const unsigned char *rose_dec_etsi_MWIDeactivate_ARG(struct pri *ctrl, unsigned tag,
 
475
        const unsigned char *pos, const unsigned char *end,
 
476
        union rose_msg_invoke_args *args)
 
477
{
 
478
        int32_t value;
 
479
        int length;
 
480
        int seq_offset;
 
481
        const unsigned char *seq_end;
 
482
        struct roseEtsiMWIDeactivate_ARG *mwi_deactivate;
 
483
 
 
484
        mwi_deactivate = &args->etsi.MWIDeactivate;
 
485
 
 
486
        ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
 
487
        if (ctrl->debug & PRI_DEBUG_APDU) {
 
488
                pri_message(ctrl, "  MWIDeactivate %s\n", asn1_tag2str(tag));
 
489
        }
 
490
        ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
 
491
        ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
 
492
 
 
493
        ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
 
494
        ASN1_CALL(pos, rose_dec_PartyNumber(ctrl, "receivingUserNr", tag, pos, seq_end,
 
495
                &mwi_deactivate->receiving_user_number));
 
496
 
 
497
        ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
 
498
        ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_ENUMERATED);
 
499
        ASN1_CALL(pos, asn1_dec_int(ctrl, "basicService", tag, pos, seq_end, &value));
 
500
        mwi_deactivate->basic_service = value;
 
501
 
 
502
        /*
 
503
         * A sequence specifies an ordered list of component types.
 
504
         * However, for simplicity we are not checking the order of
 
505
         * the remaining optional components.
 
506
         */
 
507
        mwi_deactivate->controlling_user_number.length = 0;
 
508
        mwi_deactivate->mode_present = 0;
 
509
        while (pos < seq_end && *pos != ASN1_INDEF_TERM) {
 
510
                ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
 
511
                switch (tag) {
 
512
                default:
 
513
                        ASN1_CALL(pos, rose_dec_PartyNumber(ctrl, "controllingUserNr", tag, pos,
 
514
                                seq_end, &mwi_deactivate->controlling_user_number));
 
515
                        break;
 
516
                case ASN1_TYPE_ENUMERATED:
 
517
                        ASN1_CALL(pos, asn1_dec_int(ctrl, "mode", tag, pos, seq_end, &value));
 
518
                        mwi_deactivate->mode = value;
 
519
                        mwi_deactivate->mode_present = 1;
 
520
                        break;
 
521
                }
 
522
        }
 
523
 
 
524
        ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
 
525
 
 
526
        return pos;
 
527
}
 
528
 
 
529
/*!
 
530
 * \brief Decode the MWIIndicate invoke argument parameters.
 
531
 *
 
532
 * \param ctrl D channel controller for diagnostic messages or global options.
 
533
 * \param tag Component tag that identified this structure.
 
534
 * \param pos Starting position of the ASN.1 component length.
 
535
 * \param end End of ASN.1 decoding data buffer.
 
536
 * \param args Arguments to fill in from the decoded buffer.
 
537
 *
 
538
 * \retval Start of the next ASN.1 component on success.
 
539
 * \retval NULL on error.
 
540
 */
 
541
const unsigned char *rose_dec_etsi_MWIIndicate_ARG(struct pri *ctrl, unsigned tag,
 
542
        const unsigned char *pos, const unsigned char *end,
 
543
        union rose_msg_invoke_args *args)
 
544
{
 
545
        int32_t value;
 
546
        size_t str_len;
 
547
        int length;
 
548
        int seq_offset;
 
549
        int explicit_offset;
 
550
        const unsigned char *explicit_end;
 
551
        const unsigned char *seq_end;
 
552
        const unsigned char *save_pos;
 
553
        struct roseEtsiMWIIndicate_ARG *mwi_indicate;
 
554
 
 
555
        mwi_indicate = &args->etsi.MWIIndicate;
 
556
 
 
557
        ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
 
558
        if (ctrl->debug & PRI_DEBUG_APDU) {
 
559
                pri_message(ctrl, "  MWIIndicate %s\n", asn1_tag2str(tag));
 
560
        }
 
561
        ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
 
562
        ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
 
563
 
 
564
        /*
 
565
         * A sequence specifies an ordered list of component types.
 
566
         * However, for simplicity we are not checking the order of
 
567
         * the remaining optional components.
 
568
         */
 
569
        mwi_indicate->controlling_user_number.length = 0;
 
570
        mwi_indicate->basic_service_present = 0;
 
571
        mwi_indicate->number_of_messages_present = 0;
 
572
        mwi_indicate->controlling_user_provided_number.length = 0;
 
573
        mwi_indicate->time_present = 0;
 
574
        mwi_indicate->message_id_present = 0;
 
575
        while (pos < seq_end && *pos != ASN1_INDEF_TERM) {
 
576
                save_pos = pos;
 
577
                ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
 
578
                switch (tag) {
 
579
                case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 1:
 
580
                        /* Remove EXPLICIT tag */
 
581
                        if (ctrl->debug & PRI_DEBUG_APDU) {
 
582
                                pri_message(ctrl, "  Explicit %s\n", asn1_tag2str(tag));
 
583
                        }
 
584
                        ASN1_CALL(pos, asn1_dec_length(pos, seq_end, &length));
 
585
                        ASN1_END_SETUP(explicit_end, explicit_offset, length, pos, seq_end);
 
586
 
 
587
                        ASN1_CALL(pos, asn1_dec_tag(pos, explicit_end, &tag));
 
588
                        ASN1_CALL(pos, rose_dec_PartyNumber(ctrl, "controllingUserNr", tag, pos,
 
589
                                explicit_end, &mwi_indicate->controlling_user_number));
 
590
 
 
591
                        ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
 
592
                        break;
 
593
                case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 2:
 
594
                        /* Remove EXPLICIT tag */
 
595
                        if (ctrl->debug & PRI_DEBUG_APDU) {
 
596
                                pri_message(ctrl, "  Explicit %s\n", asn1_tag2str(tag));
 
597
                        }
 
598
                        ASN1_CALL(pos, asn1_dec_length(pos, seq_end, &length));
 
599
                        ASN1_END_SETUP(explicit_end, explicit_offset, length, pos, seq_end);
 
600
 
 
601
                        ASN1_CALL(pos, asn1_dec_tag(pos, explicit_end, &tag));
 
602
                        ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_ENUMERATED);
 
603
                        ASN1_CALL(pos, asn1_dec_int(ctrl, "basicService", tag, pos, explicit_end,
 
604
                                &value));
 
605
                        mwi_indicate->basic_service = value;
 
606
                        mwi_indicate->basic_service_present = 1;
 
607
 
 
608
                        ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
 
609
                        break;
 
610
                case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 3:
 
611
                        /* Remove EXPLICIT tag */
 
612
                        if (ctrl->debug & PRI_DEBUG_APDU) {
 
613
                                pri_message(ctrl, "  Explicit %s\n", asn1_tag2str(tag));
 
614
                        }
 
615
                        ASN1_CALL(pos, asn1_dec_length(pos, seq_end, &length));
 
616
                        ASN1_END_SETUP(explicit_end, explicit_offset, length, pos, seq_end);
 
617
 
 
618
                        ASN1_CALL(pos, asn1_dec_tag(pos, explicit_end, &tag));
 
619
                        ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_INTEGER);
 
620
                        ASN1_CALL(pos, asn1_dec_int(ctrl, "numberOfMessages", tag, pos, explicit_end,
 
621
                                &value));
 
622
                        mwi_indicate->number_of_messages = value;
 
623
                        mwi_indicate->number_of_messages_present = 1;
 
624
 
 
625
                        ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
 
626
                        break;
 
627
                case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 4:
 
628
                        /* Remove EXPLICIT tag */
 
629
                        if (ctrl->debug & PRI_DEBUG_APDU) {
 
630
                                pri_message(ctrl, "  Explicit %s\n", asn1_tag2str(tag));
 
631
                        }
 
632
                        ASN1_CALL(pos, asn1_dec_length(pos, seq_end, &length));
 
633
                        ASN1_END_SETUP(explicit_end, explicit_offset, length, pos, seq_end);
 
634
 
 
635
                        ASN1_CALL(pos, asn1_dec_tag(pos, explicit_end, &tag));
 
636
                        ASN1_CALL(pos, rose_dec_PartyNumber(ctrl, "controllingUserProvidedNr", tag,
 
637
                                pos, explicit_end, &mwi_indicate->controlling_user_provided_number));
 
638
 
 
639
                        ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
 
640
                        break;
 
641
                case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 5:
 
642
                        /* Remove EXPLICIT tag */
 
643
                        if (ctrl->debug & PRI_DEBUG_APDU) {
 
644
                                pri_message(ctrl, "  Explicit %s\n", asn1_tag2str(tag));
 
645
                        }
 
646
                        ASN1_CALL(pos, asn1_dec_length(pos, seq_end, &length));
 
647
                        ASN1_END_SETUP(explicit_end, explicit_offset, length, pos, seq_end);
 
648
 
 
649
                        ASN1_CALL(pos, asn1_dec_tag(pos, explicit_end, &tag));
 
650
                        ASN1_CHECK_TAG(ctrl, tag & ~ASN1_PC_MASK, tag, ASN1_TYPE_GENERALIZED_TIME);
 
651
                        ASN1_CALL(pos, asn1_dec_string_max(ctrl, "time", tag, pos, explicit_end,
 
652
                                sizeof(mwi_indicate->time.str), mwi_indicate->time.str, &str_len));
 
653
                        mwi_indicate->time_present = 1;
 
654
 
 
655
                        ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
 
656
                        break;
 
657
                case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 6:
 
658
                        /* Remove EXPLICIT tag */
 
659
                        if (ctrl->debug & PRI_DEBUG_APDU) {
 
660
                                pri_message(ctrl, "  Explicit %s\n", asn1_tag2str(tag));
 
661
                        }
 
662
                        ASN1_CALL(pos, asn1_dec_length(pos, seq_end, &length));
 
663
                        ASN1_END_SETUP(explicit_end, explicit_offset, length, pos, seq_end);
 
664
 
 
665
                        ASN1_CALL(pos, asn1_dec_tag(pos, explicit_end, &tag));
 
666
                        ASN1_CALL(pos, rose_dec_etsi_message_id(ctrl, "messageId", tag, pos,
 
667
                                explicit_end, &mwi_indicate->message_id));
 
668
                        mwi_indicate->message_id_present = 1;
 
669
 
 
670
                        ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
 
671
                        break;
 
672
                default:
 
673
                        pos = save_pos;
 
674
                        goto cancel_options;
 
675
                }
 
676
        }
 
677
cancel_options:;
 
678
 
 
679
        ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
 
680
 
 
681
        return pos;
 
682
}
 
683
 
 
684
 
 
685
/* ------------------------------------------------------------------- */
 
686
/* end rose_etsi_mwi.c */