2
* libpri: An implementation of Primary Rate ISDN
4
* Copyright (C) 2010 Digium, Inc.
6
* Richard Mudgett <rmudgett@digium.com>
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.
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.
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
29
* \brief ROSE Message Waiting Indication (MWI) operations
31
* Message Waiting Indication (MWI) supplementary service EN 300 745-1
33
* \author Richard Mudgett <rmudgett@digium.com>
39
#include "pri_internal.h"
41
#include "rose_internal.h"
45
/* ------------------------------------------------------------------- */
49
* \brief Encode the MessageID type.
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.
56
* \retval Start of the next ASN.1 component to encode on success.
57
* \retval NULL on error.
59
static unsigned char *rose_enc_etsi_message_id(struct pri *ctrl, unsigned char *pos,
60
unsigned char *end, const struct roseEtsiMessageID *msg_id)
62
unsigned char *seq_len;
64
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
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));
69
ASN1_CONSTRUCTED_END(seq_len, pos, end);
75
* \brief Encode the MWIActivate invoke facility ie arguments.
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.
82
* \retval Start of the next ASN.1 component to encode on success.
83
* \retval NULL on error.
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)
88
const struct roseEtsiMWIActivate_ARG *mwi_activate;
89
unsigned char *seq_len;
90
unsigned char *explicit_len;
92
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
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) {
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);
106
if (mwi_activate->number_of_messages_present) {
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);
113
if (mwi_activate->controlling_user_provided_number.length) {
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);
120
if (mwi_activate->time_present) {
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);
127
if (mwi_activate->message_id_present) {
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);
134
if (mwi_activate->mode_present) {
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);
142
ASN1_CONSTRUCTED_END(seq_len, pos, end);
148
* \brief Encode the MWIDeactivate invoke facility ie arguments.
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.
155
* \retval Start of the next ASN.1 component to encode on success.
156
* \retval NULL on error.
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)
161
const struct roseEtsiMWIDeactivate_ARG *mwi_deactivate;
162
unsigned char *seq_len;
164
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
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));
175
if (mwi_deactivate->mode_present) {
176
ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_ENUMERATED,
177
mwi_deactivate->mode));
180
ASN1_CONSTRUCTED_END(seq_len, pos, end);
186
* \brief Encode the MWIIndicate invoke facility ie arguments.
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.
193
* \retval Start of the next ASN.1 component to encode on success.
194
* \retval NULL on error.
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)
199
const struct roseEtsiMWIIndicate_ARG *mwi_indicate;
200
unsigned char *seq_len;
201
unsigned char *explicit_len;
203
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
205
mwi_indicate = &args->etsi.MWIIndicate;
206
if (mwi_indicate->controlling_user_number.length) {
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);
213
if (mwi_indicate->basic_service_present) {
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);
220
if (mwi_indicate->number_of_messages_present) {
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);
227
if (mwi_indicate->controlling_user_provided_number.length) {
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);
234
if (mwi_indicate->time_present) {
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);
241
if (mwi_indicate->message_id_present) {
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);
249
ASN1_CONSTRUCTED_END(seq_len, pos, end);
256
* \brief Decode the MessageID argument parameters.
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.
265
* \retval Start of the next ASN.1 component on success.
266
* \retval NULL on error.
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)
275
const unsigned char *seq_end;
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));
281
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
282
ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
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;
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;
294
ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
300
* \brief Decode the MWIActivate invoke argument parameters.
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.
308
* \retval Start of the next ASN.1 component on success.
309
* \retval NULL on error.
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)
320
const unsigned char *explicit_end;
321
const unsigned char *seq_end;
322
const unsigned char *save_pos;
323
struct roseEtsiMWIActivate_ARG *mwi_activate;
325
mwi_activate = &args->etsi.MWIActivate;
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));
331
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
332
ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
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));
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;
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.
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) {
356
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &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));
363
ASN1_CALL(pos, asn1_dec_length(pos, seq_end, &length));
364
ASN1_END_SETUP(explicit_end, explicit_offset, length, pos, seq_end);
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));
370
ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
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));
377
ASN1_CALL(pos, asn1_dec_length(pos, seq_end, &length));
378
ASN1_END_SETUP(explicit_end, explicit_offset, length, pos, seq_end);
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,
384
mwi_activate->number_of_messages = value;
385
mwi_activate->number_of_messages_present = 1;
387
ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
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));
394
ASN1_CALL(pos, asn1_dec_length(pos, seq_end, &length));
395
ASN1_END_SETUP(explicit_end, explicit_offset, length, pos, seq_end);
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));
401
ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
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));
408
ASN1_CALL(pos, asn1_dec_length(pos, seq_end, &length));
409
ASN1_END_SETUP(explicit_end, explicit_offset, length, pos, seq_end);
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;
417
ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
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));
424
ASN1_CALL(pos, asn1_dec_length(pos, seq_end, &length));
425
ASN1_END_SETUP(explicit_end, explicit_offset, length, pos, seq_end);
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;
432
ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
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));
439
ASN1_CALL(pos, asn1_dec_length(pos, seq_end, &length));
440
ASN1_END_SETUP(explicit_end, explicit_offset, length, pos, seq_end);
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;
448
ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
457
ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
463
* \brief Decode the MWIDeactivate invoke argument parameters.
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.
471
* \retval Start of the next ASN.1 component on success.
472
* \retval NULL on error.
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)
481
const unsigned char *seq_end;
482
struct roseEtsiMWIDeactivate_ARG *mwi_deactivate;
484
mwi_deactivate = &args->etsi.MWIDeactivate;
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));
490
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
491
ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
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));
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;
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.
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));
513
ASN1_CALL(pos, rose_dec_PartyNumber(ctrl, "controllingUserNr", tag, pos,
514
seq_end, &mwi_deactivate->controlling_user_number));
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;
524
ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
530
* \brief Decode the MWIIndicate invoke argument parameters.
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.
538
* \retval Start of the next ASN.1 component on success.
539
* \retval NULL on error.
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)
550
const unsigned char *explicit_end;
551
const unsigned char *seq_end;
552
const unsigned char *save_pos;
553
struct roseEtsiMWIIndicate_ARG *mwi_indicate;
555
mwi_indicate = &args->etsi.MWIIndicate;
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));
561
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
562
ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
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.
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) {
577
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &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));
584
ASN1_CALL(pos, asn1_dec_length(pos, seq_end, &length));
585
ASN1_END_SETUP(explicit_end, explicit_offset, length, pos, seq_end);
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));
591
ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
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));
598
ASN1_CALL(pos, asn1_dec_length(pos, seq_end, &length));
599
ASN1_END_SETUP(explicit_end, explicit_offset, length, pos, seq_end);
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,
605
mwi_indicate->basic_service = value;
606
mwi_indicate->basic_service_present = 1;
608
ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
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));
615
ASN1_CALL(pos, asn1_dec_length(pos, seq_end, &length));
616
ASN1_END_SETUP(explicit_end, explicit_offset, length, pos, seq_end);
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,
622
mwi_indicate->number_of_messages = value;
623
mwi_indicate->number_of_messages_present = 1;
625
ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
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));
632
ASN1_CALL(pos, asn1_dec_length(pos, seq_end, &length));
633
ASN1_END_SETUP(explicit_end, explicit_offset, length, pos, seq_end);
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));
639
ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
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));
646
ASN1_CALL(pos, asn1_dec_length(pos, seq_end, &length));
647
ASN1_END_SETUP(explicit_end, explicit_offset, length, pos, seq_end);
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;
655
ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
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));
662
ASN1_CALL(pos, asn1_dec_length(pos, seq_end, &length));
663
ASN1_END_SETUP(explicit_end, explicit_offset, length, pos, seq_end);
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;
670
ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
679
ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
685
/* ------------------------------------------------------------------- */
686
/* end rose_etsi_mwi.c */