591 lines
19 KiB
C
591 lines
19 KiB
C
/*
|
|
* ASN1 components for supplementary services
|
|
*
|
|
* 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 "ccbs.h"
|
|
#include "ect.h"
|
|
#include <string.h>
|
|
|
|
// ======================================================================
|
|
// Component EN 300 196-1 D.1
|
|
|
|
static const struct asn1OidConvert OIDConversion[] = {
|
|
/* *INDENT-OFF* */
|
|
/*
|
|
* Note the first value in oid.values[] is really the first two
|
|
* OID subidentifiers. They are compressed using this formula:
|
|
* First_Value = (First_Subidentifier * 40) + Second_Subidentifier
|
|
*/
|
|
|
|
/* {ccitt(0) identified-organization(4) etsi(0) 359 operations-and-errors(1)} */
|
|
{ FacOIDBase_CCBS, { 4, { 4, 0, 359, 1 } } },
|
|
|
|
/* {ccitt(0) identified-organization(4) etsi(0) 359 private-networks-operations-and-errors(2)} */
|
|
{ FacOIDBase_CCBS_T, { 4, { 4, 0, 359, 2 } } },
|
|
|
|
/* {ccitt(0) identified-organization(4) etsi(0) 1065 operations-and-errors(1)} */
|
|
{ FacOIDBase_CCNR, { 4, { 4, 0, 1065, 1 } } },
|
|
|
|
/* {ccitt(0) identified-organization(4) etsi(0) 1065 private-networks-operations-and-errors(2)} */
|
|
{ FacOIDBase_CCNR_T, { 4, { 4, 0, 1065, 2 } } },
|
|
|
|
/* {itu-t(0) identified-organization(4) etsi(0) 196 status-request-procedure(9)} */
|
|
{ FacOIDBase_StatusRequest, { 4, { 4, 0, 196, 9 } } },
|
|
|
|
/* {ccitt(0) identified-organization(4) etsi(0) 369 operations-and-errors(1)} */
|
|
{ FacOIDBase_ECT, { 4, { 4, 0, 369, 1 } } },
|
|
/* *INDENT-ON* */
|
|
};
|
|
|
|
const struct asn1OidConvert *FindOidByOidValue(int length, const __u16 oidValues[])
|
|
{
|
|
int index;
|
|
|
|
for (index = 0; index < sizeof(OIDConversion) / sizeof(OIDConversion[0]); ++index) {
|
|
if (OIDConversion[index].oid.numValues == length
|
|
&& memcmp(OIDConversion[index].oid.value, oidValues, length * sizeof(oidValues[0])) == 0) {
|
|
return &OIDConversion[index];
|
|
}
|
|
} /* end for */
|
|
|
|
return NULL;
|
|
} /* end FindOidByOidValue() */
|
|
|
|
const struct asn1OidConvert *FindOidByEnum(__u16 value)
|
|
{
|
|
int index;
|
|
|
|
for (index = 0; index < sizeof(OIDConversion) / sizeof(OIDConversion[0]); ++index) {
|
|
if (FAC_OID_BASE(OIDConversion[index].baseCode) <= value && value < FAC_OID_BASE(OIDConversion[index].baseCode + 1)) {
|
|
return &OIDConversion[index];
|
|
}
|
|
} /* end for */
|
|
|
|
return NULL;
|
|
} /* end FindOidByEnum() */
|
|
|
|
__u16 ConvertOidToEnum(const struct asn1Oid * oid, __u16 errorValue)
|
|
{
|
|
const struct asn1OidConvert *convert;
|
|
__u16 enumValue;
|
|
|
|
enumValue = errorValue;
|
|
if (oid->numValues) {
|
|
convert = FindOidByOidValue(oid->numValues - 1, oid->value);
|
|
if (convert) {
|
|
enumValue = FAC_OID_BASE(convert->baseCode) + oid->value[oid->numValues - 1];
|
|
}
|
|
}
|
|
|
|
return enumValue;
|
|
} /* end ConvertOidToEnum() */
|
|
|
|
int ConvertEnumToOid(struct asn1Oid *oid, __u16 enumValue)
|
|
{
|
|
int status;
|
|
const struct asn1OidConvert *convert;
|
|
|
|
status = 0; /* Assume failure */
|
|
convert = FindOidByEnum(enumValue);
|
|
if (convert) {
|
|
*oid = convert->oid;
|
|
if (oid->numValues < sizeof(oid->value) / sizeof(oid->value[0])) {
|
|
oid->value[oid->numValues] = enumValue - FAC_OID_BASE(convert->baseCode);
|
|
++oid->numValues;
|
|
status = 1; /* successful */
|
|
}
|
|
}
|
|
|
|
return status;
|
|
} /* end ConvertEnumToOid() */
|
|
|
|
static int ParseOperationOid(struct asn1_parm *pc, u_char * p, u_char * end, unsigned int *operationValue)
|
|
{
|
|
struct asn1Oid operationOid;
|
|
int rval;
|
|
|
|
CallASN1(rval, p, end, ParseOid(pc, p, end, &operationOid));
|
|
*operationValue = ConvertOidToEnum(&operationOid, Fac_None);
|
|
|
|
return rval;
|
|
} /* end ParseOperationOid() */
|
|
|
|
static int ParseOperationValue(struct asn1_parm *pc, u_char * p, u_char * end, unsigned int *operationValue)
|
|
{
|
|
INIT;
|
|
|
|
XCHOICE_1(ParseUnsignedInteger, ASN1_TAG_INTEGER, ASN1_NOT_TAGGED, operationValue);
|
|
XCHOICE_1(ParseOperationOid, ASN1_TAG_OBJECT_IDENTIFIER, ASN1_NOT_TAGGED, operationValue);
|
|
XCHOICE_DEFAULT;
|
|
}
|
|
|
|
static int ParseInvokeComponent(struct asn1_parm *pc, u_char * p, u_char * end, int dummy)
|
|
{
|
|
signed int invokeId;
|
|
signed int linkedId;
|
|
unsigned int operationValue;
|
|
INIT;
|
|
|
|
pc->comp = CompInvoke;
|
|
XSEQUENCE_1(ParseSignedInteger, ASN1_TAG_INTEGER, ASN1_NOT_TAGGED, &invokeId);
|
|
pc->u.inv.invokeId = invokeId;
|
|
XSEQUENCE_OPT_1(ParseSignedInteger, ASN1_TAG_CONTEXT_SPECIFIC, 0, &linkedId);
|
|
XSEQUENCE_1(ParseOperationValue, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &operationValue);
|
|
pc->u.inv.operationValue = operationValue;
|
|
|
|
switch (operationValue) {
|
|
/* Diversion support */
|
|
case Fac_Begin3PTY:
|
|
case Fac_End3PTY:
|
|
/* No additional invoke parameters */
|
|
break;
|
|
case Fac_ActivationDiversion:
|
|
XSEQUENCE_1(ParseActivationDiversion, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &pc->u.inv.o.ActivationDiversion);
|
|
break;
|
|
case Fac_DeactivationDiversion:
|
|
XSEQUENCE_1(ParseDeactivationDiversion, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &pc->u.inv.o.DeactivationDiversion);
|
|
break;
|
|
case Fac_ActivationStatusNotificationDiv:
|
|
XSEQUENCE_1(ParseActivationStatusNotificationDiv, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED,
|
|
&pc->u.inv.o.ActivationStatusNotificationDiv);
|
|
break;
|
|
case Fac_DeactivationStatusNotificationDiv:
|
|
XSEQUENCE_1(ParseDeactivationStatusNotificationDiv, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED,
|
|
&pc->u.inv.o.DeactivationStatusNotificationDiv);
|
|
break;
|
|
case Fac_InterrogationDiversion:
|
|
XSEQUENCE_1(ParseInterrogationDiversion, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED,
|
|
&pc->u.inv.o.InterrogationDiversion);
|
|
break;
|
|
case Fac_DiversionInformation:
|
|
XSEQUENCE_1(ParseDiversionInformation, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &pc->u.inv.o.DiversionInformation);
|
|
break;
|
|
case Fac_CallDeflection:
|
|
XSEQUENCE_1(ParseCallDeflection, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &pc->u.inv.o.CallDeflection);
|
|
break;
|
|
case Fac_CallRerouteing:
|
|
XSEQUENCE_1(ParseCallRerouteing, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &pc->u.inv.o.CallRerouteing);
|
|
break;
|
|
case Fac_InterrogateServedUserNumbers:
|
|
/* No additional invoke parameters */
|
|
break;
|
|
case Fac_DivertingLegInformation1:
|
|
XSEQUENCE_1(ParseDivertingLegInformation1, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED,
|
|
&pc->u.inv.o.DivertingLegInformation1);
|
|
break;
|
|
case Fac_DivertingLegInformation2:
|
|
XSEQUENCE_1(ParseDivertingLegInformation2, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED,
|
|
&pc->u.inv.o.DivertingLegInformation2);
|
|
break;
|
|
case Fac_DivertingLegInformation3:
|
|
XSEQUENCE_1(ParseDivertingLegInformation3, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED,
|
|
&pc->u.inv.o.DivertingLegInformation3);
|
|
break;
|
|
|
|
/* ECT support */
|
|
case Fac_EctExecute:
|
|
/* No additional invoke parameters */
|
|
break;
|
|
case Fac_ExplicitEctExecute:
|
|
XSEQUENCE_1(ParseExplicitEctExecute, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &pc->u.inv.o.ExplicitEctExecute);
|
|
break;
|
|
case Fac_RequestSubaddress:
|
|
/* No additional invoke parameters */
|
|
break;
|
|
case Fac_SubaddressTransfer:
|
|
XSEQUENCE_1(ParseSubaddressTransfer, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &pc->u.inv.o.SubaddressTransfer);
|
|
break;
|
|
case Fac_EctLinkIdRequest:
|
|
/* No additional invoke parameters */
|
|
break;
|
|
case Fac_EctInform:
|
|
XSEQUENCE_1(ParseEctInform, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &pc->u.inv.o.EctInform);
|
|
break;
|
|
case Fac_EctLoopTest:
|
|
XSEQUENCE_1(ParseEctLoopTest, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &pc->u.inv.o.EctLoopTest);
|
|
break;
|
|
|
|
/* AOC support */
|
|
#if 0
|
|
case Fac_ChargingRequest:
|
|
case Fac_AOCSCurrency:
|
|
case Fac_AOCSSpecialArr:
|
|
break;
|
|
#endif
|
|
case Fac_AOCDCurrency:
|
|
XSEQUENCE_1(ParseAOCDCurrency, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &pc->u.inv.o.AOCcur);
|
|
break;
|
|
case Fac_AOCDChargingUnit:
|
|
XSEQUENCE_1(ParseAOCDChargingUnit, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &pc->u.inv.o.AOCchu);
|
|
break;
|
|
case Fac_AOCECurrency:
|
|
XSEQUENCE_1(ParseAOCECurrency, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &pc->u.inv.o.AOCcur);
|
|
break;
|
|
case Fac_AOCEChargingUnit:
|
|
XSEQUENCE_1(ParseAOCEChargingUnit, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &pc->u.inv.o.AOCchu);
|
|
break;
|
|
case Fac_StatusRequest:
|
|
XSEQUENCE_1(ParseStatusRequest, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &pc->u.inv.o.StatusRequest);
|
|
break;
|
|
|
|
/* CCBS/CCNR support */
|
|
case Fac_CallInfoRetain:
|
|
XSEQUENCE_1(ParseCallInfoRetain, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &pc->u.inv.o.CallInfoRetain);
|
|
break;
|
|
case Fac_CCBSRequest:
|
|
XSEQUENCE_1(ParseCCBSRequest, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &pc->u.inv.o.CCBSRequest);
|
|
break;
|
|
case Fac_CCBSDeactivate:
|
|
XSEQUENCE_1(ParseCCBSDeactivate, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &pc->u.inv.o.CCBSDeactivate);
|
|
break;
|
|
case Fac_CCBSInterrogate:
|
|
XSEQUENCE_1(ParseCCBSInterrogate, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &pc->u.inv.o.CCBSInterrogate);
|
|
break;
|
|
case Fac_CCBSErase:
|
|
XSEQUENCE_1(ParseCCBSErase, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &pc->u.inv.o.CCBSErase);
|
|
break;
|
|
case Fac_CCBSRemoteUserFree:
|
|
XSEQUENCE_1(ParseCCBSRemoteUserFree, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &pc->u.inv.o.CCBSRemoteUserFree);
|
|
break;
|
|
case Fac_CCBSCall:
|
|
XSEQUENCE_1(ParseCCBSCall, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &pc->u.inv.o.CCBSCall);
|
|
break;
|
|
case Fac_CCBSStatusRequest:
|
|
XSEQUENCE_1(ParseCCBSStatusRequest, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &pc->u.inv.o.CCBSStatusRequest);
|
|
break;
|
|
case Fac_CCBSBFree:
|
|
XSEQUENCE_1(ParseCCBSBFree, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &pc->u.inv.o.CCBSBFree);
|
|
break;
|
|
case Fac_EraseCallLinkageID:
|
|
XSEQUENCE_1(ParseEraseCallLinkageID, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &pc->u.inv.o.EraseCallLinkageID);
|
|
break;
|
|
case Fac_CCBSStopAlerting:
|
|
XSEQUENCE_1(ParseCCBSStopAlerting, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &pc->u.inv.o.CCBSStopAlerting);
|
|
break;
|
|
case Fac_CCNRRequest:
|
|
XSEQUENCE_1(ParseCCNRRequest, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &pc->u.inv.o.CCNRRequest);
|
|
break;
|
|
case Fac_CCNRInterrogate:
|
|
XSEQUENCE_1(ParseCCNRInterrogate, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &pc->u.inv.o.CCNRInterrogate);
|
|
break;
|
|
|
|
/* CCBS-T/CCNR-T support */
|
|
case Fac_CCBS_T_Call:
|
|
case Fac_CCBS_T_Suspend:
|
|
case Fac_CCBS_T_Resume:
|
|
case Fac_CCBS_T_RemoteUserFree:
|
|
case Fac_CCBS_T_Available:
|
|
/* No additional invoke parameters */
|
|
break;
|
|
case Fac_CCBS_T_Request:
|
|
XSEQUENCE_1(ParseCCBS_T_Request, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &pc->u.inv.o.CCBS_T_Request);
|
|
break;
|
|
case Fac_CCNR_T_Request:
|
|
XSEQUENCE_1(ParseCCNR_T_Request, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &pc->u.inv.o.CCNR_T_Request);
|
|
break;
|
|
|
|
default:
|
|
return -1;
|
|
}
|
|
|
|
return p - beg;
|
|
}
|
|
|
|
int ParseReturnResultComponentSequence(struct asn1_parm *pc, u_char * p, u_char * end, int dummy)
|
|
{
|
|
INIT;
|
|
|
|
XSEQUENCE_1(ParseOperationValue, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &pc->u.retResult.operationValue);
|
|
pc->u.retResult.operationValuePresent = 1;
|
|
|
|
switch (pc->u.retResult.operationValue) {
|
|
/* 3PTY */
|
|
case Fac_Begin3PTY:
|
|
case Fac_End3PTY:
|
|
/* No additional result parameters */
|
|
break;
|
|
/* Diversion support */
|
|
case Fac_ActivationDiversion:
|
|
case Fac_DeactivationDiversion:
|
|
/* No additional result parameters */
|
|
break;
|
|
case Fac_InterrogationDiversion:
|
|
XSEQUENCE_1(ParseInterrogationDiversion_RES, ASN1_TAG_SET, ASN1_NOT_TAGGED,
|
|
&pc->u.retResult.o.InterrogationDiversion);
|
|
break;
|
|
case Fac_CallDeflection:
|
|
case Fac_CallRerouteing:
|
|
/* No additional result parameters */
|
|
break;
|
|
case Fac_InterrogateServedUserNumbers:
|
|
XSEQUENCE_1(ParseInterrogateServedUserNumbers_RES, ASN1_TAG_SET, ASN1_NOT_TAGGED,
|
|
&pc->u.retResult.o.InterrogateServedUserNumbers);
|
|
break;
|
|
|
|
/* ECT support */
|
|
case Fac_EctLinkIdRequest:
|
|
XSEQUENCE_1(ParseEctLinkIdRequest_RES, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &pc->u.retResult.o.EctLinkIdRequest);
|
|
break;
|
|
case Fac_EctLoopTest:
|
|
XSEQUENCE_1(ParseEctLoopTest_RES, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &pc->u.retResult.o.EctLoopTest);
|
|
break;
|
|
|
|
case Fac_StatusRequest:
|
|
XSEQUENCE_1(ParseStatusRequest_RES, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &pc->u.retResult.o.StatusRequest);
|
|
break;
|
|
|
|
/* CCBS/CCNR support */
|
|
case Fac_CCBSDeactivate:
|
|
/* No additional result parameters */
|
|
break;
|
|
case Fac_CCBSStatusRequest:
|
|
XSEQUENCE_1(ParseCCBSStatusRequest_RES, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &pc->u.retResult.o.CCBSStatusRequest);
|
|
break;
|
|
case Fac_CCBSRequest:
|
|
XSEQUENCE_1(ParseCCBSRequest_RES, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &pc->u.retResult.o.CCBSRequest);
|
|
break;
|
|
case Fac_CCBSInterrogate:
|
|
XSEQUENCE_1(ParseCCBSInterrogate_RES, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &pc->u.retResult.o.CCBSInterrogate);
|
|
break;
|
|
case Fac_CCNRRequest:
|
|
XSEQUENCE_1(ParseCCNRRequest_RES, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &pc->u.retResult.o.CCNRRequest);
|
|
break;
|
|
case Fac_CCNRInterrogate:
|
|
XSEQUENCE_1(ParseCCNRInterrogate_RES, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &pc->u.retResult.o.CCNRInterrogate);
|
|
break;
|
|
|
|
/* CCBS-T/CCNR-T support */
|
|
case Fac_CCBS_T_Request:
|
|
XSEQUENCE_1(ParseCCBS_T_Request_RES, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &pc->u.retResult.o.CCBS_T_Request);
|
|
break;
|
|
case Fac_CCNR_T_Request:
|
|
XSEQUENCE_1(ParseCCNR_T_Request_RES, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &pc->u.retResult.o.CCNR_T_Request);
|
|
break;
|
|
|
|
default:
|
|
return -1;
|
|
}
|
|
|
|
return p - beg;
|
|
}
|
|
|
|
static int ParseReturnResultComponent(struct asn1_parm *pc, u_char * p, u_char * end, int dummy)
|
|
{
|
|
signed int invokeId;
|
|
INIT;
|
|
|
|
pc->comp = CompReturnResult;
|
|
XSEQUENCE_1(ParseSignedInteger, ASN1_TAG_INTEGER, ASN1_NOT_TAGGED, &invokeId);
|
|
pc->u.retResult.invokeId = invokeId;
|
|
pc->u.retResult.operationValuePresent = 0;
|
|
XSEQUENCE_OPT(ParseReturnResultComponentSequence, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED);
|
|
|
|
return p - beg;
|
|
}
|
|
|
|
static int ParseErrorOid(struct asn1_parm *pc, u_char * p, u_char * end, unsigned int *errorValue)
|
|
{
|
|
struct asn1Oid errorOid;
|
|
int rval;
|
|
|
|
CallASN1(rval, p, end, ParseOid(pc, p, end, &errorOid));
|
|
*errorValue = ConvertOidToEnum(&errorOid, FacError_Unknown);
|
|
|
|
return rval;
|
|
} /* end ParseErrorOid() */
|
|
|
|
static int ParseErrorValue(struct asn1_parm *pc, u_char * p, u_char * end, unsigned int *errorValue)
|
|
{
|
|
INIT;
|
|
|
|
XCHOICE_1(ParseUnsignedInteger, ASN1_TAG_INTEGER, ASN1_NOT_TAGGED, errorValue);
|
|
XCHOICE_1(ParseErrorOid, ASN1_TAG_OBJECT_IDENTIFIER, ASN1_NOT_TAGGED, errorValue);
|
|
XCHOICE_DEFAULT;
|
|
}
|
|
|
|
int ParseReturnErrorComponent(struct asn1_parm *pc, u_char * p, u_char * end, int dummy)
|
|
{
|
|
int invokeId;
|
|
unsigned int errorValue;
|
|
const char *error;
|
|
char msg[20];
|
|
INIT;
|
|
|
|
pc->comp = CompReturnError;
|
|
|
|
XSEQUENCE_1(ParseSignedInteger, ASN1_TAG_INTEGER, ASN1_NOT_TAGGED, &invokeId);
|
|
XSEQUENCE_1(ParseErrorValue, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &errorValue);
|
|
|
|
pc->u.retError.invokeId = invokeId;
|
|
pc->u.retError.errorValue = errorValue;
|
|
|
|
switch (errorValue) {
|
|
case FacError_Gen_NotSubscribed:
|
|
error = "not subscribed";
|
|
break;
|
|
case FacError_Gen_NotAvailable:
|
|
error = "not available";
|
|
break;
|
|
case FacError_Gen_NotImplemented:
|
|
error = "not implemented";
|
|
break;
|
|
case FacError_Gen_InvalidServedUserNr:
|
|
error = "invalid served user nr";
|
|
break;
|
|
case FacError_Gen_InvalidCallState:
|
|
error = "invalid call state";
|
|
break;
|
|
case FacError_Gen_BasicServiceNotProvided:
|
|
error = "basic service not provided";
|
|
break;
|
|
case FacError_Gen_NotIncomingCall:
|
|
error = "not incoming call";
|
|
break;
|
|
case FacError_Gen_SupplementaryServiceInteractionNotAllowed:
|
|
error = "supplementary service interaction not allowed";
|
|
break;
|
|
case FacError_Gen_ResourceUnavailable:
|
|
error = "resource unavailable";
|
|
break;
|
|
case FacError_Div_InvalidDivertedToNr:
|
|
error = "invalid diverted-to nr";
|
|
break;
|
|
case FacError_Div_SpecialServiceNr:
|
|
error = "special service nr";
|
|
break;
|
|
case FacError_Div_DiversionToServedUserNr:
|
|
error = "diversion to served user nr";
|
|
break;
|
|
case FacError_Div_IncomingCallAccepted:
|
|
error = "incoming call accepted";
|
|
break;
|
|
case FacError_Div_NumberOfDiversionsExceeded:
|
|
error = "number of diversions exceeded";
|
|
break;
|
|
case FacError_Div_NotActivated:
|
|
error = "not activated";
|
|
break;
|
|
case FacError_Div_RequestAlreadyAccepted:
|
|
error = "request already accepted";
|
|
break;
|
|
case FacError_AOC_NoChargingInfoAvailable:
|
|
error = "no charging info available";
|
|
break;
|
|
case FacError_CCBS_InvalidCallLinkageID:
|
|
error = "invalid call linkage id";
|
|
break;
|
|
case FacError_CCBS_InvalidCCBSReference:
|
|
error = "invalid ccbs reference";
|
|
break;
|
|
case FacError_CCBS_T_LongTermDenial:
|
|
case FacError_CCBS_LongTermDenial:
|
|
error = "long term denial";
|
|
break;
|
|
case FacError_CCBS_T_ShortTermDenial:
|
|
case FacError_CCBS_ShortTermDenial:
|
|
error = "short term denial";
|
|
break;
|
|
case FacError_CCBS_IsAlreadyActivated:
|
|
error = "ccbs is already activated";
|
|
break;
|
|
case FacError_CCBS_AlreadyAccepted:
|
|
error = "already accepted";
|
|
break;
|
|
case FacError_CCBS_OutgoingCCBSQueueFull:
|
|
error = "outgoing ccbs queue full";
|
|
break;
|
|
case FacError_CCBS_CallFailureReasonNotBusy:
|
|
error = "call failure reason not busy";
|
|
break;
|
|
case FacError_CCBS_NotReadyForCall:
|
|
error = "not ready for call";
|
|
break;
|
|
case FacError_Unknown:
|
|
error = "unknown OID error code";
|
|
break;
|
|
default:
|
|
sprintf(msg, "(%d)", errorValue);
|
|
error = msg;
|
|
break;
|
|
}
|
|
dprint(DBGM_ASN1_DEC, "Decoded-Error: %s\n", error);
|
|
return p - beg;
|
|
} /* end of ParseReturnErrorComponent() */
|
|
|
|
int ParseProblemValue(struct asn1_parm *pc, u_char * p, u_char * end, asn1Problem prob)
|
|
{
|
|
int rval;
|
|
|
|
pc->u.reject.problem = prob;
|
|
rval = ParseUnsignedInteger(pc, p, end, &pc->u.reject.problemValue);
|
|
dprint(DBGM_ASN1_DEC, "ParseProblemValue: %d %d, rval:%d\n", prob, pc->u.reject.problemValue, rval);
|
|
|
|
return rval;
|
|
}
|
|
|
|
int ParseRejectProblem(struct asn1_parm *pc, u_char * p, u_char * end, int dummy)
|
|
{
|
|
INIT;
|
|
|
|
XCHOICE_1(ParseProblemValue, ASN1_TAG_CONTEXT_SPECIFIC, 0, GeneralP);
|
|
XCHOICE_1(ParseProblemValue, ASN1_TAG_CONTEXT_SPECIFIC, 1, InvokeP);
|
|
XCHOICE_1(ParseProblemValue, ASN1_TAG_CONTEXT_SPECIFIC, 2, ReturnResultP);
|
|
XCHOICE_1(ParseProblemValue, ASN1_TAG_CONTEXT_SPECIFIC, 3, ReturnErrorP);
|
|
XCHOICE_DEFAULT;
|
|
}
|
|
|
|
static int ParseRejectInvokeId(struct asn1_parm *pc, u_char * p, u_char * end, int dummy)
|
|
{
|
|
INIT;
|
|
|
|
pc->u.reject.invokeIdPresent = 1;
|
|
XCHOICE_1(ParseSignedInteger, ASN1_TAG_INTEGER, ASN1_NOT_TAGGED, &pc->u.reject.invokeId);
|
|
|
|
pc->u.reject.invokeIdPresent = 0;
|
|
pc->u.reject.invokeId = 0;
|
|
XCHOICE(ParseNull, ASN1_TAG_NULL, ASN1_NOT_TAGGED);
|
|
|
|
XCHOICE_DEFAULT;
|
|
}
|
|
|
|
int ParseRejectComponent(struct asn1_parm *pc, u_char * p, u_char * end, int dummy)
|
|
{
|
|
INIT;
|
|
|
|
pc->comp = CompReject;
|
|
|
|
XSEQUENCE(ParseRejectInvokeId, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED);
|
|
if (pc->u.reject.invokeIdPresent) {
|
|
dprint(DBGM_ASN1_DEC, "ParseRejectComponent: invokeId %d\n", pc->u.reject.invokeId);
|
|
}
|
|
|
|
XSEQUENCE(ParseRejectProblem, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED);
|
|
|
|
return p - beg;
|
|
}
|
|
|
|
int ParseComponent(struct asn1_parm *pc, u_char * p, u_char * end)
|
|
{
|
|
INIT;
|
|
|
|
XCHOICE(ParseInvokeComponent, ASN1_TAG_CONTEXT_SPECIFIC | ASN1_TAG_CONSTRUCTED, 1);
|
|
XCHOICE(ParseReturnResultComponent, ASN1_TAG_CONTEXT_SPECIFIC | ASN1_TAG_CONSTRUCTED, 2);
|
|
XCHOICE(ParseReturnErrorComponent, ASN1_TAG_CONTEXT_SPECIFIC | ASN1_TAG_CONSTRUCTED, 3);
|
|
XCHOICE(ParseRejectComponent, ASN1_TAG_CONTEXT_SPECIFIC | ASN1_TAG_CONSTRUCTED, 4);
|
|
XCHOICE_DEFAULT;
|
|
}
|