osmo-cc-misdn-endpoint/src/libmisdnuser/suppserv/diversion.c

1570 lines
48 KiB
C

/*
*
* Diversion Supplementary Services ETS 300 207-1 Table 3
*
* Diversion Facility ie encode/decode
*
* Copyright 2009,2010 by Karsten Keil <kkeil@linux-pingi.de>
*
* This code is free software; you can redistribute it and/or modify
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE
* version 2.1 as published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU LESSER GENERAL PUBLIC LICENSE for more details.
*
*/
#include "asn1.h"
#include "diversion.h"
#include <string.h>
/* ------------------------------------------------------------------- */
/* ******************************************************************* */
/*!
* \internal
* \brief Encode the Q.931 ie UserUser value used for Diversion.
*
* \param Dest Where to put the encoding
* \param Q931ie Q931 ie information to encode.
*
* \retval length
*/
static int encodeQ931_Div_UserInfo(__u8 * Dest, const struct Q931_UserUserInformation *Q931ie)
{
int Length;
__u8 *p;
/* [APPLICATION 0] IMPLICIT OCTET STRING */
Dest[0] = ASN1_TAG_APPLICATION_WIDE | 0;
/* Pre-calculate content length */
if (Q931ie->Length) {
Length = 2 + Q931ie->Length;
} else {
Length = 0;
}
/* Store length */
if (Length < 0x80) {
Dest[1] = Length;
p = &Dest[2];
} else {
encodeLen_Long_u8(&Dest[1], Length);
p = &Dest[1 + ASN1_NUM_OCTETS_LONG_LENGTH_u8];
}
/* Store value */
if (Q931ie->Length) {
*p++ = 0x7E; /* Q.931 User-User-Information ie tag */
*p++ = Q931ie->Length;
memcpy(p, Q931ie->Contents, Q931ie->Length);
p += Q931ie->Length;
}
return p - Dest;
} /* end encodeQ931_Div_UserInfo() */
/* ******************************************************************* */
/*!
* \internal
* \brief Parse the Q.931 argument contents for Diversion.
*
* \param pc Complete component message storage data.
* \param p Starting buffer position to parse arguments
* \param end End buffer position that must not go past.
* \param Q931ie Parameter storage to fill.
*
* \retval length of buffer consumed
* \retval -1 on error.
*/
static int ParseQ931_Div_UserInfo(struct asn1_parm *pc, u_char * p, u_char * end, struct Q931_UserUserInformation *Q931ie)
{
__u8 Ie_type;
size_t Length;
INIT;
memset(Q931ie, 0, sizeof(*Q931ie));
do {
if (end < p + 2) {
/* Q.931 ie length error */
return -1;
}
Ie_type = *p++;
Length = *p++;
if (end < p + Length) {
/* Q.931 ie length error */
return -1;
}
switch (Ie_type) {
case 0x7E: /* Q.931 User-User-Information ie tag */
if (Length <= sizeof(Q931ie->Contents)) {
Q931ie->Length = Length;
memcpy(Q931ie->Contents, p, Length);
}
break;
default:
/* Unknown Q.931 ie in Diversion message */
break;
} /* end switch */
p += Length;
} while (p < end);
return p - beg;
} /* end ParseQ931_Div_UserInfo() */
/* ******************************************************************* */
/*!
* \internal
* \brief Encode the Q.931 ie value used for Diversion.
*
* \param Dest Where to put the encoding
* \param Q931ie Q931 ie information to encode.
*
* \retval length
*/
static int encodeQ931_Div(__u8 * Dest, const struct Q931_Bc_Hlc_Llc_Uu *Q931ie)
{
int Length;
__u8 *p;
/* [APPLICATION 0] IMPLICIT OCTET STRING */
Dest[0] = ASN1_TAG_APPLICATION_WIDE | 0;
/* Pre-calculate content length */
Length = 0;
if (Q931ie->Bc.Length) {
Length += 2 + Q931ie->Bc.Length;
}
if (Q931ie->Hlc.Length) {
Length += 2 + Q931ie->Hlc.Length;
}
if (Q931ie->Llc.Length) {
Length += 2 + Q931ie->Llc.Length;
}
if (Q931ie->UserInfo.Length) {
Length += 2 + Q931ie->UserInfo.Length;
}
/* Store length */
if (Length < 0x80) {
Dest[1] = Length;
p = &Dest[2];
} else {
encodeLen_Long_u8(&Dest[1], Length);
p = &Dest[1 + ASN1_NUM_OCTETS_LONG_LENGTH_u8];
}
/* Store value */
if (Q931ie->Bc.Length) {
*p++ = 0x04; /* Q.931 Bearer Capability ie tag */
*p++ = Q931ie->Bc.Length;
memcpy(p, Q931ie->Bc.Contents, Q931ie->Bc.Length);
p += Q931ie->Bc.Length;
}
if (Q931ie->Llc.Length) {
*p++ = 0x7C; /* Q.931 Low Layer Compatibility ie tag */
*p++ = Q931ie->Llc.Length;
memcpy(p, Q931ie->Llc.Contents, Q931ie->Llc.Length);
p += Q931ie->Llc.Length;
}
if (Q931ie->Hlc.Length) {
*p++ = 0x7D; /* Q.931 High Layer Compatibility ie tag */
*p++ = Q931ie->Hlc.Length;
memcpy(p, Q931ie->Hlc.Contents, Q931ie->Hlc.Length);
p += Q931ie->Hlc.Length;
}
if (Q931ie->UserInfo.Length) {
*p++ = 0x7E; /* Q.931 User-User-Information ie tag */
*p++ = Q931ie->UserInfo.Length;
memcpy(p, Q931ie->UserInfo.Contents, Q931ie->UserInfo.Length);
p += Q931ie->UserInfo.Length;
}
return p - Dest;
} /* end encodeQ931_Div() */
/* ******************************************************************* */
/*!
* \internal
* \brief Parse the Q.931 argument contents for Diversion.
*
* \param pc Complete component message storage data.
* \param p Starting buffer position to parse arguments
* \param end End buffer position that must not go past.
* \param Q931ie Parameter storage to fill.
*
* \retval length of buffer consumed
* \retval -1 on error.
*/
static int ParseQ931_Div(struct asn1_parm *pc, u_char * p, u_char * end, struct Q931_Bc_Hlc_Llc_Uu *Q931ie)
{
__u8 Ie_type;
size_t Length;
INIT;
memset(Q931ie, 0, sizeof(*Q931ie));
do {
if (end < p + 2) {
/* Q.931 ie length error */
return -1;
}
Ie_type = *p++;
Length = *p++;
if (end < p + Length) {
/* Q.931 ie length error */
return -1;
}
switch (Ie_type) {
case 0x04: /* Q.931 Bearer Capability ie tag */
if (Length <= sizeof(Q931ie->Bc.Contents)) {
Q931ie->Bc.Length = Length;
memcpy(Q931ie->Bc.Contents, p, Length);
}
break;
case 0x7C: /* Q.931 Low Layer Compatibility ie tag */
if (Length <= sizeof(Q931ie->Llc.Contents)) {
Q931ie->Llc.Length = Length;
memcpy(Q931ie->Llc.Contents, p, Length);
}
break;
case 0x7D: /* Q.931 High Layer Compatibility ie tag */
if (Length <= sizeof(Q931ie->Hlc.Contents)) {
Q931ie->Hlc.Length = Length;
memcpy(Q931ie->Hlc.Contents, p, Length);
}
break;
case 0x7E: /* Q.931 User-User-Information ie tag */
if (Length <= sizeof(Q931ie->UserInfo.Contents)) {
Q931ie->UserInfo.Length = Length;
memcpy(Q931ie->UserInfo.Contents, p, Length);
}
break;
default:
/* Unknown Q.931 ie in Diversion message */
break;
} /* end switch */
p += Length;
} while (p < end);
return p - beg;
} /* end ParseQ931_Div() */
/* ******************************************************************* */
/*!
* \internal
* \brief Encode the ServedUserNr type.
*
* \param Dest Where to put the encoding
* \param ServedUser Served user number information to encode.
*
* \retval length
*/
static int encodeServedUserNumber_Full(__u8 * Dest, const struct FacPartyNumber *ServedUser)
{
int Length;
if (ServedUser->LengthOfNumber) {
/* Forward this number */
Length = encodePartyNumber_Full(Dest, ServedUser);
} else {
/* Forward all numbers */
Length = encodeNull(Dest, ASN1_TAG_NULL);
}
return Length;
} /* end encodeServedUserNumber_Full() */
/* ******************************************************************* */
/*!
* \brief Parse the ServedUserNr argument parameters.
*
* \param pc Complete component message storage data.
* \param p Starting buffer position to parse arguments
* \param end End buffer position that must not go past.
* \param ServedUser Parameter storage to fill.
*
* \retval length of buffer consumed
* \retval -1 on error.
*/
static int ParseServedUserNumber_Full(struct asn1_parm *pc, u_char * p, u_char * end, struct FacPartyNumber *ServedUser)
{
INIT;
ServedUser->LengthOfNumber = 0;
XCHOICE(ParseNull, ASN1_TAG_NULL, ASN1_NOT_TAGGED);
/* Must be a PartyNumber (Which is itself a CHOICE) */
return ParsePartyNumber_Full(pc, beg, end, ServedUser);
} /* end ParseServedUserNumber_Full() */
/* ******************************************************************* */
/*!
* \internal
* \brief Encode the IntResult type.
*
* \param Dest Where to put the encoding
* \param IntResult Forwarding record information to encode.
*
* \retval length
*/
static int encodeIntResult(__u8 * Dest, const struct FacForwardingRecord *IntResult)
{
__u8 *p;
Dest[0] = ASN1_TAG_SEQUENCE;
p = &Dest[2];
p += encodeServedUserNumber_Full(p, &IntResult->ServedUser);
p += encodeEnum(p, ASN1_TAG_ENUM, IntResult->BasicService);
p += encodeEnum(p, ASN1_TAG_ENUM, IntResult->Procedure);
p += encodeAddress_Full(p, &IntResult->ForwardedTo);
/* length */
Dest[1] = p - &Dest[2];
return p - Dest;
} /* end encodeIntResult() */
/* ******************************************************************* */
/*!
* \internal
* \brief Parse the IntResult argument parameters.
*
* \param pc Complete component message storage data.
* \param p Starting buffer position to parse arguments
* \param end End buffer position that must not go past.
* \param IntResult Forwarding record storage to fill.
*
* \retval length of buffer consumed
* \retval -1 on error.
*/
static int ParseIntResult(struct asn1_parm *pc, u_char * p, u_char * end, struct FacForwardingRecord *IntResult)
{
unsigned int Value;
INIT;
XSEQUENCE_1(ParseServedUserNumber_Full, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &IntResult->ServedUser);
XSEQUENCE_1(ParseEnum, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, &Value);
IntResult->BasicService = Value;
XSEQUENCE_1(ParseEnum, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, &Value);
IntResult->Procedure = Value;
XSEQUENCE_1(ParseAddress_Full, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &IntResult->ForwardedTo);
return p - beg;
} /* end ParseIntResult() */
/* ******************************************************************* */
/*!
* \internal
* \brief Encode the IntResultList type.
*
* \param Dest Where to put the encoding
* \param IntResultList Forwarding record list information to encode.
*
* \retval length
*/
static int encodeIntResultList(__u8 * Dest, const struct FacForwardingList *IntResultList)
{
unsigned Index;
__u8 *p;
Dest[0] = ASN1_TAG_SET;
p = &Dest[1 + ASN1_NUM_OCTETS_LONG_LENGTH_u8];
for (Index = 0; Index < IntResultList->NumRecords; ++Index) {
p += encodeIntResult(p, &IntResultList->List[Index]);
} /* end for */
/* length */
encodeLen_Long_u8(&Dest[1], p - &Dest[1 + ASN1_NUM_OCTETS_LONG_LENGTH_u8]);
return p - Dest;
} /* end encodeIntResultList() */
/* ******************************************************************* */
/*!
* \brief Parse the IntResultList argument parameters.
*
* \param pc Complete component message storage data.
* \param p Starting buffer position to parse arguments
* \param end End buffer position that must not go past.
* \param IntResultList Forwarding record list storage to fill.
*
* \retval length of buffer consumed
* \retval -1 on error.
*/
int ParseIntResultList(struct asn1_parm *pc, u_char * p, u_char * end, struct FacForwardingList *IntResultList)
{
INIT;
IntResultList->NumRecords = 0;
while (p < end) {
if (IntResultList->NumRecords < sizeof(IntResultList->List) / sizeof(IntResultList->List[0])) {
XSEQUENCE_1(ParseIntResult, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED,
&IntResultList->List[IntResultList->NumRecords]);
++IntResultList->NumRecords;
} else {
/* Too many records */
return -1;
}
} /* end while */
return p - beg;
} /* end ParseIntResultList() */
/* ******************************************************************* */
/*!
* \internal
* \brief Encode the ServedUserNumberList type.
*
* \param Dest Where to put the encoding
* \param ServedUserNumberList Served user record list information to encode.
*
* \retval length
*/
static int encodeServedUserNumberList(__u8 * Dest, const struct FacServedUserNumberList *ServedUserNumberList)
{
unsigned Index;
__u8 *p;
Dest[0] = ASN1_TAG_SET;
p = &Dest[1 + ASN1_NUM_OCTETS_LONG_LENGTH_u8];
for (Index = 0; Index < ServedUserNumberList->NumRecords; ++Index) {
p += encodePartyNumber_Full(p, &ServedUserNumberList->List[Index]);
} /* end for */
/* length */
encodeLen_Long_u8(&Dest[1], p - &Dest[1 + ASN1_NUM_OCTETS_LONG_LENGTH_u8]);
return p - Dest;
} /* end encodeServedUserNumberList() */
/* ******************************************************************* */
/*!
* \brief Parse the ServedUserNumberList argument parameters.
*
* \param pc Complete component message storage data.
* \param p Starting buffer position to parse arguments
* \param end End buffer position that must not go past.
* \param ServedUserNumberList Served user record list storage to fill.
*
* \retval length of buffer consumed
* \retval -1 on error.
*/
int ParseServedUserNumberList(struct asn1_parm *pc, u_char * p, u_char * end, struct FacServedUserNumberList *ServedUserNumberList)
{
INIT;
ServedUserNumberList->NumRecords = 0;
while (p < end) {
if (ServedUserNumberList->NumRecords < sizeof(ServedUserNumberList->List) / sizeof(ServedUserNumberList->List[0])) {
XSEQUENCE_1(ParsePartyNumber_Full, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED,
&ServedUserNumberList->List[ServedUserNumberList->NumRecords]);
++ServedUserNumberList->NumRecords;
} else {
/* Too many records */
return -1;
}
} /* end while */
return p - beg;
} /* end ParseServedUserNumberList() */
/* ******************************************************************* */
/*!
* \brief Encode the ActivationDiversion facility ie.
*
* \param Dest Where to put the encoding
* \param ActivationDiversion Information needed to encode in ie.
*
* \retval length on success.
* \retval -1 on error.
*/
int encodeFacActivationDiversion(__u8 * Dest, const struct asn1_parm *pc, const struct FacActivationDiversion *ActivationDiversion)
{
int Length;
__u8 *p;
__u8 *SeqStart;
switch (pc->comp) {
case CompInvoke:
p = encodeComponentInvoke_Head(Dest, pc->u.inv.invokeId, Fac_ActivationDiversion);
SeqStart = p;
SeqStart[0] = ASN1_TAG_SEQUENCE;
p = &SeqStart[2];
p += encodeEnum(p, ASN1_TAG_ENUM, ActivationDiversion->Procedure);
p += encodeEnum(p, ASN1_TAG_ENUM, ActivationDiversion->BasicService);
p += encodeAddress_Full(p, &ActivationDiversion->ForwardedTo);
p += encodeServedUserNumber_Full(p, &ActivationDiversion->ServedUser);
/* sequence Length */
SeqStart[1] = p - &SeqStart[2];
Length = encodeComponent_Length(Dest, p);
break;
case CompReturnResult:
p = encodeComponent_Head(Dest, asn1ComponentTag_Result);
p += encodeInt(p, ASN1_TAG_INTEGER, pc->u.retResult.invokeId);
SeqStart = p;
SeqStart[0] = ASN1_TAG_SEQUENCE;
p = &SeqStart[2];
p += encodeOperationValue(p, Fac_ActivationDiversion);
/* No arguments */
/* sequence Length */
SeqStart[1] = p - &SeqStart[2];
Length = encodeComponent_Length(Dest, p);
break;
default:
Length = -1;
break;
} /* end switch */
return Length;
} /* end encodeFacActivationDiversion() */
/* ******************************************************************* */
/*!
* \brief Parse the ActivationDiversion invoke argument parameters.
*
* \param pc Complete component message storage data.
* \param p Starting buffer position to parse arguments
* \param end End buffer position that must not go past.
* \param ActivationDiversion Parameter storage to fill.
*
* \retval length of buffer consumed
* \retval -1 on error.
*/
int ParseActivationDiversion(struct asn1_parm *pc, u_char * p, u_char * end,
struct FacActivationDiversion *ActivationDiversion)
{
unsigned int Value;
INIT;
XSEQUENCE_1(ParseEnum, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, &Value);
ActivationDiversion->Procedure = Value;
XSEQUENCE_1(ParseEnum, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, &Value);
ActivationDiversion->BasicService = Value;
XSEQUENCE_1(ParseAddress_Full, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &ActivationDiversion->ForwardedTo);
XSEQUENCE_1(ParseServedUserNumber_Full, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &ActivationDiversion->ServedUser);
return p - beg;
} /* end ParseActivationDiversion() */
/* ******************************************************************* */
/*!
* \brief Encode the DeactivationDiversion facility ie.
*
* \param Dest Where to put the encoding
* \param DeactivationDiversion Information needed to encode in ie.
*
* \retval length on success.
* \retval -1 on error.
*/
int encodeFacDeactivationDiversion(__u8 * Dest, const struct asn1_parm *pc, const struct FacDeactivationDiversion *DeactivationDiversion)
{
int Length;
__u8 *p;
__u8 *SeqStart;
switch (pc->comp) {
case CompInvoke:
p = encodeComponentInvoke_Head(Dest, pc->u.inv.invokeId, Fac_DeactivationDiversion);
SeqStart = p;
SeqStart[0] = ASN1_TAG_SEQUENCE;
p = &SeqStart[2];
p += encodeEnum(p, ASN1_TAG_ENUM, DeactivationDiversion->Procedure);
p += encodeEnum(p, ASN1_TAG_ENUM, DeactivationDiversion->BasicService);
p += encodeServedUserNumber_Full(p, &DeactivationDiversion->ServedUser);
/* sequence Length */
SeqStart[1] = p - &SeqStart[2];
Length = encodeComponent_Length(Dest, p);
break;
case CompReturnResult:
p = encodeComponent_Head(Dest, asn1ComponentTag_Result);
p += encodeInt(p, ASN1_TAG_INTEGER, pc->u.retResult.invokeId);
SeqStart = p;
SeqStart[0] = ASN1_TAG_SEQUENCE;
p = &SeqStart[2];
p += encodeOperationValue(p, Fac_DeactivationDiversion);
/* No arguments */
/* sequence Length */
SeqStart[1] = p - &SeqStart[2];
Length = encodeComponent_Length(Dest, p);
break;
default:
Length = -1;
break;
} /* end switch */
return Length;
} /* end encodeFacDeactivationDiversion() */
/* ******************************************************************* */
/*!
* \brief Parse the DeactivationDiversion invoke argument parameters.
*
* \param pc Complete component message storage data.
* \param p Starting buffer position to parse arguments
* \param end End buffer position that must not go past.
* \param DeactivationDiversion Parameter storage to fill.
*
* \retval length of buffer consumed
* \retval -1 on error.
*/
int ParseDeactivationDiversion(struct asn1_parm *pc, u_char * p, u_char * end, struct FacDeactivationDiversion *DeactivationDiversion)
{
unsigned int Value;
INIT;
XSEQUENCE_1(ParseEnum, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, &Value);
DeactivationDiversion->Procedure = Value;
XSEQUENCE_1(ParseEnum, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, &Value);
DeactivationDiversion->BasicService = Value;
XSEQUENCE_1(ParseServedUserNumber_Full, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &DeactivationDiversion->ServedUser);
return p - beg;
} /* end ParseDeactivationDiversion() */
/* ******************************************************************* */
/*!
* \brief Encode the ActivationStatusNotificationDiv facility ie.
*
* \param Dest Where to put the encoding
* \param ActivationStatusNotificationDiv Information needed to encode in ie.
*
* \retval length on success.
* \retval -1 on error.
*/
int encodeFacActivationStatusNotificationDiv(__u8 * Dest, const struct asn1_parm *pc,
const struct FacActivationStatusNotificationDiv *ActivationStatusNotificationDiv)
{
int Length;
__u8 *p;
__u8 *SeqStart;
p = encodeComponentInvoke_Head(Dest, pc->u.inv.invokeId, Fac_ActivationStatusNotificationDiv);
SeqStart = p;
SeqStart[0] = ASN1_TAG_SEQUENCE;
p = &SeqStart[2];
p += encodeEnum(p, ASN1_TAG_ENUM, ActivationStatusNotificationDiv->Procedure);
p += encodeEnum(p, ASN1_TAG_ENUM, ActivationStatusNotificationDiv->BasicService);
p += encodeAddress_Full(p, &ActivationStatusNotificationDiv->ForwardedTo);
p += encodeServedUserNumber_Full(p, &ActivationStatusNotificationDiv->ServedUser);
/* sequence Length */
SeqStart[1] = p - &SeqStart[2];
Length = encodeComponent_Length(Dest, p);
return Length;
} /* end encodeFacActivationStatusNotificationDiv() */
/* ******************************************************************* */
/*!
* \brief Parse the ActivationStatusNotificationDiv invoke argument parameters.
*
* \param pc Complete component message storage data.
* \param p Starting buffer position to parse arguments
* \param end End buffer position that must not go past.
* \param ActivationStatusNotificationDiv Parameter storage to fill.
*
* \retval length of buffer consumed
* \retval -1 on error.
*/
int ParseActivationStatusNotificationDiv(struct asn1_parm *pc, u_char * p, u_char * end,
struct FacActivationStatusNotificationDiv *ActivationStatusNotificationDiv)
{
unsigned int Value;
INIT;
XSEQUENCE_1(ParseEnum, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, &Value);
ActivationStatusNotificationDiv->Procedure = Value;
XSEQUENCE_1(ParseEnum, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, &Value);
ActivationStatusNotificationDiv->BasicService = Value;
XSEQUENCE_1(ParseAddress_Full, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &ActivationStatusNotificationDiv->ForwardedTo);
XSEQUENCE_1(ParseServedUserNumber_Full, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &ActivationStatusNotificationDiv->ServedUser);
return p - beg;
} /* end ParseActivationStatusNotificationDiv() */
/* ******************************************************************* */
/*!
* \brief Encode the DeactivationStatusNotificationDiv facility ie.
*
* \param Dest Where to put the encoding
* \param DeactivationStatusNotificationDiv Information needed to encode in ie.
*
* \retval length on success.
* \retval -1 on error.
*/
int encodeFacDeactivationStatusNotificationDiv(__u8 * Dest, const struct asn1_parm *pc,
const struct FacDeactivationStatusNotificationDiv
*DeactivationStatusNotificationDiv)
{
int Length;
__u8 *p;
__u8 *SeqStart;
p = encodeComponentInvoke_Head(Dest, pc->u.inv.invokeId, Fac_DeactivationStatusNotificationDiv);
SeqStart = p;
SeqStart[0] = ASN1_TAG_SEQUENCE;
p = &SeqStart[2];
p += encodeEnum(p, ASN1_TAG_ENUM, DeactivationStatusNotificationDiv->Procedure);
p += encodeEnum(p, ASN1_TAG_ENUM, DeactivationStatusNotificationDiv->BasicService);
p += encodeServedUserNumber_Full(p, &DeactivationStatusNotificationDiv->ServedUser);
/* sequence Length */
SeqStart[1] = p - &SeqStart[2];
Length = encodeComponent_Length(Dest, p);
return Length;
} /* end encodeFacDeactivationStatusNotificationDiv() */
/* ******************************************************************* */
/*!
* \brief Parse the DeactivationStatusNotificationDiv invoke argument parameters.
*
* \param pc Complete component message storage data.
* \param p Starting buffer position to parse arguments
* \param end End buffer position that must not go past.
* \param DeactivationStatusNotificationDiv Parameter storage to fill.
*
* \retval length of buffer consumed
* \retval -1 on error.
*/
int ParseDeactivationStatusNotificationDiv(struct asn1_parm *pc, u_char * p, u_char * end,
struct FacDeactivationStatusNotificationDiv *DeactivationStatusNotificationDiv)
{
unsigned int Value;
INIT;
XSEQUENCE_1(ParseEnum, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, &Value);
DeactivationStatusNotificationDiv->Procedure = Value;
XSEQUENCE_1(ParseEnum, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, &Value);
DeactivationStatusNotificationDiv->BasicService = Value;
XSEQUENCE_1(ParseServedUserNumber_Full, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &DeactivationStatusNotificationDiv->ServedUser);
return p - beg;
} /* end ParseDeactivationStatusNotificationDiv() */
/* ******************************************************************* */
/*!
* \brief Encode the InterrogationDiversion facility ie.
*
* \param Dest Where to put the encoding
* \param InterrogationDiversion Information needed to encode in ie.
*
* \retval length on success.
* \retval -1 on error.
*/
int encodeFacInterrogationDiversion(__u8 * Dest, const struct asn1_parm *pc, const struct FacInterrogationDiversion *InterrogationDiversion)
{
int Length;
__u8 *p;
__u8 *SeqStart;
switch (pc->comp) {
case CompInvoke:
p = encodeComponentInvoke_Head(Dest, pc->u.inv.invokeId, Fac_InterrogationDiversion);
SeqStart = p;
SeqStart[0] = ASN1_TAG_SEQUENCE;
p = &SeqStart[2];
p += encodeEnum(p, ASN1_TAG_ENUM, InterrogationDiversion->Procedure);
if (InterrogationDiversion->BasicService) {
/* Not the DEFAULT value */
p += encodeEnum(p, ASN1_TAG_ENUM, InterrogationDiversion->BasicService);
}
p += encodeServedUserNumber_Full(p, &InterrogationDiversion->ServedUser);
/* sequence Length */
SeqStart[1] = p - &SeqStart[2];
Length = encodeComponent_Length(Dest, p);
break;
case CompReturnResult:
p = encodeComponent_Head_Long_u8(Dest, asn1ComponentTag_Result);
p += encodeInt(p, ASN1_TAG_INTEGER, pc->u.retResult.invokeId);
SeqStart = p;
SeqStart[0] = ASN1_TAG_SEQUENCE;
p = &SeqStart[1 + ASN1_NUM_OCTETS_LONG_LENGTH_u8];
p += encodeOperationValue(p, Fac_InterrogationDiversion);
p += encodeIntResultList(p, &pc->u.retResult.o.InterrogationDiversion);
/* sequence Length */
encodeLen_Long_u8(&SeqStart[1], p - &SeqStart[1 + ASN1_NUM_OCTETS_LONG_LENGTH_u8]);
Length = encodeComponent_Length_Long_u8(Dest, p);
break;
default:
Length = -1;
break;
} /* end switch */
return Length;
} /* end encodeFacInterrogationDiversion() */
/* ******************************************************************* */
/*!
* \brief Parse the InterrogationDiversion invoke argument parameters.
*
* \param pc Complete component message storage data.
* \param p Starting buffer position to parse arguments
* \param end End buffer position that must not go past.
* \param InterrogationDiversion Parameter storage to fill.
*
* \retval length of buffer consumed
* \retval -1 on error.
*/
int ParseInterrogationDiversion(struct asn1_parm *pc, u_char * p, u_char * end,
struct FacInterrogationDiversion *InterrogationDiversion)
{
unsigned int Value;
INIT;
XSEQUENCE_1(ParseEnum, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, &Value);
InterrogationDiversion->Procedure = Value;
Value = 0; /* DEFAULT BasicService value (allServices) */
XSEQUENCE_OPT_1(ParseEnum, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, &Value);
InterrogationDiversion->BasicService = Value;
XSEQUENCE_1(ParseServedUserNumber_Full, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &InterrogationDiversion->ServedUser);
return p - beg;
} /* end ParseInterrogationDiversion() */
/* ******************************************************************* */
#if 0
/*!
* \brief Parse the InterrogationDiversion result parameters.
*
* \param pc Complete component message storage data.
* \param p Starting buffer position to parse parameters
* \param end End buffer position that must not go past.
* \param InterrogationDiversion Parameter storage to fill.
*
* \retval length of buffer consumed
* \retval -1 on error.
*/
int ParseInterrogationDiversion_RES(struct asn1_parm *pc, u_char * p, u_char * end,
struct FacForwardingList *InterrogationDiversion)
{
return ParseIntResultList(pc, p, end, InterrogationDiversion);
} /* end ParseInterrogationDiversion_RES() */
#endif
/* ******************************************************************* */
/*!
* \brief Encode the DiversionInformation facility ie.
*
* \param Dest Where to put the encoding
* \param DiversionInformation Information needed to encode in ie.
*
* \retval length on success.
* \retval -1 on error.
*/
int encodeFacDiversionInformation(__u8 * Dest, const struct asn1_parm *pc, const struct FacDiversionInformation *DiversionInformation)
{
int Length;
__u8 *p;
__u8 *SeqStart;
__u8 *TagStart;
p = encodeComponentInvoke_Head_Long_u8(Dest, pc->u.inv.invokeId, Fac_DiversionInformation);
SeqStart = p;
SeqStart[0] = ASN1_TAG_SEQUENCE;
p = &SeqStart[1 + ASN1_NUM_OCTETS_LONG_LENGTH_u8];
p += encodeEnum(p, ASN1_TAG_ENUM, DiversionInformation->DiversionReason);
p += encodeEnum(p, ASN1_TAG_ENUM, DiversionInformation->BasicService);
if (DiversionInformation->ServedUserSubaddress.Length) {
p += encodePartySubaddress_Full(p, &DiversionInformation->ServedUserSubaddress);
}
if (DiversionInformation->CallingAddressPresent) {
TagStart = p;
TagStart[0] = ASN1_TAG_CONTEXT_SPECIFIC | ASN1_TAG_CONSTRUCTED | 0;
p = &TagStart[2];
p += encodePresentedAddressScreened_Full(p, &DiversionInformation->CallingAddress);
/* Tag Length */
TagStart[1] = p - &TagStart[2];
}
if (DiversionInformation->OriginalCalledPresent) {
TagStart = p;
TagStart[0] = ASN1_TAG_CONTEXT_SPECIFIC | ASN1_TAG_CONSTRUCTED | 1;
p = &TagStart[2];
p += encodePresentedNumberUnscreened_Full(p, &DiversionInformation->OriginalCalled);
/* Tag Length */
TagStart[1] = p - &TagStart[2];
}
if (DiversionInformation->LastDivertingPresent) {
TagStart = p;
TagStart[0] = ASN1_TAG_CONTEXT_SPECIFIC | ASN1_TAG_CONSTRUCTED | 2;
p = &TagStart[2];
p += encodePresentedNumberUnscreened_Full(p, &DiversionInformation->LastDiverting);
/* Tag Length */
TagStart[1] = p - &TagStart[2];
}
if (DiversionInformation->LastDivertingReasonPresent) {
TagStart = p;
TagStart[0] = ASN1_TAG_CONTEXT_SPECIFIC | ASN1_TAG_CONSTRUCTED | 3;
p = &TagStart[2];
p += encodeEnum(p, ASN1_TAG_ENUM, DiversionInformation->LastDivertingReason);
/* Tag Length */
TagStart[1] = p - &TagStart[2];
}
if (DiversionInformation->UserInfo.Length) {
p += encodeQ931_Div_UserInfo(p, &DiversionInformation->UserInfo);
}
/* sequence Length */
encodeLen_Long_u8(&SeqStart[1], p - &SeqStart[1 + ASN1_NUM_OCTETS_LONG_LENGTH_u8]);
Length = encodeComponent_Length_Long_u8(Dest, p);
return Length;
} /* end encodeFacDiversionInformation() */
/* ******************************************************************* */
/*!
* \brief Parse the DiversionInformation invoke argument parameters.
*
* \param pc Complete component message storage data.
* \param p Starting buffer position to parse arguments
* \param end End buffer position that must not go past.
* \param DiversionInformation Parameter storage to fill.
*
* \retval length of buffer consumed
* \retval -1 on error.
*/
int ParseDiversionInformation(struct asn1_parm *pc, u_char * p, u_char * end,
struct FacDiversionInformation *DiversionInformation)
{
int xtag;
int xlen;
unsigned int Value;
INIT;
XSEQUENCE_1(ParseEnum, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, &Value);
DiversionInformation->DiversionReason = Value;
XSEQUENCE_1(ParseEnum, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, &Value);
DiversionInformation->BasicService = Value;
if (p < end && (*p == ASN1_TAG_SEQUENCE || *p == ASN1_TAG_OCTET_STRING)) {
CallASN1(ret, p, end, ParsePartySubaddress_Full(pc, p, end, &DiversionInformation->ServedUserSubaddress));
} else {
DiversionInformation->ServedUserSubaddress.Length = 0;
}
if (p < end && *p == (ASN1_TAG_CONTEXT_SPECIFIC | ASN1_TAG_CONSTRUCTED | 0)) {
/* Remove EXPLICIT tag */
CallASN1(ret, p, end, ParseTag(p, end, &xtag));
CallASN1(ret, p, end, ParseLen(p, end, &xlen));
CallASN1(ret, p, end, ParsePresentedAddressScreened_Full(pc, p, end, &DiversionInformation->CallingAddress));
DiversionInformation->CallingAddressPresent = 1;
} else {
DiversionInformation->CallingAddressPresent = 0;
}
if (p < end && *p == (ASN1_TAG_CONTEXT_SPECIFIC | ASN1_TAG_CONSTRUCTED | 1)) {
/* Remove EXPLICIT tag */
CallASN1(ret, p, end, ParseTag(p, end, &xtag));
CallASN1(ret, p, end, ParseLen(p, end, &xlen));
CallASN1(ret, p, end, ParsePresentedNumberUnscreened_Full(pc, p, end, &DiversionInformation->OriginalCalled));
DiversionInformation->OriginalCalledPresent = 1;
} else {
DiversionInformation->OriginalCalledPresent = 0;
}
if (p < end && *p == (ASN1_TAG_CONTEXT_SPECIFIC | ASN1_TAG_CONSTRUCTED | 2)) {
/* Remove EXPLICIT tag */
CallASN1(ret, p, end, ParseTag(p, end, &xtag));
CallASN1(ret, p, end, ParseLen(p, end, &xlen));
CallASN1(ret, p, end, ParsePresentedNumberUnscreened_Full(pc, p, end, &DiversionInformation->LastDiverting));
DiversionInformation->LastDivertingPresent = 1;
} else {
DiversionInformation->LastDivertingPresent = 0;
}
if (p < end && *p == (ASN1_TAG_CONTEXT_SPECIFIC | ASN1_TAG_CONSTRUCTED | 3)) {
/* Remove EXPLICIT tag */
CallASN1(ret, p, end, ParseTag(p, end, &xtag));
CallASN1(ret, p, end, ParseLen(p, end, &xlen));
CallASN1(ret, p, end, ParseEnum(pc, p, end, &Value));
DiversionInformation->LastDivertingReason = Value;
DiversionInformation->LastDivertingReasonPresent = 1;
} else {
DiversionInformation->LastDivertingReasonPresent = 0;
}
DiversionInformation->UserInfo.Length = 0;
XSEQUENCE_OPT_1(ParseQ931_Div_UserInfo, ASN1_TAG_APPLICATION_WIDE, 0, &DiversionInformation->UserInfo);
return p - beg;
} /* end ParseDiversionInformation() */
/* ******************************************************************* */
/*!
* \brief Encode the CallDeflection facility ie.
*
* \param Dest Where to put the encoding
* \param CallDeflection Information needed to encode in ie.
*
* \retval length on success.
* \retval -1 on error.
*/
int encodeFacCallDeflection(__u8 * Dest, const struct asn1_parm *pc, const struct FacCallDeflection *CallDeflection)
{
int Length;
__u8 *p;
__u8 *SeqStart;
switch (pc->comp) {
case CompInvoke:
p = encodeComponentInvoke_Head(Dest, pc->u.inv.invokeId, Fac_CallDeflection);
SeqStart = p;
SeqStart[0] = ASN1_TAG_SEQUENCE;
p = &SeqStart[2];
p += encodeAddress_Full(p, &CallDeflection->Deflection);
if (CallDeflection->PresentationAllowedToDivertedToUserPresent) {
p += encodeBoolean(p, ASN1_TAG_BOOLEAN,
CallDeflection->PresentationAllowedToDivertedToUser);
}
/* sequence Length */
SeqStart[1] = p - &SeqStart[2];
Length = encodeComponent_Length(Dest, p);
break;
case CompReturnResult:
p = encodeComponent_Head(Dest, asn1ComponentTag_Result);
p += encodeInt(p, ASN1_TAG_INTEGER, pc->u.retResult.invokeId);
SeqStart = p;
SeqStart[0] = ASN1_TAG_SEQUENCE;
p = &SeqStart[2];
p += encodeOperationValue(p, Fac_CallDeflection);
/* No arguments */
/* sequence Length */
SeqStart[1] = p - &SeqStart[2];
Length = encodeComponent_Length(Dest, p);
break;
default:
Length = -1;
break;
} /* end switch */
return Length;
} /* end encodeFacCallDeflection() */
/* ******************************************************************* */
/*!
* \brief Parse the CallDeflection invoke argument parameters.
*
* \param pc Complete component message storage data.
* \param p Starting buffer position to parse arguments
* \param end End buffer position that must not go past.
* \param CallDeflection Parameter storage to fill.
*
* \retval length of buffer consumed
* \retval -1 on error.
*/
int ParseCallDeflection(struct asn1_parm *pc, u_char * p, u_char * end, struct FacCallDeflection *CallDeflection)
{
int Value;
INIT;
XSEQUENCE_1(ParseAddress_Full, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &CallDeflection->Deflection);
if (p < end) {
CallDeflection->PresentationAllowedToDivertedToUserPresent = 1;
XSEQUENCE_1(ParseBoolean, ASN1_TAG_BOOLEAN, ASN1_NOT_TAGGED, &Value);
CallDeflection->PresentationAllowedToDivertedToUser = Value;
} else {
CallDeflection->PresentationAllowedToDivertedToUserPresent = 0;
}
return p - beg;
} /* end ParseCallDeflection() */
/* ******************************************************************* */
/*!
* \brief Encode the CallRerouteing facility ie.
*
* \param Dest Where to put the encoding
* \param CallRerouteing Information needed to encode in ie.
*
* \retval length on success.
* \retval -1 on error.
*/
int encodeFacCallRerouteing(__u8 * Dest, const struct asn1_parm *pc, const struct FacCallRerouteing *CallRerouteing)
{
int Length;
__u8 *p;
__u8 *SeqStart;
__u8 *TagStart;
__u8 big = 0;
start:
switch (pc->comp) {
case CompInvoke:
if (big)
p = encodeComponentInvoke_Head_Long_u8(Dest, pc->u.inv.invokeId, Fac_CallRerouteing);
else
p = encodeComponentInvoke_Head(Dest, pc->u.inv.invokeId, Fac_CallRerouteing);
SeqStart = p;
SeqStart[0] = ASN1_TAG_SEQUENCE;
p = &SeqStart[2 + big];
p += encodeEnum(p, ASN1_TAG_ENUM, CallRerouteing->ReroutingReason);
p += encodeAddress_Full(p, &CallRerouteing->CalledAddress);
p += encodeInt(p, ASN1_TAG_INTEGER, CallRerouteing->ReroutingCounter);
p += encodeQ931_Div(p, &CallRerouteing->Q931ie);
TagStart = p;
TagStart[0] = ASN1_TAG_CONTEXT_SPECIFIC | ASN1_TAG_CONSTRUCTED | 1;
p = &TagStart[2];
p += encodePresentedNumberUnscreened_Full(p, &CallRerouteing->LastRerouting);
/* Tag Length */
TagStart[1] = p - &TagStart[2];
if (CallRerouteing->SubscriptionOption) {
/* Not the DEFAULT value */
TagStart = p;
TagStart[0] = ASN1_TAG_CONTEXT_SPECIFIC | ASN1_TAG_CONSTRUCTED | 2;
p = &TagStart[2];
p += encodeEnum(p, ASN1_TAG_ENUM, CallRerouteing->SubscriptionOption);
/* Tag Length */
TagStart[1] = p - &TagStart[2];
}
if (CallRerouteing->CallingPartySubaddress.Length) {
TagStart = p;
TagStart[0] = ASN1_TAG_CONTEXT_SPECIFIC | ASN1_TAG_CONSTRUCTED | 3;
p = &TagStart[2];
p += encodePartySubaddress_Full(p, &CallRerouteing->CallingPartySubaddress);
/* Tag Length */
TagStart[1] = p - &TagStart[2];
}
/* sequence Length */
if (big) {
encodeLen_Long_u8(&SeqStart[1], p - &SeqStart[1 + ASN1_NUM_OCTETS_LONG_LENGTH_u8]);
Length = encodeComponent_Length_Long_u8(Dest, p);
} else {
Length = p - &SeqStart[2];
if (Length > 127) {
big = 1; /* == ASN1_NUM_OCTETS_LONG_LENGTH_u8 - 1 */
/* start again with full byte length element */
goto start;
}
SeqStart[1] = Length & 0x7f;
Length = encodeComponent_Length(Dest, p);
}
break;
case CompReturnResult:
p = encodeComponent_Head(Dest, asn1ComponentTag_Result);
p += encodeInt(p, ASN1_TAG_INTEGER, pc->u.retResult.invokeId);
SeqStart = p;
SeqStart[0] = ASN1_TAG_SEQUENCE;
p = &SeqStart[2];
p += encodeOperationValue(p, Fac_CallRerouteing);
/* No arguments */
/* sequence Length */
SeqStart[1] = p - &SeqStart[2];
Length = encodeComponent_Length(Dest, p);
break;
default:
Length = -1;
break;
} /* end switch */
return Length;
} /* end encodeFacCallRerouteing() */
/* ******************************************************************* */
/*!
* \brief Parse the CallRerouteing invoke argument parameters.
*
* \param pc Complete component message storage data.
* \param p Starting buffer position to parse arguments
* \param end End buffer position that must not go past.
* \param CallRerouteing Parameter storage to fill.
*
* \retval length of buffer consumed
* \retval -1 on error.
*/
int ParseCallRerouteing(struct asn1_parm *pc, u_char * p, u_char * end, struct FacCallRerouteing *CallRerouteing)
{
unsigned int Value;
INIT;
XSEQUENCE_1(ParseEnum, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, &Value);
CallRerouteing->ReroutingReason = Value;
XSEQUENCE_1(ParseAddress_Full, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &CallRerouteing->CalledAddress);
XSEQUENCE_1(ParseUnsignedInteger, ASN1_TAG_INTEGER, ASN1_NOT_TAGGED, &Value);
CallRerouteing->ReroutingCounter = Value;
XSEQUENCE_1(ParseQ931_Div, ASN1_TAG_APPLICATION_WIDE, 0, &CallRerouteing->Q931ie);
XSEQUENCE_1(ParsePresentedNumberUnscreened_Full, ASN1_TAG_CONTEXT_SPECIFIC, ASN1_TAG_EXPLICIT | 1,
&CallRerouteing->LastRerouting);
Value = 0; /* DEFAULT value noNotification */
XSEQUENCE_OPT_1(ParseEnum, ASN1_TAG_CONTEXT_SPECIFIC, ASN1_TAG_EXPLICIT | 2, &Value);
CallRerouteing->SubscriptionOption = Value;
CallRerouteing->CallingPartySubaddress.Length = 0;
XSEQUENCE_OPT_1(ParsePartySubaddress_Full, ASN1_TAG_CONTEXT_SPECIFIC, ASN1_TAG_EXPLICIT | 3,
&CallRerouteing->CallingPartySubaddress);
return p - beg;
} /* end ParseCallRerouteing() */
/* ******************************************************************* */
/*!
* \brief Encode the InterrogateServedUserNumbers facility ie.
*
* \param Dest Where to put the encoding
* \param InterrogateServedUserNumbers Information needed to encode in ie.
*
* \retval length on success.
* \retval -1 on error.
*/
int encodeFacInterrogateServedUserNumbers(__u8 * Dest, const struct asn1_parm *pc, const struct FacServedUserNumberList *InterrogateServedUserNumbers)
{
int Length;
__u8 *p;
__u8 *SeqStart;
switch (pc->comp) {
case CompInvoke:
p = encodeComponentInvoke_Head(Dest, pc->u.inv.invokeId, Fac_InterrogateServedUserNumbers);
/* No arguments */
Length = encodeComponent_Length(Dest, p);
break;
case CompReturnResult:
p = encodeComponent_Head_Long_u8(Dest, asn1ComponentTag_Result);
p += encodeInt(p, ASN1_TAG_INTEGER, pc->u.retResult.invokeId);
SeqStart = p;
SeqStart[0] = ASN1_TAG_SEQUENCE;
p = &SeqStart[1 + ASN1_NUM_OCTETS_LONG_LENGTH_u8];
p += encodeOperationValue(p, Fac_InterrogateServedUserNumbers);
p += encodeServedUserNumberList(p, InterrogateServedUserNumbers);
/* sequence Length */
encodeLen_Long_u8(&SeqStart[1], p - &SeqStart[1 + ASN1_NUM_OCTETS_LONG_LENGTH_u8]);
Length = encodeComponent_Length_Long_u8(Dest, p);
break;
default:
Length = -1;
break;
} /* end switch */
return Length;
} /* end encodeFacInterrogateServedUserNumbers() */
/* ******************************************************************* */
#if 0
/*!
* \brief Parse the InterrogateServedUserNumbers result parameters.
*
* \param pc Complete component message storage data.
* \param p Starting buffer position to parse parameters
* \param end End buffer position that must not go past.
* \param InterrogateServedUserNumbers Parameter storage to fill.
*
* \retval length of buffer consumed
* \retval -1 on error.
*/
int ParseInterrogateServedUserNumbers_RES(struct asn1_parm *pc, u_char * p, u_char * end,
struct FacServedUserNumberList *InterrogateServedUserNumbers)
{
return ParseServedUserNumberList(pc, p, end, InterrogationDiversion);
} /* end ParseInterrogateServedUserNumbers_RES() */
#endif
/* ******************************************************************* */
/*!
* \brief Encode the DivertingLegInformation1 facility ie.
*
* \param Dest Where to put the encoding
* \param DivertingLegInformation1 Information needed to encode in ie.
*
* \retval length on success.
* \retval -1 on error.
*/
int encodeFacDivertingLegInformation1(__u8 * Dest, const struct asn1_parm *pc, const struct FacDivertingLegInformation1 *DivertingLegInformation1)
{
int Length;
__u8 *p;
__u8 *SeqStart;
p = encodeComponentInvoke_Head(Dest, pc->u.inv.invokeId, Fac_DivertingLegInformation1);
SeqStart = p;
SeqStart[0] = ASN1_TAG_SEQUENCE;
p = &SeqStart[2];
p += encodeEnum(p, ASN1_TAG_ENUM, DivertingLegInformation1->DiversionReason);
p += encodeEnum(p, ASN1_TAG_ENUM, DivertingLegInformation1->SubscriptionOption);
if (DivertingLegInformation1->DivertedToPresent) {
p += encodePresentedNumberUnscreened_Full(p, &DivertingLegInformation1->DivertedTo);
}
/* sequence Length */
SeqStart[1] = p - &SeqStart[2];
Length = encodeComponent_Length(Dest, p);
return Length;
} /* end encodeFacDivertingLegInformation1() */
/* ******************************************************************* */
/*!
* \brief Parse the DivertingLegInformation1 invoke argument parameters.
*
* \param pc Complete component message storage data.
* \param p Starting buffer position to parse arguments
* \param end End buffer position that must not go past.
* \param DivertingLegInformation1 Parameter storage to fill.
*
* \retval length of buffer consumed
* \retval -1 on error.
*/
int ParseDivertingLegInformation1(struct asn1_parm *pc, u_char * p, u_char * end,
struct FacDivertingLegInformation1 *DivertingLegInformation1)
{
unsigned int Value;
INIT;
XSEQUENCE_1(ParseEnum, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, &Value);
DivertingLegInformation1->DiversionReason = Value;
XSEQUENCE_1(ParseEnum, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, &Value);
DivertingLegInformation1->SubscriptionOption = Value;
if (p < end) {
XSEQUENCE_1(ParsePresentedNumberUnscreened_Full, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED,
&DivertingLegInformation1->DivertedTo);
DivertingLegInformation1->DivertedToPresent = 1;
} else {
DivertingLegInformation1->DivertedToPresent = 0;
}
return p - beg;
} /* end ParseDivertingLegInformation1() */
/* ******************************************************************* */
/*!
* \brief Encode the DivertingLegInformation2 facility ie.
*
* \param Dest Where to put the encoding
* \param DivertingLegInformation2 Information needed to encode in ie.
*
* \retval length on success.
* \retval -1 on error.
*/
int encodeFacDivertingLegInformation2(__u8 * Dest, const struct asn1_parm *pc, const struct FacDivertingLegInformation2 *DivertingLegInformation2)
{
int Length;
__u8 *p;
__u8 *SeqStart;
__u8 *TagStart;
p = encodeComponentInvoke_Head(Dest, pc->u.inv.invokeId, Fac_DivertingLegInformation2);
SeqStart = p;
SeqStart[0] = ASN1_TAG_SEQUENCE;
p = &SeqStart[2];
p += encodeInt(p, ASN1_TAG_INTEGER, DivertingLegInformation2->DiversionCounter);
p += encodeEnum(p, ASN1_TAG_ENUM, DivertingLegInformation2->DiversionReason);
if (DivertingLegInformation2->DivertingPresent) {
TagStart = p;
TagStart[0] = ASN1_TAG_CONTEXT_SPECIFIC | ASN1_TAG_CONSTRUCTED | 1;
p = &TagStart[2];
p += encodePresentedNumberUnscreened_Full(p, &DivertingLegInformation2->Diverting);
/* Tag Length */
TagStart[1] = p - &TagStart[2];
}
if (DivertingLegInformation2->OriginalCalledPresent) {
TagStart = p;
TagStart[0] = ASN1_TAG_CONTEXT_SPECIFIC | ASN1_TAG_CONSTRUCTED | 2;
p = &TagStart[2];
p += encodePresentedNumberUnscreened_Full(p, &DivertingLegInformation2->OriginalCalled);
/* Tag Length */
TagStart[1] = p - &TagStart[2];
}
/* sequence Length */
SeqStart[1] = p - &SeqStart[2];
Length = encodeComponent_Length(Dest, p);
return Length;
} /* end encodeFacDivertingLegInformation2() */
/* ******************************************************************* */
/*!
* \brief Parse the DivertingLegInformation2 invoke argument parameters.
*
* \param pc Complete component message storage data.
* \param p Starting buffer position to parse arguments
* \param end End buffer position that must not go past.
* \param DivertingLegInformation2 Parameter storage to fill.
*
* \retval length of buffer consumed
* \retval -1 on error.
*/
int ParseDivertingLegInformation2(struct asn1_parm *pc, u_char * p, u_char * end,
struct FacDivertingLegInformation2 *DivertingLegInformation2)
{
int xtag;
int xlen;
unsigned int Value;
INIT;
XSEQUENCE_1(ParseUnsignedInteger, ASN1_TAG_INTEGER, ASN1_NOT_TAGGED, &Value);
DivertingLegInformation2->DiversionCounter = Value;
XSEQUENCE_1(ParseEnum, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, &Value);
DivertingLegInformation2->DiversionReason = Value;
if (p < end && *p == (ASN1_TAG_CONTEXT_SPECIFIC | ASN1_TAG_CONSTRUCTED | 1)) {
DivertingLegInformation2->DivertingPresent = 1;
CallASN1(ret, p, end, ParseTag(p, end, &xtag));
CallASN1(ret, p, end, ParseLen(p, end, &xlen));
CallASN1(ret, p, end, ParsePresentedNumberUnscreened_Full(pc, p, end, &DivertingLegInformation2->Diverting));
} else {
DivertingLegInformation2->DivertingPresent = 0;
}
if (p < end && *p == (ASN1_TAG_CONTEXT_SPECIFIC | ASN1_TAG_CONSTRUCTED | 2)) {
DivertingLegInformation2->OriginalCalledPresent = 1;
CallASN1(ret, p, end, ParseTag(p, end, &xtag));
CallASN1(ret, p, end, ParseLen(p, end, &xlen));
CallASN1(ret, p, end, ParsePresentedNumberUnscreened_Full(pc, p, end, &DivertingLegInformation2->OriginalCalled));
} else {
DivertingLegInformation2->OriginalCalledPresent = 0;
}
return p - beg;
} /* end ParseDivertingLegInformation2() */
/* ******************************************************************* */
/*!
* \brief Encode the DivertingLegInformation3 facility ie.
*
* \param Dest Where to put the encoding
* \param DivertingLegInformation3 Information needed to encode in ie.
*
* \retval length on success.
* \retval -1 on error.
*/
int encodeFacDivertingLegInformation3(__u8 * Dest, const struct asn1_parm *pc, const struct FacDivertingLegInformation3 *DivertingLegInformation3)
{
int Length;
__u8 *p;
p = encodeComponentInvoke_Head(Dest, pc->u.inv.invokeId, Fac_DivertingLegInformation3);
p += encodeBoolean(p, ASN1_TAG_BOOLEAN, DivertingLegInformation3->PresentationAllowedIndicator);
Length = encodeComponent_Length(Dest, p);
return Length;
} /* end encodeFacDivertingLegInformation3() */
/* ******************************************************************* */
/*!
* \brief Parse the DivertingLegInformation3 invoke argument parameters.
*
* \param pc Complete component message storage data.
* \param p Starting buffer position to parse arguments
* \param end End buffer position that must not go past.
* \param DivertingLegInformation3 Parameter storage to fill.
*
* \retval length of buffer consumed
* \retval -1 on error.
*/
int ParseDivertingLegInformation3(struct asn1_parm *pc, u_char * p, u_char * end,
struct FacDivertingLegInformation3 *DivertingLegInformation3)
{
int Value;
int ret;
u_char *beg;
beg = p;
XSEQUENCE_1(ParseBoolean, ASN1_TAG_BOOLEAN, ASN1_NOT_TAGGED, &Value);
DivertingLegInformation3->PresentationAllowedIndicator = Value;
return p - beg;
} /* end ParseDivertingLegInformation3() */
/* ------------------------------------------------------------------- */
/* end asn1_diversion.c */