6829faae06
Call Completion Supplementary Service (CCSS) added for the following switch types: ETSI PTMP, ETSI PTP, Q.SIG. Specifications: ETS 300 359 CCBS for PTMP and PTP ETS 301 065 CCNR for PTMP and PTP ECMA-186 Call Completion for Q.SIG Several support services were added to support CC: Dummy Call Reference. Q.931 REGISTER message. Dynamic expansion of the number of available timers (up to 8192). Enhanced facility message handling. Current implementation limitations preclude the following: CC service retention is not supported. Q.SIG path reservation is not supported. (closes issue #14292) Reported by: tomaso Tested by: rmudgett JIRA SWP-1493 Review: https://reviewboard.asterisk.org/r/522/ git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.4@1714 2fbb986a-6c06-0410-b554-c9c1f0a7f128
985 lines
34 KiB
C
985 lines
34 KiB
C
/*
|
|
* libpri: An implementation of Primary Rate ISDN
|
|
*
|
|
* Copyright (C) 2009 Digium, Inc.
|
|
*
|
|
* Richard Mudgett <rmudgett@digium.com>
|
|
*
|
|
* See http://www.asterisk.org for more information about
|
|
* the Asterisk project. Please do not directly contact
|
|
* any of the maintainers of this project for assistance;
|
|
* the project provides a web site, mailing lists and IRC
|
|
* channels for your use.
|
|
*
|
|
* This program is free software, distributed under the terms of
|
|
* the GNU General Public License Version 2 as published by the
|
|
* Free Software Foundation. See the LICENSE file included with
|
|
* this program for more details.
|
|
*
|
|
* In addition, when this program is distributed with Asterisk in
|
|
* any form that would qualify as a 'combined work' or as a
|
|
* 'derivative work' (but not mere aggregation), you can redistribute
|
|
* and/or modify the combination under the terms of the license
|
|
* provided with that copy of Asterisk, instead of the license
|
|
* terms granted here.
|
|
*/
|
|
|
|
/*!
|
|
* \file
|
|
* \brief Q.SIG ROSE SS-CC-Operations (CC)
|
|
*
|
|
* SS-CC-Operations ECMA-186 Annex F Table F.1
|
|
*
|
|
* \author Richard Mudgett <rmudgett@digium.com>
|
|
*/
|
|
|
|
|
|
#include "compat.h"
|
|
#include "libpri.h"
|
|
#include "pri_internal.h"
|
|
#include "rose.h"
|
|
#include "rose_internal.h"
|
|
#include "asn1.h"
|
|
|
|
|
|
/* ------------------------------------------------------------------- */
|
|
|
|
/*!
|
|
* \internal
|
|
* \brief Encode the CcExtension type.
|
|
*
|
|
* \param ctrl D channel controller for diagnostic messages or global options.
|
|
* \param pos Starting position to encode ASN.1 component.
|
|
* \param end End of ASN.1 encoding data buffer.
|
|
*
|
|
* \retval Start of the next ASN.1 component to encode on success.
|
|
* \retval NULL on error.
|
|
*
|
|
* \details
|
|
* CcExtension ::= CHOICE {
|
|
* none NULL,
|
|
* single [14] IMPLICIT Extension,
|
|
* multiple [15] IMPLICIT SEQUENCE OF Extension
|
|
* }
|
|
*/
|
|
static unsigned char *rose_enc_qsig_CcExtension(struct pri *ctrl, unsigned char *pos,
|
|
unsigned char *end)
|
|
{
|
|
return asn1_enc_null(pos, end, ASN1_TYPE_NULL);
|
|
}
|
|
|
|
/*!
|
|
* \internal
|
|
* \brief Encode the CcRequestArg type.
|
|
*
|
|
* \param ctrl D channel controller for diagnostic messages or global options.
|
|
* \param pos Starting position to encode ASN.1 component.
|
|
* \param end End of ASN.1 encoding data buffer.
|
|
* \param tag Component tag to identify the encoded component.
|
|
* The tag should be ASN1_TAG_SEQUENCE unless the caller implicitly
|
|
* tags it otherwise.
|
|
* \param cc_request_arg Call-completion request arguments to encode.
|
|
*
|
|
* \retval Start of the next ASN.1 component to encode on success.
|
|
* \retval NULL on error.
|
|
*/
|
|
static unsigned char *rose_enc_qsig_CcRequestArg(struct pri *ctrl, unsigned char *pos,
|
|
unsigned char *end, unsigned tag, const struct roseQsigCcRequestArg *cc_request_arg)
|
|
{
|
|
unsigned char *seq_len;
|
|
unsigned char *exp_len;
|
|
|
|
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, tag);
|
|
|
|
ASN1_CALL(pos, rose_enc_PresentedNumberUnscreened(ctrl, pos, end,
|
|
&cc_request_arg->number_a));
|
|
ASN1_CALL(pos, rose_enc_PartyNumber(ctrl, pos, end, &cc_request_arg->number_b));
|
|
ASN1_CALL(pos, rose_enc_Q931ie(ctrl, pos, end, ASN1_CLASS_APPLICATION | 0,
|
|
&cc_request_arg->q931ie));
|
|
|
|
if (cc_request_arg->subaddr_a.length) {
|
|
/* EXPLICIT tag */
|
|
ASN1_CONSTRUCTED_BEGIN(exp_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 10);
|
|
ASN1_CALL(pos, rose_enc_PartySubaddress(ctrl, pos, end,
|
|
&cc_request_arg->subaddr_a));
|
|
ASN1_CONSTRUCTED_END(exp_len, pos, end);
|
|
}
|
|
|
|
if (cc_request_arg->subaddr_b.length) {
|
|
/* EXPLICIT tag */
|
|
ASN1_CONSTRUCTED_BEGIN(exp_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 11);
|
|
ASN1_CALL(pos, rose_enc_PartySubaddress(ctrl, pos, end,
|
|
&cc_request_arg->subaddr_b));
|
|
ASN1_CONSTRUCTED_END(exp_len, pos, end);
|
|
}
|
|
|
|
if (cc_request_arg->can_retain_service) {
|
|
/* Not the DEFAULT value */
|
|
ASN1_CALL(pos, asn1_enc_boolean(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 12,
|
|
cc_request_arg->can_retain_service));
|
|
}
|
|
|
|
if (cc_request_arg->retain_sig_connection_present) {
|
|
ASN1_CALL(pos, asn1_enc_boolean(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 13,
|
|
cc_request_arg->retain_sig_connection));
|
|
}
|
|
|
|
/* No extension to encode */
|
|
|
|
ASN1_CONSTRUCTED_END(seq_len, pos, end);
|
|
|
|
return pos;
|
|
}
|
|
|
|
/*!
|
|
* \brief Encode the Q.SIG CcbsRequest invoke facility ie arguments.
|
|
*
|
|
* \param ctrl D channel controller for diagnostic messages or global options.
|
|
* \param pos Starting position to encode ASN.1 component.
|
|
* \param end End of ASN.1 encoding data buffer.
|
|
* \param args Arguments to encode in the buffer.
|
|
*
|
|
* \retval Start of the next ASN.1 component to encode on success.
|
|
* \retval NULL on error.
|
|
*/
|
|
unsigned char *rose_enc_qsig_CcbsRequest_ARG(struct pri *ctrl, unsigned char *pos,
|
|
unsigned char *end, const union rose_msg_invoke_args *args)
|
|
{
|
|
return rose_enc_qsig_CcRequestArg(ctrl, pos, end, ASN1_TAG_SEQUENCE,
|
|
&args->qsig.CcbsRequest);
|
|
}
|
|
|
|
/*!
|
|
* \brief Encode the Q.SIG CcnrRequest invoke facility ie arguments.
|
|
*
|
|
* \param ctrl D channel controller for diagnostic messages or global options.
|
|
* \param pos Starting position to encode ASN.1 component.
|
|
* \param end End of ASN.1 encoding data buffer.
|
|
* \param args Arguments to encode in the buffer.
|
|
*
|
|
* \retval Start of the next ASN.1 component to encode on success.
|
|
* \retval NULL on error.
|
|
*/
|
|
unsigned char *rose_enc_qsig_CcnrRequest_ARG(struct pri *ctrl, unsigned char *pos,
|
|
unsigned char *end, const union rose_msg_invoke_args *args)
|
|
{
|
|
return rose_enc_qsig_CcRequestArg(ctrl, pos, end, ASN1_TAG_SEQUENCE,
|
|
&args->qsig.CcnrRequest);
|
|
}
|
|
|
|
/*!
|
|
* \internal
|
|
* \brief Encode the CcRequestRes type.
|
|
*
|
|
* \param ctrl D channel controller for diagnostic messages or global options.
|
|
* \param pos Starting position to encode ASN.1 component.
|
|
* \param end End of ASN.1 encoding data buffer.
|
|
* \param tag Component tag to identify the encoded component.
|
|
* The tag should be ASN1_TAG_SEQUENCE unless the caller implicitly
|
|
* tags it otherwise.
|
|
* \param cc_request_res Call-completion request result to encode.
|
|
*
|
|
* \retval Start of the next ASN.1 component to encode on success.
|
|
* \retval NULL on error.
|
|
*/
|
|
static unsigned char *rose_enc_qsig_CcRequestRes(struct pri *ctrl, unsigned char *pos,
|
|
unsigned char *end, unsigned tag, const struct roseQsigCcRequestRes *cc_request_res)
|
|
{
|
|
unsigned char *seq_len;
|
|
|
|
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, tag);
|
|
|
|
if (cc_request_res->no_path_reservation) {
|
|
/* Not the DEFAULT value */
|
|
ASN1_CALL(pos, asn1_enc_boolean(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 0,
|
|
cc_request_res->no_path_reservation));
|
|
}
|
|
|
|
if (cc_request_res->retain_service) {
|
|
/* Not the DEFAULT value */
|
|
ASN1_CALL(pos, asn1_enc_boolean(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 1,
|
|
cc_request_res->retain_service));
|
|
}
|
|
|
|
/* No extension to encode */
|
|
|
|
ASN1_CONSTRUCTED_END(seq_len, pos, end);
|
|
|
|
return pos;
|
|
}
|
|
|
|
/*!
|
|
* \brief Encode the Q.SIG CcbsRequest result facility ie arguments.
|
|
*
|
|
* \param ctrl D channel controller for diagnostic messages or global options.
|
|
* \param pos Starting position to encode ASN.1 component.
|
|
* \param end End of ASN.1 encoding data buffer.
|
|
* \param args Arguments to encode in the buffer.
|
|
*
|
|
* \retval Start of the next ASN.1 component to encode on success.
|
|
* \retval NULL on error.
|
|
*/
|
|
unsigned char *rose_enc_qsig_CcbsRequest_RES(struct pri *ctrl, unsigned char *pos,
|
|
unsigned char *end, const union rose_msg_result_args *args)
|
|
{
|
|
return rose_enc_qsig_CcRequestRes(ctrl, pos, end, ASN1_TAG_SEQUENCE,
|
|
&args->qsig.CcbsRequest);
|
|
}
|
|
|
|
/*!
|
|
* \brief Encode the Q.SIG CcnrRequest result facility ie arguments.
|
|
*
|
|
* \param ctrl D channel controller for diagnostic messages or global options.
|
|
* \param pos Starting position to encode ASN.1 component.
|
|
* \param end End of ASN.1 encoding data buffer.
|
|
* \param args Arguments to encode in the buffer.
|
|
*
|
|
* \retval Start of the next ASN.1 component to encode on success.
|
|
* \retval NULL on error.
|
|
*/
|
|
unsigned char *rose_enc_qsig_CcnrRequest_RES(struct pri *ctrl, unsigned char *pos,
|
|
unsigned char *end, const union rose_msg_result_args *args)
|
|
{
|
|
return rose_enc_qsig_CcRequestRes(ctrl, pos, end, ASN1_TAG_SEQUENCE,
|
|
&args->qsig.CcnrRequest);
|
|
}
|
|
|
|
/*!
|
|
* \internal
|
|
* \brief Encode the CcOptionalArg type.
|
|
*
|
|
* \param ctrl D channel controller for diagnostic messages or global options.
|
|
* \param pos Starting position to encode ASN.1 component.
|
|
* \param end End of ASN.1 encoding data buffer.
|
|
* \param cc_optional_arg Call-completion optional arguments to encode.
|
|
*
|
|
* \retval Start of the next ASN.1 component to encode on success.
|
|
* \retval NULL on error.
|
|
*/
|
|
static unsigned char *rose_enc_qsig_CcOptionalArg(struct pri *ctrl, unsigned char *pos,
|
|
unsigned char *end, const struct roseQsigCcOptionalArg *cc_optional_arg)
|
|
{
|
|
unsigned char *seq_len;
|
|
unsigned char *exp_len;
|
|
|
|
if (!cc_optional_arg->full_arg_present) {
|
|
return rose_enc_qsig_CcExtension(ctrl, pos, end);
|
|
}
|
|
|
|
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 0);
|
|
|
|
ASN1_CALL(pos, rose_enc_PartyNumber(ctrl, pos, end, &cc_optional_arg->number_a));
|
|
ASN1_CALL(pos, rose_enc_PartyNumber(ctrl, pos, end, &cc_optional_arg->number_b));
|
|
ASN1_CALL(pos, rose_enc_Q931ie(ctrl, pos, end, ASN1_CLASS_APPLICATION | 0,
|
|
&cc_optional_arg->q931ie));
|
|
|
|
if (cc_optional_arg->subaddr_a.length) {
|
|
/* EXPLICIT tag */
|
|
ASN1_CONSTRUCTED_BEGIN(exp_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 10);
|
|
ASN1_CALL(pos, rose_enc_PartySubaddress(ctrl, pos, end,
|
|
&cc_optional_arg->subaddr_a));
|
|
ASN1_CONSTRUCTED_END(exp_len, pos, end);
|
|
}
|
|
|
|
if (cc_optional_arg->subaddr_b.length) {
|
|
/* EXPLICIT tag */
|
|
ASN1_CONSTRUCTED_BEGIN(exp_len, pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 11);
|
|
ASN1_CALL(pos, rose_enc_PartySubaddress(ctrl, pos, end,
|
|
&cc_optional_arg->subaddr_b));
|
|
ASN1_CONSTRUCTED_END(exp_len, pos, end);
|
|
}
|
|
|
|
/* No extension to encode */
|
|
|
|
ASN1_CONSTRUCTED_END(seq_len, pos, end);
|
|
|
|
return pos;
|
|
}
|
|
|
|
/*!
|
|
* \brief Encode the Q.SIG CcCancel invoke facility ie arguments.
|
|
*
|
|
* \param ctrl D channel controller for diagnostic messages or global options.
|
|
* \param pos Starting position to encode ASN.1 component.
|
|
* \param end End of ASN.1 encoding data buffer.
|
|
* \param args Arguments to encode in the buffer.
|
|
*
|
|
* \retval Start of the next ASN.1 component to encode on success.
|
|
* \retval NULL on error.
|
|
*/
|
|
unsigned char *rose_enq_qsig_CcCancel_ARG(struct pri *ctrl, unsigned char *pos,
|
|
unsigned char *end, const union rose_msg_invoke_args *args)
|
|
{
|
|
return rose_enc_qsig_CcOptionalArg(ctrl, pos, end, &args->qsig.CcCancel);
|
|
}
|
|
|
|
/*!
|
|
* \brief Encode the Q.SIG CcExecPossible invoke facility ie arguments.
|
|
*
|
|
* \param ctrl D channel controller for diagnostic messages or global options.
|
|
* \param pos Starting position to encode ASN.1 component.
|
|
* \param end End of ASN.1 encoding data buffer.
|
|
* \param args Arguments to encode in the buffer.
|
|
*
|
|
* \retval Start of the next ASN.1 component to encode on success.
|
|
* \retval NULL on error.
|
|
*/
|
|
unsigned char *rose_enq_qsig_CcExecPossible_ARG(struct pri *ctrl, unsigned char *pos,
|
|
unsigned char *end, const union rose_msg_invoke_args *args)
|
|
{
|
|
return rose_enc_qsig_CcOptionalArg(ctrl, pos, end, &args->qsig.CcExecPossible);
|
|
}
|
|
|
|
/*!
|
|
* \brief Encode the Q.SIG CcPathReserve invoke facility ie arguments.
|
|
*
|
|
* \param ctrl D channel controller for diagnostic messages or global options.
|
|
* \param pos Starting position to encode ASN.1 component.
|
|
* \param end End of ASN.1 encoding data buffer.
|
|
* \param args Arguments to encode in the buffer.
|
|
*
|
|
* \retval Start of the next ASN.1 component to encode on success.
|
|
* \retval NULL on error.
|
|
*/
|
|
unsigned char *rose_enc_qsig_CcPathReserve_ARG(struct pri *ctrl, unsigned char *pos,
|
|
unsigned char *end, const union rose_msg_invoke_args *args)
|
|
{
|
|
return rose_enc_qsig_CcExtension(ctrl, pos, end);
|
|
}
|
|
|
|
/*!
|
|
* \brief Encode the Q.SIG CcPathReserve result facility ie arguments.
|
|
*
|
|
* \param ctrl D channel controller for diagnostic messages or global options.
|
|
* \param pos Starting position to encode ASN.1 component.
|
|
* \param end End of ASN.1 encoding data buffer.
|
|
* \param args Arguments to encode in the buffer.
|
|
*
|
|
* \retval Start of the next ASN.1 component to encode on success.
|
|
* \retval NULL on error.
|
|
*/
|
|
unsigned char *rose_enc_qsig_CcPathReserve_RES(struct pri *ctrl, unsigned char *pos,
|
|
unsigned char *end, const union rose_msg_result_args *args)
|
|
{
|
|
return rose_enc_qsig_CcExtension(ctrl, pos, end);
|
|
}
|
|
|
|
/*!
|
|
* \brief Encode the Q.SIG CcRingout invoke facility ie arguments.
|
|
*
|
|
* \param ctrl D channel controller for diagnostic messages or global options.
|
|
* \param pos Starting position to encode ASN.1 component.
|
|
* \param end End of ASN.1 encoding data buffer.
|
|
* \param args Arguments to encode in the buffer.
|
|
*
|
|
* \retval Start of the next ASN.1 component to encode on success.
|
|
* \retval NULL on error.
|
|
*/
|
|
unsigned char *rose_enc_qsig_CcRingout_ARG(struct pri *ctrl, unsigned char *pos,
|
|
unsigned char *end, const union rose_msg_invoke_args *args)
|
|
{
|
|
return rose_enc_qsig_CcExtension(ctrl, pos, end);
|
|
}
|
|
|
|
/*!
|
|
* \brief Encode the Q.SIG CcSuspend invoke facility ie arguments.
|
|
*
|
|
* \param ctrl D channel controller for diagnostic messages or global options.
|
|
* \param pos Starting position to encode ASN.1 component.
|
|
* \param end End of ASN.1 encoding data buffer.
|
|
* \param args Arguments to encode in the buffer.
|
|
*
|
|
* \retval Start of the next ASN.1 component to encode on success.
|
|
* \retval NULL on error.
|
|
*/
|
|
unsigned char *rose_enc_qsig_CcSuspend_ARG(struct pri *ctrl, unsigned char *pos,
|
|
unsigned char *end, const union rose_msg_invoke_args *args)
|
|
{
|
|
return rose_enc_qsig_CcExtension(ctrl, pos, end);
|
|
}
|
|
|
|
/*!
|
|
* \brief Encode the Q.SIG CcResume invoke facility ie arguments.
|
|
*
|
|
* \param ctrl D channel controller for diagnostic messages or global options.
|
|
* \param pos Starting position to encode ASN.1 component.
|
|
* \param end End of ASN.1 encoding data buffer.
|
|
* \param args Arguments to encode in the buffer.
|
|
*
|
|
* \retval Start of the next ASN.1 component to encode on success.
|
|
* \retval NULL on error.
|
|
*/
|
|
unsigned char *rose_enc_qsig_CcResume_ARG(struct pri *ctrl, unsigned char *pos,
|
|
unsigned char *end, const union rose_msg_invoke_args *args)
|
|
{
|
|
return rose_enc_qsig_CcExtension(ctrl, pos, end);
|
|
}
|
|
|
|
/*!
|
|
* \internal
|
|
* \brief Decode the CcExtension argument parameters.
|
|
*
|
|
* \param ctrl D channel controller for any diagnostic messages.
|
|
* \param name Field name
|
|
* \param tag Component tag that identified this production.
|
|
* \param pos Starting position of the ASN.1 component length.
|
|
* \param end End of ASN.1 decoding data buffer.
|
|
*
|
|
* \retval Start of the next ASN.1 component on success.
|
|
* \retval NULL on error.
|
|
*
|
|
* \details
|
|
* CcExtension ::= CHOICE {
|
|
* none NULL,
|
|
* single [14] IMPLICIT Extension,
|
|
* multiple [15] IMPLICIT SEQUENCE OF Extension
|
|
* }
|
|
*/
|
|
static const unsigned char *rose_dec_qsig_CcExtension(struct pri *ctrl, const char *name,
|
|
unsigned tag, const unsigned char *pos, const unsigned char *end)
|
|
{
|
|
int length;
|
|
int ext_offset;
|
|
const unsigned char *ext_end;
|
|
|
|
if (ctrl->debug & PRI_DEBUG_APDU) {
|
|
pri_message(ctrl, " %s CcExtension\n", name);
|
|
}
|
|
switch (tag & ~ASN1_PC_MASK) {
|
|
case ASN1_TYPE_NULL:
|
|
/* Must not be constructed but we will not check for it for simplicity. */
|
|
return asn1_dec_null(ctrl, "none", tag, pos, end);
|
|
case ASN1_CLASS_CONTEXT_SPECIFIC | 14:
|
|
name = "single";
|
|
break;
|
|
case ASN1_CLASS_CONTEXT_SPECIFIC | 15:
|
|
name = "multiple";
|
|
break;
|
|
default:
|
|
ASN1_DID_NOT_EXPECT_TAG(ctrl, tag);
|
|
return NULL;
|
|
}
|
|
|
|
if (ctrl->debug & PRI_DEBUG_APDU) {
|
|
pri_message(ctrl, " %s %s\n", name, asn1_tag2str(tag));
|
|
}
|
|
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
|
|
ASN1_END_SETUP(ext_end, ext_offset, length, pos, end);
|
|
|
|
/* Fixup will skip over the manufacturer extension information */
|
|
ASN1_END_FIXUP(ctrl, pos, ext_offset, ext_end, end);
|
|
|
|
return pos;
|
|
}
|
|
|
|
/*!
|
|
* \internal
|
|
* \brief Decode the CcRequestArg argument parameters.
|
|
*
|
|
* \param ctrl D channel controller for any diagnostic messages.
|
|
* \param name Field name
|
|
* \param tag Component tag that identified this production.
|
|
* \param pos Starting position of the ASN.1 component length.
|
|
* \param end End of ASN.1 decoding data buffer.
|
|
* \param cc_request_arg Parameter storage to fill.
|
|
*
|
|
* \retval Start of the next ASN.1 component on success.
|
|
* \retval NULL on error.
|
|
*/
|
|
static const unsigned char *rose_dec_qsig_CcRequestArg(struct pri *ctrl,
|
|
const char *name, unsigned tag, const unsigned char *pos, const unsigned char *end,
|
|
struct roseQsigCcRequestArg *cc_request_arg)
|
|
{
|
|
int32_t value;
|
|
int length;
|
|
int seq_offset;
|
|
int explicit_offset;
|
|
const unsigned char *explicit_end;
|
|
const unsigned char *seq_end;
|
|
const unsigned char *save_pos;
|
|
|
|
if (ctrl->debug & PRI_DEBUG_APDU) {
|
|
pri_message(ctrl, " %s CcRequestArg %s\n", name, asn1_tag2str(tag));
|
|
}
|
|
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
|
|
ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
|
|
|
|
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
|
ASN1_CALL(pos, rose_dec_PresentedNumberUnscreened(ctrl, "numberA", tag, pos, seq_end,
|
|
&cc_request_arg->number_a));
|
|
|
|
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
|
ASN1_CALL(pos, rose_dec_PartyNumber(ctrl, "numberB", tag, pos, seq_end,
|
|
&cc_request_arg->number_b));
|
|
|
|
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
|
ASN1_CHECK_TAG(ctrl, tag, tag & ~ASN1_PC_MASK, ASN1_CLASS_APPLICATION | 0);
|
|
ASN1_CALL(pos, rose_dec_Q931ie(ctrl, "service", tag, pos, seq_end,
|
|
&cc_request_arg->q931ie, sizeof(cc_request_arg->q931ie_contents)));
|
|
|
|
/*
|
|
* A sequence specifies an ordered list of component types.
|
|
* However, for simplicity we are not checking the order of
|
|
* the remaining optional components.
|
|
*/
|
|
cc_request_arg->subaddr_a.length = 0;
|
|
cc_request_arg->subaddr_b.length = 0;
|
|
cc_request_arg->can_retain_service = 0; /* DEFAULT FALSE */
|
|
cc_request_arg->retain_sig_connection_present = 0;
|
|
while (pos < seq_end && *pos != ASN1_INDEF_TERM) {
|
|
save_pos = pos;
|
|
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
|
switch (tag) {
|
|
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 10:
|
|
/* Remove EXPLICIT tag */
|
|
if (ctrl->debug & PRI_DEBUG_APDU) {
|
|
pri_message(ctrl, " Explicit %s\n", asn1_tag2str(tag));
|
|
}
|
|
ASN1_CALL(pos, asn1_dec_length(pos, seq_end, &length));
|
|
ASN1_END_SETUP(explicit_end, explicit_offset, length, pos, seq_end);
|
|
|
|
ASN1_CALL(pos, asn1_dec_tag(pos, explicit_end, &tag));
|
|
ASN1_CALL(pos, rose_dec_PartySubaddress(ctrl, "subaddrA", tag, pos,
|
|
explicit_end, &cc_request_arg->subaddr_a));
|
|
|
|
ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
|
|
break;
|
|
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 11:
|
|
/* Remove EXPLICIT tag */
|
|
if (ctrl->debug & PRI_DEBUG_APDU) {
|
|
pri_message(ctrl, " Explicit %s\n", asn1_tag2str(tag));
|
|
}
|
|
ASN1_CALL(pos, asn1_dec_length(pos, seq_end, &length));
|
|
ASN1_END_SETUP(explicit_end, explicit_offset, length, pos, seq_end);
|
|
|
|
ASN1_CALL(pos, asn1_dec_tag(pos, explicit_end, &tag));
|
|
ASN1_CALL(pos, rose_dec_PartySubaddress(ctrl, "subaddrB", tag, pos,
|
|
explicit_end, &cc_request_arg->subaddr_b));
|
|
|
|
ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
|
|
break;
|
|
case ASN1_CLASS_CONTEXT_SPECIFIC | 12:
|
|
ASN1_CALL(pos, asn1_dec_boolean(ctrl, "can-retain-service", tag, pos,
|
|
seq_end, &value));
|
|
cc_request_arg->can_retain_service = value;
|
|
break;
|
|
case ASN1_CLASS_CONTEXT_SPECIFIC | 13:
|
|
ASN1_CALL(pos, asn1_dec_boolean(ctrl, "retain-sig-connection", tag, pos,
|
|
seq_end, &value));
|
|
cc_request_arg->retain_sig_connection = value;
|
|
cc_request_arg->retain_sig_connection_present = 1;
|
|
break;
|
|
case ASN1_TYPE_NULL:
|
|
case ASN1_CLASS_CONTEXT_SPECIFIC | 14:
|
|
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 14:
|
|
case ASN1_CLASS_CONTEXT_SPECIFIC | 15:
|
|
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 15:
|
|
ASN1_CALL(pos, rose_dec_qsig_CcExtension(ctrl, "extension", tag, pos,
|
|
seq_end));
|
|
break;
|
|
default:
|
|
pos = save_pos;
|
|
goto cancel_options;
|
|
}
|
|
}
|
|
cancel_options:;
|
|
|
|
ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
|
|
|
|
return pos;
|
|
}
|
|
|
|
/*!
|
|
* \brief Decode the Q.SIG CcbsRequest invoke argument parameters.
|
|
*
|
|
* \param ctrl D channel controller for diagnostic messages or global options.
|
|
* \param tag Component tag that identified this structure.
|
|
* \param pos Starting position of the ASN.1 component length.
|
|
* \param end End of ASN.1 decoding data buffer.
|
|
* \param args Arguments to fill in from the decoded buffer.
|
|
*
|
|
* \retval Start of the next ASN.1 component on success.
|
|
* \retval NULL on error.
|
|
*/
|
|
const unsigned char *rose_dec_qsig_CcbsRequest_ARG(struct pri *ctrl, unsigned tag,
|
|
const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
|
|
{
|
|
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
|
|
return rose_dec_qsig_CcRequestArg(ctrl, "CcbsRequest", tag, pos, end,
|
|
&args->qsig.CcbsRequest);
|
|
}
|
|
|
|
/*!
|
|
* \brief Decode the Q.SIG CcnrRequest invoke argument parameters.
|
|
*
|
|
* \param ctrl D channel controller for diagnostic messages or global options.
|
|
* \param tag Component tag that identified this structure.
|
|
* \param pos Starting position of the ASN.1 component length.
|
|
* \param end End of ASN.1 decoding data buffer.
|
|
* \param args Arguments to fill in from the decoded buffer.
|
|
*
|
|
* \retval Start of the next ASN.1 component on success.
|
|
* \retval NULL on error.
|
|
*/
|
|
const unsigned char *rose_dec_qsig_CcnrRequest_ARG(struct pri *ctrl, unsigned tag,
|
|
const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
|
|
{
|
|
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
|
|
return rose_dec_qsig_CcRequestArg(ctrl, "CcnrRequest", tag, pos, end,
|
|
&args->qsig.CcnrRequest);
|
|
}
|
|
|
|
/*!
|
|
* \internal
|
|
* \brief Decode the CcRequestRes argument parameters.
|
|
*
|
|
* \param ctrl D channel controller for any diagnostic messages.
|
|
* \param name Field name
|
|
* \param tag Component tag that identified this production.
|
|
* \param pos Starting position of the ASN.1 component length.
|
|
* \param end End of ASN.1 decoding data buffer.
|
|
* \param cc_request_res Parameter storage to fill.
|
|
*
|
|
* \retval Start of the next ASN.1 component on success.
|
|
* \retval NULL on error.
|
|
*/
|
|
static const unsigned char *rose_dec_qsig_CcRequestRes(struct pri *ctrl,
|
|
const char *name, unsigned tag, const unsigned char *pos, const unsigned char *end,
|
|
struct roseQsigCcRequestRes *cc_request_res)
|
|
{
|
|
int32_t value;
|
|
int length;
|
|
int seq_offset;
|
|
const unsigned char *seq_end;
|
|
const unsigned char *save_pos;
|
|
|
|
if (ctrl->debug & PRI_DEBUG_APDU) {
|
|
pri_message(ctrl, " %s CcRequestRes %s\n", name, asn1_tag2str(tag));
|
|
}
|
|
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
|
|
ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
|
|
|
|
/*
|
|
* A sequence specifies an ordered list of component types.
|
|
* However, for simplicity we are not checking the order of
|
|
* the remaining optional components.
|
|
*/
|
|
cc_request_res->no_path_reservation = 0; /* DEFAULT FALSE */
|
|
cc_request_res->retain_service = 0; /* DEFAULT FALSE */
|
|
while (pos < seq_end && *pos != ASN1_INDEF_TERM) {
|
|
save_pos = pos;
|
|
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
|
switch (tag) {
|
|
case ASN1_CLASS_CONTEXT_SPECIFIC | 0:
|
|
ASN1_CALL(pos, asn1_dec_boolean(ctrl, "no-path-reservation", tag, pos,
|
|
seq_end, &value));
|
|
cc_request_res->no_path_reservation = value;
|
|
break;
|
|
case ASN1_CLASS_CONTEXT_SPECIFIC | 1:
|
|
ASN1_CALL(pos, asn1_dec_boolean(ctrl, "retain-service", tag, pos, seq_end,
|
|
&value));
|
|
cc_request_res->retain_service = value;
|
|
break;
|
|
case ASN1_TYPE_NULL:
|
|
case ASN1_CLASS_CONTEXT_SPECIFIC | 14:
|
|
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 14:
|
|
case ASN1_CLASS_CONTEXT_SPECIFIC | 15:
|
|
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 15:
|
|
ASN1_CALL(pos, rose_dec_qsig_CcExtension(ctrl, "extension", tag, pos,
|
|
seq_end));
|
|
break;
|
|
default:
|
|
pos = save_pos;
|
|
goto cancel_options;
|
|
}
|
|
}
|
|
cancel_options:;
|
|
|
|
ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
|
|
|
|
return pos;
|
|
}
|
|
|
|
/*!
|
|
* \brief Decode the Q.SIG CcbsRequest result argument parameters.
|
|
*
|
|
* \param ctrl D channel controller for diagnostic messages or global options.
|
|
* \param tag Component tag that identified this structure.
|
|
* \param pos Starting position of the ASN.1 component length.
|
|
* \param end End of ASN.1 decoding data buffer.
|
|
* \param args Arguments to fill in from the decoded buffer.
|
|
*
|
|
* \retval Start of the next ASN.1 component on success.
|
|
* \retval NULL on error.
|
|
*/
|
|
const unsigned char *rose_dec_qsig_CcbsRequest_RES(struct pri *ctrl, unsigned tag,
|
|
const unsigned char *pos, const unsigned char *end, union rose_msg_result_args *args)
|
|
{
|
|
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
|
|
return rose_dec_qsig_CcRequestRes(ctrl, "CcbsRequest", tag, pos, end,
|
|
&args->qsig.CcbsRequest);
|
|
}
|
|
|
|
/*!
|
|
* \brief Decode the Q.SIG CcnrRequest result argument parameters.
|
|
*
|
|
* \param ctrl D channel controller for diagnostic messages or global options.
|
|
* \param tag Component tag that identified this structure.
|
|
* \param pos Starting position of the ASN.1 component length.
|
|
* \param end End of ASN.1 decoding data buffer.
|
|
* \param args Arguments to fill in from the decoded buffer.
|
|
*
|
|
* \retval Start of the next ASN.1 component on success.
|
|
* \retval NULL on error.
|
|
*/
|
|
const unsigned char *rose_dec_qsig_CcnrRequest_RES(struct pri *ctrl, unsigned tag,
|
|
const unsigned char *pos, const unsigned char *end, union rose_msg_result_args *args)
|
|
{
|
|
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
|
|
return rose_dec_qsig_CcRequestRes(ctrl, "CcnrRequest", tag, pos, end,
|
|
&args->qsig.CcnrRequest);
|
|
}
|
|
|
|
/*!
|
|
* \internal
|
|
* \brief Decode the CcOptionalArg argument parameters.
|
|
*
|
|
* \param ctrl D channel controller for any diagnostic messages.
|
|
* \param name Field name
|
|
* \param tag Component tag that identified this production.
|
|
* \param pos Starting position of the ASN.1 component length.
|
|
* \param end End of ASN.1 decoding data buffer.
|
|
* \param cc_optional_arg Parameter storage to fill.
|
|
*
|
|
* \retval Start of the next ASN.1 component on success.
|
|
* \retval NULL on error.
|
|
*/
|
|
static const unsigned char *rose_dec_qsig_CcOptionalArg(struct pri *ctrl,
|
|
const char *name, unsigned tag, const unsigned char *pos, const unsigned char *end,
|
|
struct roseQsigCcOptionalArg *cc_optional_arg)
|
|
{
|
|
int length;
|
|
int seq_offset;
|
|
int explicit_offset;
|
|
const unsigned char *explicit_end;
|
|
const unsigned char *seq_end;
|
|
const unsigned char *save_pos;
|
|
|
|
if (ctrl->debug & PRI_DEBUG_APDU) {
|
|
pri_message(ctrl, " %s CcOptionalArg\n", name);
|
|
}
|
|
if (tag != (ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 0)) {
|
|
cc_optional_arg->full_arg_present = 0;
|
|
return rose_dec_qsig_CcExtension(ctrl, "extArg", tag, pos, end);
|
|
}
|
|
cc_optional_arg->full_arg_present = 1;
|
|
|
|
if (ctrl->debug & PRI_DEBUG_APDU) {
|
|
pri_message(ctrl, " fullArg %s\n", asn1_tag2str(tag));
|
|
}
|
|
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
|
|
ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
|
|
|
|
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
|
ASN1_CALL(pos, rose_dec_PartyNumber(ctrl, "numberA", tag, pos, seq_end,
|
|
&cc_optional_arg->number_a));
|
|
|
|
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
|
ASN1_CALL(pos, rose_dec_PartyNumber(ctrl, "numberB", tag, pos, seq_end,
|
|
&cc_optional_arg->number_b));
|
|
|
|
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
|
ASN1_CHECK_TAG(ctrl, tag, tag & ~ASN1_PC_MASK, ASN1_CLASS_APPLICATION | 0);
|
|
ASN1_CALL(pos, rose_dec_Q931ie(ctrl, "service", tag, pos, seq_end,
|
|
&cc_optional_arg->q931ie, sizeof(cc_optional_arg->q931ie_contents)));
|
|
|
|
/*
|
|
* A sequence specifies an ordered list of component types.
|
|
* However, for simplicity we are not checking the order of
|
|
* the remaining optional components.
|
|
*/
|
|
cc_optional_arg->subaddr_a.length = 0;
|
|
cc_optional_arg->subaddr_b.length = 0;
|
|
while (pos < seq_end && *pos != ASN1_INDEF_TERM) {
|
|
save_pos = pos;
|
|
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
|
switch (tag) {
|
|
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 10:
|
|
/* Remove EXPLICIT tag */
|
|
if (ctrl->debug & PRI_DEBUG_APDU) {
|
|
pri_message(ctrl, " Explicit %s\n", asn1_tag2str(tag));
|
|
}
|
|
ASN1_CALL(pos, asn1_dec_length(pos, seq_end, &length));
|
|
ASN1_END_SETUP(explicit_end, explicit_offset, length, pos, seq_end);
|
|
|
|
ASN1_CALL(pos, asn1_dec_tag(pos, explicit_end, &tag));
|
|
ASN1_CALL(pos, rose_dec_PartySubaddress(ctrl, "subaddrA", tag, pos,
|
|
explicit_end, &cc_optional_arg->subaddr_a));
|
|
|
|
ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
|
|
break;
|
|
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 11:
|
|
/* Remove EXPLICIT tag */
|
|
if (ctrl->debug & PRI_DEBUG_APDU) {
|
|
pri_message(ctrl, " Explicit %s\n", asn1_tag2str(tag));
|
|
}
|
|
ASN1_CALL(pos, asn1_dec_length(pos, seq_end, &length));
|
|
ASN1_END_SETUP(explicit_end, explicit_offset, length, pos, seq_end);
|
|
|
|
ASN1_CALL(pos, asn1_dec_tag(pos, explicit_end, &tag));
|
|
ASN1_CALL(pos, rose_dec_PartySubaddress(ctrl, "subaddrB", tag, pos,
|
|
explicit_end, &cc_optional_arg->subaddr_b));
|
|
|
|
ASN1_END_FIXUP(ctrl, pos, explicit_offset, explicit_end, seq_end);
|
|
break;
|
|
case ASN1_TYPE_NULL:
|
|
case ASN1_CLASS_CONTEXT_SPECIFIC | 14:
|
|
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 14:
|
|
case ASN1_CLASS_CONTEXT_SPECIFIC | 15:
|
|
case ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_PC_CONSTRUCTED | 15:
|
|
ASN1_CALL(pos, rose_dec_qsig_CcExtension(ctrl, "extension", tag, pos,
|
|
seq_end));
|
|
break;
|
|
default:
|
|
pos = save_pos;
|
|
goto cancel_options;
|
|
}
|
|
}
|
|
cancel_options:;
|
|
|
|
ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
|
|
|
|
return pos;
|
|
}
|
|
|
|
/*!
|
|
* \brief Decode the Q.SIG CcCancel invoke argument parameters.
|
|
*
|
|
* \param ctrl D channel controller for diagnostic messages or global options.
|
|
* \param tag Component tag that identified this structure.
|
|
* \param pos Starting position of the ASN.1 component length.
|
|
* \param end End of ASN.1 decoding data buffer.
|
|
* \param args Arguments to fill in from the decoded buffer.
|
|
*
|
|
* \retval Start of the next ASN.1 component on success.
|
|
* \retval NULL on error.
|
|
*/
|
|
const unsigned char *rose_dec_qsig_CcCancel_ARG(struct pri *ctrl, unsigned tag,
|
|
const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
|
|
{
|
|
return rose_dec_qsig_CcOptionalArg(ctrl, "CcCancel", tag, pos, end,
|
|
&args->qsig.CcCancel);
|
|
}
|
|
|
|
/*!
|
|
* \brief Decode the Q.SIG CcExecPossible invoke argument parameters.
|
|
*
|
|
* \param ctrl D channel controller for diagnostic messages or global options.
|
|
* \param tag Component tag that identified this structure.
|
|
* \param pos Starting position of the ASN.1 component length.
|
|
* \param end End of ASN.1 decoding data buffer.
|
|
* \param args Arguments to fill in from the decoded buffer.
|
|
*
|
|
* \retval Start of the next ASN.1 component on success.
|
|
* \retval NULL on error.
|
|
*/
|
|
const unsigned char *rose_dec_qsig_CcExecPossible_ARG(struct pri *ctrl, unsigned tag,
|
|
const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
|
|
{
|
|
return rose_dec_qsig_CcOptionalArg(ctrl, "CcExecPossible", tag, pos, end,
|
|
&args->qsig.CcCancel);
|
|
}
|
|
|
|
/*!
|
|
* \brief Decode the Q.SIG CcPathReserve invoke argument parameters.
|
|
*
|
|
* \param ctrl D channel controller for diagnostic messages or global options.
|
|
* \param tag Component tag that identified this structure.
|
|
* \param pos Starting position of the ASN.1 component length.
|
|
* \param end End of ASN.1 decoding data buffer.
|
|
* \param args Arguments to fill in from the decoded buffer.
|
|
*
|
|
* \retval Start of the next ASN.1 component on success.
|
|
* \retval NULL on error.
|
|
*/
|
|
const unsigned char *rose_dec_qsig_CcPathReserve_ARG(struct pri *ctrl, unsigned tag,
|
|
const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
|
|
{
|
|
return rose_dec_qsig_CcExtension(ctrl, "CcPathReserve", tag, pos, end);
|
|
}
|
|
|
|
/*!
|
|
* \brief Decode the Q.SIG CcPathReserve result argument parameters.
|
|
*
|
|
* \param ctrl D channel controller for diagnostic messages or global options.
|
|
* \param tag Component tag that identified this structure.
|
|
* \param pos Starting position of the ASN.1 component length.
|
|
* \param end End of ASN.1 decoding data buffer.
|
|
* \param args Arguments to fill in from the decoded buffer.
|
|
*
|
|
* \retval Start of the next ASN.1 component on success.
|
|
* \retval NULL on error.
|
|
*/
|
|
const unsigned char *rose_dec_qsig_CcPathReserve_RES(struct pri *ctrl, unsigned tag,
|
|
const unsigned char *pos, const unsigned char *end, union rose_msg_result_args *args)
|
|
{
|
|
return rose_dec_qsig_CcExtension(ctrl, "CcPathReserve", tag, pos, end);
|
|
}
|
|
|
|
/*!
|
|
* \brief Decode the Q.SIG CcRingout invoke argument parameters.
|
|
*
|
|
* \param ctrl D channel controller for diagnostic messages or global options.
|
|
* \param tag Component tag that identified this structure.
|
|
* \param pos Starting position of the ASN.1 component length.
|
|
* \param end End of ASN.1 decoding data buffer.
|
|
* \param args Arguments to fill in from the decoded buffer.
|
|
*
|
|
* \retval Start of the next ASN.1 component on success.
|
|
* \retval NULL on error.
|
|
*/
|
|
const unsigned char *rose_dec_qsig_CcRingout_ARG(struct pri *ctrl, unsigned tag,
|
|
const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
|
|
{
|
|
return rose_dec_qsig_CcExtension(ctrl, "CcRingout", tag, pos, end);
|
|
}
|
|
|
|
/*!
|
|
* \brief Decode the Q.SIG CcSuspend invoke argument parameters.
|
|
*
|
|
* \param ctrl D channel controller for diagnostic messages or global options.
|
|
* \param tag Component tag that identified this structure.
|
|
* \param pos Starting position of the ASN.1 component length.
|
|
* \param end End of ASN.1 decoding data buffer.
|
|
* \param args Arguments to fill in from the decoded buffer.
|
|
*
|
|
* \retval Start of the next ASN.1 component on success.
|
|
* \retval NULL on error.
|
|
*/
|
|
const unsigned char *rose_dec_qsig_CcSuspend_ARG(struct pri *ctrl, unsigned tag,
|
|
const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
|
|
{
|
|
return rose_dec_qsig_CcExtension(ctrl, "CcSuspend", tag, pos, end);
|
|
}
|
|
|
|
/*!
|
|
* \brief Decode the Q.SIG CcResume invoke argument parameters.
|
|
*
|
|
* \param ctrl D channel controller for diagnostic messages or global options.
|
|
* \param tag Component tag that identified this structure.
|
|
* \param pos Starting position of the ASN.1 component length.
|
|
* \param end End of ASN.1 decoding data buffer.
|
|
* \param args Arguments to fill in from the decoded buffer.
|
|
*
|
|
* \retval Start of the next ASN.1 component on success.
|
|
* \retval NULL on error.
|
|
*/
|
|
const unsigned char *rose_dec_qsig_CcResume_ARG(struct pri *ctrl, unsigned tag,
|
|
const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
|
|
{
|
|
return rose_dec_qsig_CcExtension(ctrl, "CcResume", tag, pos, end);
|
|
}
|
|
|
|
/* ------------------------------------------------------------------- */
|
|
/* end rose_qsig_cc.c */
|