New supplementary services implementation
Signed-off-by: Karsten Keil <kkeil@linux-pingi.de>
This commit is contained in:
parent
45a0d3b856
commit
4b4f5931c9
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,8 @@
|
|||
lib_LTLIBRARIES = libsuppserv.la
|
||||
libsuppserv_la_SOURCES = asn1.c asn1_enc.c asn1_generic.c asn1_aoc.c asn1_basic_service.c asn1_comp.c asn1_diversion.c asn1_address.c fac.c asn1_diversion.h asn1.h
|
||||
libsuppserv_la_LDFLAGS = -version-info 1:1:1
|
||||
libsuppserv_la_SOURCES = asn1.c asn1_enc.c asn1_generic.c asn1_aoc.c asn1_basic_service.c asn1_comp.c \
|
||||
asn1_diversion.c asn1_address.c asn1_ccbs.c asn1_ccbs.h fac.c asn1_diversion.h \
|
||||
asn1_ect.c asn1_ect.h asn1.h
|
||||
libsuppserv_la_LDFLAGS = -version-info 2:0:0
|
||||
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
/* $Id: asn1.c,v 1.2 2006/08/16 13:14:54 nadi Exp $
|
||||
/* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
#include "asn1.h"
|
||||
|
||||
int ParseTag(u_char *p, u_char *end, int *tag)
|
||||
int ParseTag(u_char * p, u_char * end, int *tag)
|
||||
{
|
||||
*tag = *p;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ParseLen(u_char *p, u_char *end, int *len)
|
||||
int ParseLen(u_char * p, u_char * end, int *len)
|
||||
{
|
||||
int l, i;
|
||||
|
||||
if (*p == 0x80) { // indefinite
|
||||
if (*p == 0x80) { // indefinite
|
||||
*len = -1;
|
||||
return 1;
|
||||
}
|
||||
if (!(*p & 0x80)) { // one byte
|
||||
if (!(*p & 0x80)) { // one byte
|
||||
*len = *p;
|
||||
return 1;
|
||||
}
|
||||
|
@ -26,15 +26,14 @@ int ParseLen(u_char *p, u_char *end, int *len)
|
|||
l = *p & ~0x80;
|
||||
p++;
|
||||
for (i = 0; i < l; i++) {
|
||||
*len = (*len << 8) + *p;
|
||||
*len = (*len << 8) + *p;
|
||||
p++;
|
||||
}
|
||||
return l+1;
|
||||
return l + 1;
|
||||
}
|
||||
|
||||
#ifdef ASN1_DEBUG
|
||||
int
|
||||
ParseASN1(u_char *p, u_char *end, int level)
|
||||
int ParseASN1(u_char * p, u_char * end, int level)
|
||||
{
|
||||
int tag, len;
|
||||
int ret;
|
||||
|
@ -45,36 +44,37 @@ ParseASN1(u_char *p, u_char *end, int level)
|
|||
|
||||
CallASN1(ret, p, end, ParseTag(p, end, &tag));
|
||||
CallASN1(ret, p, end, ParseLen(p, end, &len));
|
||||
#ifdef ASN1_DEBUG
|
||||
for (j = 0; j < level*5; j++) print_asn1msg(PRT_DEBUG_DECODE, " ");
|
||||
for (j = 0; j < level * 5; j++)
|
||||
print_asn1msg(PRT_DEBUG_DECODE, " ");
|
||||
print_asn1msg(PRT_DEBUG_DECODE, "TAG 0x%02x LEN %3d\n", tag, len);
|
||||
#endif
|
||||
|
||||
|
||||
if (tag & ASN1_TAG_CONSTRUCTED) {
|
||||
if (len == -1) { // indefinite
|
||||
if (len == -1) { // indefinite
|
||||
while (*p) {
|
||||
CallASN1(ret, p, end, ParseASN1(p, end, level + 1));
|
||||
}
|
||||
p++;
|
||||
if (*p)
|
||||
if (*p)
|
||||
return -1;
|
||||
p++;
|
||||
} else {
|
||||
tag_end = p + len;
|
||||
while (p < tag_end) {
|
||||
CallASN1(ret, p, end, ParseASN1(p, end, level +1));
|
||||
CallASN1(ret, p, end, ParseASN1(p, end, level + 1));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (j = 0; j < level*5; j++) print_asn1msg(PRT_DEBUG_DECODE, " ");
|
||||
for (j = 0; j < level * 5; j++)
|
||||
print_asn1msg(PRT_DEBUG_DECODE, " ");
|
||||
while (len--) {
|
||||
print_asn1msg(PRT_DEBUG_DECODE, "%02x ", *p);
|
||||
p++;
|
||||
}
|
||||
print_asn1msg(PRT_DEBUG_DECODE, "\n");
|
||||
}
|
||||
for (j = 0; j < level*5; j++) print_asn1msg(PRT_DEBUG_DECODE, " ");
|
||||
print_asn1msg(PRT_DEBUG_DECODE, "END (%d)\n", p - beg - 2);
|
||||
for (j = 0; j < level * 5; j++)
|
||||
print_asn1msg(PRT_DEBUG_DECODE, " ");
|
||||
print_asn1msg(PRT_DEBUG_DECODE, "END (%ld)\n", p - beg - 2);
|
||||
return p - beg;
|
||||
}
|
||||
#endif
|
||||
|
|
628
suppserv/asn1.h
628
suppserv/asn1.h
|
@ -1,3 +1,9 @@
|
|||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Abstract Syntax Notation.1 (ASN.1) ITU-T X.208
|
||||
*/
|
||||
|
||||
#ifndef __ASN1_H__
|
||||
#define __ASN1_H__
|
||||
|
||||
|
@ -6,220 +12,270 @@
|
|||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef enum {
|
||||
invoke = 1,
|
||||
returnResult = 2,
|
||||
returnError = 3,
|
||||
reject = 4,
|
||||
} asn1Component;
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
GeneralP = 0,
|
||||
InvokeP = 1,
|
||||
ReturnResultP= 2,
|
||||
ReturnErrorP = 3,
|
||||
} asn1Problem;
|
||||
/* ------------------------------------------------------------------- */
|
||||
|
||||
struct PublicPartyNumber {
|
||||
int publicTypeOfNumber;
|
||||
char numberDigits[30];
|
||||
};
|
||||
typedef enum {
|
||||
invoke = 1,
|
||||
returnResult = 2,
|
||||
returnError = 3,
|
||||
reject = 4,
|
||||
} asn1Component;
|
||||
|
||||
struct PartyNumber {
|
||||
int type;
|
||||
union {
|
||||
char unknown[30];
|
||||
struct PublicPartyNumber publicPartyNumber;
|
||||
} p;
|
||||
};
|
||||
typedef enum {
|
||||
GeneralP = 0,
|
||||
InvokeP = 1,
|
||||
ReturnResultP = 2,
|
||||
ReturnErrorP = 3,
|
||||
} asn1Problem;
|
||||
|
||||
struct Address {
|
||||
struct PartyNumber partyNumber;
|
||||
char partySubaddress[30];
|
||||
};
|
||||
struct ChargeNumber {
|
||||
char *number;
|
||||
int *identifier;
|
||||
};
|
||||
|
||||
struct ServedUserNr {
|
||||
int all;
|
||||
struct PartyNumber partyNumber;
|
||||
};
|
||||
struct asn1Invoke {
|
||||
__s16 invokeId;
|
||||
__u16 operationValue;
|
||||
union {
|
||||
struct FacAOCChargingUnit AOCchu;
|
||||
struct FacAOCCurrency AOCcur;
|
||||
|
||||
struct ActDivNotification {
|
||||
int procedure;
|
||||
int basicService;
|
||||
struct ServedUserNr servedUserNr;
|
||||
struct Address address;
|
||||
};
|
||||
struct FacStatusRequest_ARG StatusRequest;
|
||||
|
||||
struct DeactDivNotification {
|
||||
int procedure;
|
||||
int basicService;
|
||||
struct ServedUserNr servedUserNr;
|
||||
};
|
||||
/* CCBS/CCNR support */
|
||||
struct FacCallInfoRetain CallInfoRetain;
|
||||
struct FacEraseCallLinkageID EraseCallLinkageID;
|
||||
struct FacCCBSDeactivate_ARG CCBSDeactivate;
|
||||
struct FacCCBSErase CCBSErase;
|
||||
struct FacCCBSRemoteUserFree CCBSRemoteUserFree;
|
||||
struct FacCCBSCall CCBSCall;
|
||||
struct FacCCBSStatusRequest_ARG CCBSStatusRequest;
|
||||
struct FacCCBSBFree CCBSBFree;
|
||||
struct FacCCBSStopAlerting CCBSStopAlerting;
|
||||
|
||||
struct ReqCallDeflection {
|
||||
struct Address address;
|
||||
int pres;
|
||||
};
|
||||
/* CCBS support */
|
||||
struct FacCCBSRequest_ARG CCBSRequest;
|
||||
struct FacCCBSInterrogate_ARG CCBSInterrogate;
|
||||
|
||||
struct ServedUserNumberList {
|
||||
struct PartyNumber partyNumber[10];
|
||||
};
|
||||
/* CCNR support */
|
||||
struct FacCCBSRequest_ARG CCNRRequest;
|
||||
struct FacCCBSInterrogate_ARG CCNRInterrogate;
|
||||
|
||||
struct IntResult {
|
||||
struct ServedUserNr servedUserNr;
|
||||
int procedure;
|
||||
int basicService;
|
||||
struct Address address;
|
||||
};
|
||||
/* CCBS-T support */
|
||||
struct FacCCBS_T_Request_ARG CCBS_T_Request;
|
||||
|
||||
struct IntResultList {
|
||||
struct IntResult intResult[10];
|
||||
};
|
||||
/* CCNR-T support */
|
||||
struct FacCCBS_T_Request_ARG CCNR_T_Request;
|
||||
|
||||
struct asn1Invoke {
|
||||
__u16 invokeId;
|
||||
__u16 operationValue;
|
||||
union {
|
||||
struct ActDivNotification actNot;
|
||||
struct DeactDivNotification deactNot;
|
||||
struct ReqCallDeflection reqCD;
|
||||
struct FacAOCDChargingUnit AOCDchu;
|
||||
struct FacAOCDCurrency AOCDcur;
|
||||
} o;
|
||||
};
|
||||
/* ECT support */
|
||||
struct FacExplicitEctExecute ExplicitEctExecute;
|
||||
struct FacSubaddressTransfer SubaddressTransfer;
|
||||
struct FacEctInform EctInform;
|
||||
struct FacEctLoopTest_ARG EctLoopTest;
|
||||
|
||||
struct asn1ReturnResult {
|
||||
__u16 invokeId;
|
||||
union {
|
||||
struct ServedUserNumberList list;
|
||||
struct IntResultList resultList;
|
||||
} o;
|
||||
};
|
||||
/* Diversion support */
|
||||
struct FacActivationDiversion_ARG ActivationDiversion;
|
||||
struct FacDeactivationDiversion_ARG DeactivationDiversion;
|
||||
struct FacActivationStatusNotificationDiv ActivationStatusNotificationDiv;
|
||||
struct FacDeactivationStatusNotificationDiv DeactivationStatusNotificationDiv;
|
||||
struct FacInterrogationDiversion_ARG InterrogationDiversion;
|
||||
struct FacDiversionInformation DiversionInformation;
|
||||
struct FacCallDeflection_ARG CallDeflection;
|
||||
struct FacCallRerouteing_ARG CallRerouteing;
|
||||
struct FacDivertingLegInformation1 DivertingLegInformation1;
|
||||
struct FacDivertingLegInformation2 DivertingLegInformation2;
|
||||
struct FacDivertingLegInformation3 DivertingLegInformation3;
|
||||
} o;
|
||||
};
|
||||
|
||||
struct asn1ReturnError {
|
||||
__u16 invokeId;
|
||||
__u16 errorValue;
|
||||
};
|
||||
struct asn1ReturnResult {
|
||||
__s16 invokeId;
|
||||
int operationValuePresent;
|
||||
int operationValue;
|
||||
union {
|
||||
struct FacStatusRequest_RES StatusRequest;
|
||||
|
||||
struct asn1Reject {
|
||||
int invokeId;
|
||||
asn1Problem problem;
|
||||
__u16 problemValue;
|
||||
};
|
||||
/* CCBS/CCNR support */
|
||||
struct FacCCBSStatusRequest_RES CCBSStatusRequest;
|
||||
|
||||
struct asn1_parm {
|
||||
asn1Component comp;
|
||||
union {
|
||||
struct asn1Invoke inv;
|
||||
struct asn1ReturnResult retResult;
|
||||
struct asn1ReturnError retError;
|
||||
struct asn1Reject reject;
|
||||
} u;
|
||||
};
|
||||
/* CCBS support */
|
||||
struct FacCCBSRequest_RES CCBSRequest;
|
||||
struct FacCCBSInterrogate_RES CCBSInterrogate;
|
||||
|
||||
/* CCNR support */
|
||||
struct FacCCBSRequest_RES CCNRRequest;
|
||||
struct FacCCBSInterrogate_RES CCNRInterrogate;
|
||||
|
||||
/* CCBS-T support */
|
||||
struct FacCCBS_T_Request_RES CCBS_T_Request;
|
||||
|
||||
/* CCNR-T support */
|
||||
struct FacCCBS_T_Request_RES CCNR_T_Request;
|
||||
|
||||
/* ECT support */
|
||||
struct FacEctLinkIdRequest_RES EctLinkIdRequest;
|
||||
struct FacEctLoopTest_RES EctLoopTest;
|
||||
|
||||
/* Diversion support */
|
||||
struct FacForwardingList InterrogationDiversion;
|
||||
struct FacServedUserNumberList InterrogateServedUserNumbers;
|
||||
} o;
|
||||
};
|
||||
|
||||
struct asn1Oid {
|
||||
/* Number of subidentifier values in OID list */
|
||||
__u16 numValues;
|
||||
|
||||
/*
|
||||
* OID subidentifier value list
|
||||
* Note the first value is really the first two OID subidentifiers.
|
||||
* They are compressed using this formula:
|
||||
* First_Value = (First_Subidentifier * 40) + Second_Subidentifier
|
||||
*/
|
||||
__u16 value[10];
|
||||
};
|
||||
|
||||
struct asn1OidConvert {
|
||||
enum FacOIDBase baseCode;
|
||||
struct asn1Oid oid;
|
||||
};
|
||||
|
||||
struct asn1ReturnError {
|
||||
__s16 invokeId;
|
||||
/*! \see enum FacErrorCode */
|
||||
__u16 errorValue;
|
||||
};
|
||||
|
||||
struct asn1Reject {
|
||||
int invokeIdPresent;
|
||||
int invokeId;
|
||||
asn1Problem problem;
|
||||
int problemValue;
|
||||
};
|
||||
|
||||
struct asn1_parm {
|
||||
asn1Component comp;
|
||||
union {
|
||||
struct asn1Invoke inv;
|
||||
struct asn1ReturnResult retResult;
|
||||
struct asn1ReturnError retError;
|
||||
struct asn1Reject reject;
|
||||
} u;
|
||||
};
|
||||
|
||||
#ifdef ASN1_DEBUG
|
||||
#define print_asn1msg(dummy, fmt, args...) printf(fmt, ## args)
|
||||
int ParseASN1(u_char *p, u_char *end, int level);
|
||||
int ParseASN1(u_char * p, u_char * end, int level);
|
||||
#else
|
||||
#define print_asn1msg(dummy, fmt, args...)
|
||||
#define print_asn1msg(dummy, fmt, args...)
|
||||
#define ParseASN1(p,end,level)
|
||||
#endif
|
||||
|
||||
#define int_error() \
|
||||
printf("mISDN: INTERNAL ERROR in %s:%d\n", \
|
||||
__FILE__, __LINE__)
|
||||
__FILE__, __LINE__)
|
||||
|
||||
int ParseTag(u_char *p, u_char *end, int *tag);
|
||||
int ParseLen(u_char *p, u_char *end, int *len);
|
||||
int ParseTag(u_char * p, u_char * end, int *tag);
|
||||
int ParseLen(u_char * p, u_char * end, int *len);
|
||||
|
||||
#define ASN1_TAG_BOOLEAN (0x01) // is that true?
|
||||
#define ASN1_TAG_INTEGER (0x02)
|
||||
#define ASN1_TAG_BIT_STRING (0x03)
|
||||
#define ASN1_TAG_OCTET_STRING (0x04)
|
||||
#define ASN1_TAG_NULL (0x05)
|
||||
#define ASN1_TAG_OBJECT_IDENTIFIER (0x06)
|
||||
#define ASN1_TAG_ENUM (0x0a)
|
||||
#define ASN1_TAG_SEQUENCE (0x30)
|
||||
#define ASN1_TAG_SET (0x31)
|
||||
#define ASN1_TAG_NUMERIC_STRING (0x12)
|
||||
#define ASN1_TAG_PRINTABLE_STRING (0x13)
|
||||
#define ASN1_TAG_IA5_STRING (0x16)
|
||||
#define ASN1_TAG_UTC_TIME (0x17)
|
||||
#define ASN1_TAG_BOOLEAN 1
|
||||
#define ASN1_TAG_INTEGER 2
|
||||
#define ASN1_TAG_BIT_STRING 3
|
||||
#define ASN1_TAG_OCTET_STRING 4
|
||||
#define ASN1_TAG_NULL 5
|
||||
#define ASN1_TAG_OBJECT_IDENTIFIER 6
|
||||
#define ASN1_TAG_ENUM 10
|
||||
#define ASN1_TAG_SEQUENCE (ASN1_TAG_CONSTRUCTED | 16)
|
||||
#define ASN1_TAG_SET (ASN1_TAG_CONSTRUCTED | 17)
|
||||
#define ASN1_TAG_NUMERIC_STRING 18
|
||||
#define ASN1_TAG_PRINTABLE_STRING 19
|
||||
#define ASN1_TAG_IA5_STRING 22
|
||||
#define ASN1_TAG_UTC_TIME 23
|
||||
|
||||
#define ASN1_TAG_CONSTRUCTED (0x20)
|
||||
#define ASN1_TAG_CONTEXT_SPECIFIC (0x80)
|
||||
#define ASN1_TAG_CONSTRUCTED 0x20
|
||||
|
||||
#define ASN1_TAG_EXPLICIT (0x100)
|
||||
#define ASN1_TAG_OPT (0x200)
|
||||
#define ASN1_NOT_TAGGED (0x400)
|
||||
#define ASN1_TAG_TYPE_MASK 0xC0
|
||||
#define ASN1_TAG_UNIVERSAL 0x00
|
||||
#define ASN1_TAG_APPLICATION_WIDE 0x40
|
||||
#define ASN1_TAG_CONTEXT_SPECIFIC 0x80
|
||||
#define ASN1_TAG_PRIVATE 0xC0
|
||||
|
||||
#define CallASN1(ret, p, end, todo) do { \
|
||||
ret = todo; \
|
||||
if (ret < 0) { \
|
||||
int_error(); \
|
||||
return -1; \
|
||||
} \
|
||||
p += ret; \
|
||||
} while (0)
|
||||
#define ASN1_TAG_EXPLICIT 0x100
|
||||
#define ASN1_TAG_OPT 0x200
|
||||
#define ASN1_NOT_TAGGED 0x400
|
||||
|
||||
#define CallASN1(ret, p, end, todo) \
|
||||
do { \
|
||||
ret = todo; \
|
||||
if (ret < 0) { \
|
||||
int_error(); \
|
||||
return -1; \
|
||||
} \
|
||||
p += ret; \
|
||||
} while (0)
|
||||
|
||||
/* INIT must be placed after the last variable declared */
|
||||
#define INIT \
|
||||
int tag, len; \
|
||||
int ret; \
|
||||
u_char *beg; \
|
||||
\
|
||||
print_asn1msg(PRT_DEBUG_DECODE, " DEBUG> %s\n", __FUNCTION__); \
|
||||
\
|
||||
print_asn1msg(PRT_DEBUG_DECODE, " DEBUG> %s\n", __FUNCTION__); \
|
||||
beg = p; \
|
||||
CallASN1(ret, p, end, ParseTag(p, end, &tag)); \
|
||||
CallASN1(ret, p, end, ParseLen(p, end, &len)); \
|
||||
if (len >= 0) { \
|
||||
if (p + len > end) \
|
||||
return -1; \
|
||||
end = p + len; \
|
||||
}
|
||||
|
||||
#define XSEQUENCE_1(todo, act_tag, the_tag, arg1) do { \
|
||||
if (p < end) { \
|
||||
if (((the_tag) &~ ASN1_TAG_OPT) == ASN1_NOT_TAGGED) { \
|
||||
if (((u_char)act_tag == *p) || ((act_tag) == ASN1_NOT_TAGGED)) { \
|
||||
CallASN1(ret, p, end, todo(pc, p, end, arg1)); \
|
||||
} else { \
|
||||
if (!((the_tag) & ASN1_TAG_OPT)) { \
|
||||
print_asn1msg(PRT_DEBUG_DECODE, " DEBUG> err 1 %s:%d\n", __FUNCTION__, __LINE__); \
|
||||
return -1; \
|
||||
} \
|
||||
} \
|
||||
} else { \
|
||||
if ((the_tag) & ASN1_TAG_EXPLICIT) { \
|
||||
if ((u_char)(((the_tag) & 0xff) | (ASN1_TAG_CONTEXT_SPECIFIC | ASN1_TAG_CONSTRUCTED)) == *p) { \
|
||||
int xtag, xlen; \
|
||||
CallASN1(ret, p, end, ParseTag(p, end, &xtag)); \
|
||||
CallASN1(ret, p, end, ParseLen(p, end, &xlen)); \
|
||||
CallASN1(ret, p, end, todo(pc, p, end, arg1)); \
|
||||
} else { \
|
||||
if (!((the_tag) & ASN1_TAG_OPT)) { \
|
||||
print_asn1msg(PRT_DEBUG_DECODE, " DEBUG> err 2 %s:%d\n", __FUNCTION__, __LINE__); \
|
||||
return -1; \
|
||||
} \
|
||||
} \
|
||||
} else { \
|
||||
if ((u_char)(((the_tag) & 0xff) | (ASN1_TAG_CONTEXT_SPECIFIC | (act_tag & ASN1_TAG_CONSTRUCTED))) == *p) { \
|
||||
CallASN1(ret, p, end, todo(pc, p, end, arg1)); \
|
||||
} else { \
|
||||
if (!((the_tag) & ASN1_TAG_OPT)) { \
|
||||
print_asn1msg(PRT_DEBUG_DECODE, " DEBUG> err 3 %s:%d\n", __FUNCTION__, __LINE__); \
|
||||
return -1; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} else { \
|
||||
if (!((the_tag) & ASN1_TAG_OPT)) { \
|
||||
print_asn1msg(PRT_DEBUG_DECODE, " DEBUG> err 4 %s:%d\n", __FUNCTION__, __LINE__); \
|
||||
if (len >= 0) { \
|
||||
if (p + len > end) \
|
||||
return -1; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
end = p + len; \
|
||||
}
|
||||
|
||||
#define XSEQUENCE_1(todo, act_tag, the_tag, arg1) \
|
||||
do { \
|
||||
if (p < end) { \
|
||||
if (((the_tag) & ~ASN1_TAG_OPT) == ASN1_NOT_TAGGED) { \
|
||||
if (((act_tag) == ASN1_NOT_TAGGED) || ((u_char) (act_tag) == *p)) { \
|
||||
CallASN1(ret, p, end, todo(pc, p, end, arg1)); \
|
||||
} else { \
|
||||
if (!((the_tag) & ASN1_TAG_OPT)) { \
|
||||
print_asn1msg(PRT_DEBUG_DECODE, " DEBUG> err 1 %s:%d\n", __FUNCTION__, __LINE__); \
|
||||
return -1; \
|
||||
} \
|
||||
} \
|
||||
} else if ((the_tag) & ASN1_TAG_EXPLICIT) { \
|
||||
/* EXPLICIT tags are always constructed */ \
|
||||
if ((u_char) (((the_tag) & 0xff) | (((act_tag) & ASN1_TAG_TYPE_MASK) | ASN1_TAG_CONSTRUCTED)) == *p) { \
|
||||
int xtag, xlen; \
|
||||
CallASN1(ret, p, end, ParseTag(p, end, &xtag)); \
|
||||
CallASN1(ret, p, end, ParseLen(p, end, &xlen)); \
|
||||
CallASN1(ret, p, end, todo(pc, p, end, arg1)); \
|
||||
} else { \
|
||||
if (!((the_tag) & ASN1_TAG_OPT)) { \
|
||||
print_asn1msg(PRT_DEBUG_DECODE, " DEBUG> err 2 %s:%d\n", __FUNCTION__, __LINE__); \
|
||||
return -1; \
|
||||
} \
|
||||
} \
|
||||
} else { /* IMPLICIT */ \
|
||||
if ((u_char) (((the_tag) & 0xff) | ((act_tag) & (ASN1_TAG_TYPE_MASK | ASN1_TAG_CONSTRUCTED))) == *p) { \
|
||||
CallASN1(ret, p, end, todo(pc, p, end, arg1)); \
|
||||
} else { \
|
||||
if (!((the_tag) & ASN1_TAG_OPT)) { \
|
||||
print_asn1msg(PRT_DEBUG_DECODE, " DEBUG> err 3 %s:%d\n", __FUNCTION__, __LINE__); \
|
||||
return -1; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} else { \
|
||||
if (!((the_tag) & ASN1_TAG_OPT)) { \
|
||||
print_asn1msg(PRT_DEBUG_DECODE, " DEBUG> err 4 %s:%d\n", __FUNCTION__, __LINE__); \
|
||||
return -1; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define XSEQUENCE_OPT_1(todo, act_tag, the_tag, arg1) \
|
||||
XSEQUENCE_1(todo, act_tag, (the_tag | ASN1_TAG_OPT), arg1)
|
||||
|
@ -228,119 +284,153 @@ int ParseLen(u_char *p, u_char *end, int *len);
|
|||
#define XSEQUENCE_OPT(todo, act_tag, the_tag) XSEQUENCE_OPT_1(todo, act_tag, the_tag, -1)
|
||||
|
||||
#define XCHOICE_1(todo, act_tag, the_tag, arg1) \
|
||||
if (act_tag == ASN1_NOT_TAGGED) { \
|
||||
return todo(pc, beg, end, arg1); \
|
||||
} \
|
||||
if (the_tag == ASN1_NOT_TAGGED) { \
|
||||
if (act_tag == tag) { \
|
||||
return todo(pc, beg, end, arg1); \
|
||||
} \
|
||||
} else { \
|
||||
if ((the_tag | (0x80 | (act_tag & 0x20))) == tag) { \
|
||||
return todo(pc, beg, end, arg1); \
|
||||
} \
|
||||
}
|
||||
do { \
|
||||
if ((act_tag) == ASN1_NOT_TAGGED) { \
|
||||
return todo(pc, beg, end, arg1); \
|
||||
} else if ((the_tag) == ASN1_NOT_TAGGED) { \
|
||||
if ((act_tag) == tag) { \
|
||||
return todo(pc, beg, end, arg1); \
|
||||
} \
|
||||
} else if ((act_tag) & ASN1_TAG_EXPLICIT) { \
|
||||
/* EXPLICIT tags are always constructed */ \
|
||||
if (((the_tag) | (((act_tag) & ASN1_TAG_TYPE_MASK) | ASN1_TAG_CONSTRUCTED)) == tag) { \
|
||||
return todo(pc, p, end, arg1); \
|
||||
} \
|
||||
} else { \
|
||||
if (((the_tag) | ((act_tag) & (ASN1_TAG_TYPE_MASK | ASN1_TAG_CONSTRUCTED))) == tag) { \
|
||||
return todo(pc, beg, end, arg1); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define XCHOICE(todo, act_tag, the_tag) XCHOICE_1(todo, act_tag, the_tag, -1)
|
||||
|
||||
#define XCHOICE_DEFAULT do {\
|
||||
print_asn1msg(PRT_DEBUG_DECODE, " DEBUG> err 5 %s:%d\n", __FUNCTION__, __LINE__); \
|
||||
return -1; \
|
||||
} while (0)
|
||||
#define XCHOICE_DEFAULT \
|
||||
do { \
|
||||
print_asn1msg(PRT_DEBUG_DECODE, " DEBUG> err 5 %s:%d\n", __FUNCTION__, __LINE__); \
|
||||
return -1; \
|
||||
} while (0)
|
||||
|
||||
#define CHECK_P do { \
|
||||
if (p >= end) \
|
||||
return -1; \
|
||||
} while (0)
|
||||
#define CHECK_P \
|
||||
do { \
|
||||
if (p >= end) \
|
||||
return -1; \
|
||||
} while (0)
|
||||
|
||||
const struct asn1OidConvert *FindOidByOidValue(int length, const __u16 oidValues[]);
|
||||
const struct asn1OidConvert *FindOidByEnum(__u16 value);
|
||||
__u16 ConvertOidToEnum(const struct asn1Oid *oid, __u16 errorValue);
|
||||
int ConvertEnumToOid(struct asn1Oid *oid, __u16 enumValue);
|
||||
#define IsEnumOid(enumValue) \
|
||||
((FAC_OID_BASE(1) <= (enumValue) \
|
||||
&& (enumValue) < FAC_OID_BASE(FacOIDBase_Last)) ? 1 : 0)
|
||||
|
||||
/*
|
||||
** ASN.1 Encoding
|
||||
*/
|
||||
|
||||
int encodeNull(__u8 *dest);
|
||||
int encodeBoolean(__u8 *dest, __u32 i);
|
||||
int encodeInt(__u8 *dest, __u32 i);
|
||||
int encodeEnum(__u8 *dest, __u32 i);
|
||||
int encodeNumberDigits(__u8 *dest, __s8 *nd, __u8 len);
|
||||
int encodePublicPartyNumber(__u8 *dest, __s8 *facilityPartyNumber);
|
||||
int encodePartyNumber(__u8 *dest, __s8 *facilityPartyNumber);
|
||||
int encodeServedUserNumber(__u8 *dest, __s8 *servedUserNumber);
|
||||
int encodeAddress(__u8 *dest, __s8 *facilityPartyNumber, __s8 *calledPartySubaddress);
|
||||
/* Facility-Information-Element-Components prototypes */
|
||||
enum asn1ComponentTag {
|
||||
asn1ComponentTag_Invoke = ASN1_TAG_CONTEXT_SPECIFIC | ASN1_TAG_CONSTRUCTED | 1,
|
||||
asn1ComponentTag_Result = ASN1_TAG_CONTEXT_SPECIFIC | ASN1_TAG_CONSTRUCTED | 2,
|
||||
asn1ComponentTag_Error = ASN1_TAG_CONTEXT_SPECIFIC | ASN1_TAG_CONSTRUCTED | 3,
|
||||
asn1ComponentTag_Reject = ASN1_TAG_CONTEXT_SPECIFIC | ASN1_TAG_CONSTRUCTED | 4,
|
||||
};
|
||||
__u8 *encodeComponent_Head(__u8 * p, enum asn1ComponentTag componentTag);
|
||||
__u8 *encodeComponent_Head_Long_u8(__u8 * p, enum asn1ComponentTag componentTag);
|
||||
int encodeComponent_Length(__u8 * msg, __u8 * end);
|
||||
int encodeComponent_Length_Long_u8(__u8 * msg, __u8 * p);
|
||||
|
||||
__u8 *encodeComponentInvoke_Head(__u8 * Dest, int InvokeID, enum FacFunction OperationValue);
|
||||
__u8 *encodeComponentInvoke_Head_Long_u8(__u8 * Dest, int InvokeID, enum FacFunction OperationValue);
|
||||
|
||||
int encodeOperationValue(__u8 * dest, int operationValue);
|
||||
int encodeErrorValue(__u8 * dest, int errorValue);
|
||||
|
||||
/* Primitive ASN.1 prototypes */
|
||||
#define ASN1_NUM_OCTETS_LONG_LENGTH_u8 2
|
||||
#define ASN1_NUM_OCTETS_LONG_LENGTH_u16 3
|
||||
int encodeLen_Long_u8(__u8 * dest, __u8 length);
|
||||
int encodeLen_Long_u16(__u8 * dest, __u16 length);
|
||||
|
||||
int encodeNull(__u8 * dest, __u8 tagType);
|
||||
int encodeBoolean(__u8 * dest, __u8 tagType, __u32 i);
|
||||
int encodeInt(__u8 * dest, __u8 tagType, __s32 i);
|
||||
int encodeEnum(__u8 * dest, __u8 tagType, __s32 i);
|
||||
int encodeOctetString(__u8 * dest, __u8 tagType, const __s8 * str, __u8 len);
|
||||
int encodeNumericString(__u8 * dest, __u8 tagType, const __s8 * str, __u8 len);
|
||||
int encodePrintableString(__u8 * dest, __u8 tagType, const __s8 * str, __u8 len);
|
||||
int encodeIA5String(__u8 * dest, __u8 tagType, const __s8 * str, __u8 len);
|
||||
int encodeOid(__u8 * dest, __u8 tagType, const struct asn1Oid *oid);
|
||||
|
||||
/* Addressing-Data-Elements prototypes */
|
||||
int encodePartyNumber_Full(__u8 * Dest, const struct FacPartyNumber *PartyNumber);
|
||||
int encodePartySubaddress_Full(__u8 * Dest, const struct FacPartySubaddress *PartySubaddress);
|
||||
int encodeAddress_Full(__u8 * Dest, const struct FacAddress *Address);
|
||||
int encodePresentedNumberUnscreened_Full(__u8 * Dest, const struct FacPresentedNumberUnscreened *Presented);
|
||||
int encodePresentedAddressScreened_Full(__u8 * Dest, const struct FacPresentedAddressScreened *Presented);
|
||||
|
||||
/*
|
||||
** ASN.1 Parsing
|
||||
*/
|
||||
|
||||
int ParseBoolean(struct asn1_parm *pc, u_char *p, u_char *end, int *i);
|
||||
int ParseNull(struct asn1_parm *pc, u_char *p, u_char *end, int dummy);
|
||||
int ParseInteger(struct asn1_parm *pc, u_char *p, u_char *end, int *i);
|
||||
int ParseEnum(struct asn1_parm *pc, u_char *p, u_char *end, int *i);
|
||||
int ParseIA5String(struct asn1_parm *pc, u_char *p, u_char *end, char *str);
|
||||
int ParseNumericString(struct asn1_parm *pc, u_char *p, u_char *end, char *str);
|
||||
int ParseOctetString(struct asn1_parm *pc, u_char *p, u_char *end, char *str);
|
||||
/* Facility-Information-Element-Components prototypes */
|
||||
int ParseComponent(struct asn1_parm *parm, u_char * p, u_char * end);
|
||||
|
||||
int ParseARGReqCallDeflection(struct asn1_parm *pc, u_char *p, u_char *end, struct ReqCallDeflection *reqCD);
|
||||
int ParseARGActivationStatusNotificationDiv(struct asn1_parm *pc, u_char *p, u_char *end, struct ActDivNotification *actNot);
|
||||
int ParseARGDeactivationStatusNotificationDiv(struct asn1_parm *pc, u_char *p, u_char *end, struct DeactDivNotification *deactNot);
|
||||
int ParseARGInterrogationDiversion(struct asn1_parm *parm, u_char *p, u_char *end, int dummy);
|
||||
int ParseRESInterrogationDiversion(struct asn1_parm *parm, u_char *p, u_char *end, int dummy);
|
||||
int ParseARGInterrogateServedUserNumbers(struct asn1_parm *parm, u_char *p, u_char *end, int dummy);
|
||||
int ParseRESInterrogateServedUserNumbers(struct asn1_parm *parm, u_char *p, u_char *end, int dummy);
|
||||
int ParseARGDiversionInformation(struct asn1_parm *parm, u_char *p, u_char *end, int dummy);
|
||||
int ParseIntResult(struct asn1_parm *parm, u_char *p, u_char *end, struct IntResult *intResult);
|
||||
int ParseIntResultList(struct asn1_parm *parm, u_char *p, u_char *end, struct IntResultList *intResultList);
|
||||
int ParseServedUserNr(struct asn1_parm *parm, u_char *p, u_char *end, struct ServedUserNr *servedUserNr);
|
||||
int ParseProcedure(struct asn1_parm *pc, u_char *p, u_char *end, int *procedure);
|
||||
int ParseServedUserNumberList(struct asn1_parm *parm, u_char *p, u_char *end, struct ServedUserNumberList *list);
|
||||
int ParseDiversionReason(struct asn1_parm *parm, u_char *p, u_char *end, char *str);
|
||||
/* Primitive ASN.1 prototypes */
|
||||
int ParseBoolean(struct asn1_parm *pc, u_char * p, u_char * end, int *i);
|
||||
int ParseNull(struct asn1_parm *pc, u_char * p, u_char * end, int dummy);
|
||||
int ParseUnsignedInteger(struct asn1_parm *pc, u_char * p, u_char * end, unsigned int *i);
|
||||
int ParseSignedInteger(struct asn1_parm *pc, u_char * p, u_char * end, signed int *i);
|
||||
int ParseEnum(struct asn1_parm *pc, u_char * p, u_char * end, unsigned int *i);
|
||||
|
||||
int ParsePresentedAddressScreened(struct asn1_parm *pc, u_char *p, u_char *end, char *str);
|
||||
int ParsePresentedNumberScreened(struct asn1_parm *pc, u_char *p, u_char *end, char *str);
|
||||
int ParsePresentedNumberUnscreened(struct asn1_parm *pc, u_char *p, u_char *end, char *str);
|
||||
int ParseAddressScreened(struct asn1_parm *pc, u_char *p, u_char *end, char *str);
|
||||
int ParseNumberScreened(struct asn1_parm *pc, u_char *p, u_char *end, char *str);
|
||||
int ParseAddress(struct asn1_parm *pc, u_char *p, u_char *end, struct Address *address);
|
||||
int ParsePartyNumber(struct asn1_parm *pc, u_char *p, u_char *end, struct PartyNumber *partyNumber);
|
||||
int ParsePublicPartyNumber(struct asn1_parm *pc, u_char *p, u_char *end, struct PublicPartyNumber *publicPartyNumber);
|
||||
int ParsePrivatePartyNumber(struct asn1_parm *pc, u_char *p, u_char *end, char *str);
|
||||
int ParsePublicTypeOfNumber(struct asn1_parm *pc, u_char *p, u_char *end, int *publicTypeOfNumber);
|
||||
int ParsePrivateTypeOfNumber(struct asn1_parm *pc, u_char *p, u_char *end, int *privateTypeOfNumber);
|
||||
int ParsePartySubaddress(struct asn1_parm *pc, u_char *p, u_char *end, char *str);
|
||||
int ParseUserSpecifiedSubaddress(struct asn1_parm *pc, u_char *p, u_char *end, char *str);
|
||||
int ParseNSAPSubaddress(struct asn1_parm *pc, u_char *p, u_char *end, char *str);
|
||||
int ParseSubaddressInformation(struct asn1_parm *pc, u_char *p, u_char *end, char *str);
|
||||
int ParseScreeningIndicator(struct asn1_parm *pc, u_char *p, u_char *end, char *str);
|
||||
int ParseNumberDigits(struct asn1_parm *pc, u_char *p, u_char *end, char *str);
|
||||
struct asn1ParseString {
|
||||
char *buf; /* Where to put the parsed string characters */
|
||||
size_t maxSize; /* sizeof string buffer (Including an ASCIIz terminator) */
|
||||
size_t length; /* length of string put into the string buffer (Without the terminator) */
|
||||
};
|
||||
int ParseIA5String(struct asn1_parm *pc, u_char * p, u_char * end, struct asn1ParseString *str);
|
||||
int ParseNumericString(struct asn1_parm *pc, u_char * p, u_char * end, struct asn1ParseString *str);
|
||||
int ParseOctetString(struct asn1_parm *pc, u_char * p, u_char * end, struct asn1ParseString *str);
|
||||
int ParseOid(struct asn1_parm *pc, u_char * p, u_char * end, struct asn1Oid *oid);
|
||||
|
||||
int ParseInvokeId(struct asn1_parm *parm, u_char *p, u_char *end, int *invokeId);
|
||||
int ParseOperationValue(struct asn1_parm *parm, u_char *p, u_char *end, int *operationValue);
|
||||
int ParseInvokeComponent(struct asn1_parm *parm, u_char *p, u_char *end, int dummy);
|
||||
int ParseReturnResultComponent(struct asn1_parm *parm, u_char *p, u_char *end, int dummy);
|
||||
int ParseComponent(struct asn1_parm *parm, u_char *p, u_char *end);
|
||||
int XParseComponent(struct asn1_parm *parm, u_char *p, u_char *end);
|
||||
/* Addressing-Data-Elements prototypes */
|
||||
int ParsePartyNumber_Full(struct asn1_parm *pc, u_char * p, u_char * end, struct FacPartyNumber *PartyNumber);
|
||||
int ParsePartySubaddress_Full(struct asn1_parm *pc, u_char * p, u_char * end, struct FacPartySubaddress *PartySubaddress);
|
||||
int ParseAddress_Full(struct asn1_parm *pc, u_char * p, u_char * end, struct FacAddress *Address);
|
||||
int ParsePresentedNumberUnscreened_Full(struct asn1_parm *pc, u_char * p, u_char * end,
|
||||
struct FacPresentedNumberUnscreened *Presented);
|
||||
int ParsePresentedAddressScreened_Full(struct asn1_parm *pc, u_char * p, u_char * end,
|
||||
struct FacPresentedAddressScreened *Presented);
|
||||
|
||||
int ParseAOCECurrency(struct asn1_parm *pc, u_char *p, u_char *end, int dummy);
|
||||
int ParseAOCDChargingUnit(struct asn1_parm *pc,u_char *p, u_char *end, struct FacAOCDChargingUnit *chu);
|
||||
int ParseAOCDCurrency(struct asn1_parm *pc, u_char *p, u_char *end, struct FacAOCDCurrency *cur);
|
||||
int ParseAOCDCurrencyInfo(struct asn1_parm *pc,u_char *p, u_char *end, struct FacAOCDCurrency *cur);
|
||||
int ParseAOCDChargingUnitInfo(struct asn1_parm *pc,u_char *p, u_char *end, struct FacAOCDChargingUnit *chu);
|
||||
int ParseRecordedCurrency(struct asn1_parm *pc,u_char *p, u_char *end, struct FacAOCDCurrency *cur);
|
||||
int ParseRecordedUnitsList(struct asn1_parm *pc,u_char *p, u_char *end, int *recordedUnits);
|
||||
int ParseTypeOfChargingInfo(struct asn1_parm *pc,u_char *p, u_char *end, int *typeOfChargingInfo);
|
||||
int ParseRecordedUnits(struct asn1_parm *pc,u_char *p, u_char *end, int *recordedUnits);
|
||||
int ParseAOCDBillingId(struct asn1_parm *pc, u_char *p, u_char *end, int *billingId);
|
||||
int ParseAOCECurrencyInfo(struct asn1_parm *pc, u_char *p, u_char *end, int dummy);
|
||||
int ParseAOCEChargingUnitInfo(struct asn1_parm *pc,u_char *p, u_char *end, int dummy);
|
||||
int ParseAOCEBillingId(struct asn1_parm *pc,u_char *p, u_char *end, int *billingId);
|
||||
int ParseCurrency(struct asn1_parm *pc,u_char *p, u_char *end, char *currency);
|
||||
int ParseAmount(struct asn1_parm *pc,u_char *p, u_char *end, struct FacAOCDCurrency *cur);
|
||||
int ParseCurrencyAmount(struct asn1_parm *pc,u_char *p, u_char *end, int *currencyAmount);
|
||||
int ParseMultiplier(struct asn1_parm *pc,u_char *p, u_char *end, int *multiplier);
|
||||
int ParseTypeOfUnit(struct asn1_parm *pc,u_char *p, u_char *end, int *typeOfUnit);
|
||||
int ParseNumberOfUnits(struct asn1_parm *pc,u_char *p, u_char *end, int *numberOfUnits);
|
||||
int ParseChargingAssociation(struct asn1_parm *pc,u_char *p, u_char *end, int dummy);
|
||||
int ParseChargeIdentifier(struct asn1_parm *pc,u_char *p, u_char *end, int dummy);
|
||||
/* Advice Of Charge (AOC) prototypes */
|
||||
int ParseAOCECurrency(struct asn1_parm *pc, u_char * p, u_char * end, struct FacAOCCurrency *cur);
|
||||
int ParseAOCDChargingUnit(struct asn1_parm *pc, u_char * p, u_char * end, struct FacAOCChargingUnit *chu);
|
||||
int ParseAOCDCurrency(struct asn1_parm *pc, u_char * p, u_char * end, struct FacAOCCurrency *cur);
|
||||
int ParseAOCDCurrencyInfo(struct asn1_parm *pc, u_char * p, u_char * end, struct FacAOCCurrency *cur);
|
||||
int ParseAOCDChargingUnitInfo(struct asn1_parm *pc, u_char * p, u_char * end, struct FacAOCChargingUnit *chu);
|
||||
int ParseRecordedCurrency(struct asn1_parm *pc, u_char * p, u_char * end, struct FacAOCCurrency *cur);
|
||||
int ParseRecordedUnitsList(struct asn1_parm *pc, u_char * p, u_char * end, int *recordedUnits);
|
||||
int ParseTypeOfChargingInfo(struct asn1_parm *pc, u_char * p, u_char * end, int *typeOfChargingInfo);
|
||||
int ParseRecordedUnits(struct asn1_parm *pc, u_char * p, u_char * end, int *recordedUnits);
|
||||
int ParseAOCDBillingId(struct asn1_parm *pc, u_char * p, u_char * end, int *billingId);
|
||||
int ParseAOCECurrencyInfo(struct asn1_parm *pc, u_char * p, u_char * end, struct FacAOCCurrency *cur);
|
||||
int ParseAOCEChargingUnit(struct asn1_parm *pc, u_char * p, u_char * end, struct FacAOCChargingUnit *chu);
|
||||
int ParseAOCEChargingUnitInfo(struct asn1_parm *pc, u_char * p, u_char * end, struct FacAOCChargingUnit *chu);
|
||||
int ParseAOCEBillingId(struct asn1_parm *pc, u_char * p, u_char * end, int *billingId);
|
||||
int ParseCurrency(struct asn1_parm *pc, u_char * p, u_char * end, char *currency);
|
||||
int ParseAmount(struct asn1_parm *pc, u_char * p, u_char * end, struct FacAOCCurrency *cur);
|
||||
int ParseCurrencyAmount(struct asn1_parm *pc, u_char * p, u_char * end, unsigned int *currencyAmount);
|
||||
int ParseMultiplier(struct asn1_parm *pc, u_char * p, u_char * end, unsigned int *multiplier);
|
||||
int ParseTypeOfUnit(struct asn1_parm *pc, u_char * p, u_char * end, unsigned int *typeOfUnit);
|
||||
int ParseNumberOfUnits(struct asn1_parm *pc, u_char * p, u_char * end, unsigned int *numberOfUnits);
|
||||
int ParseChargingAssociation(struct asn1_parm *pc, u_char * p, u_char * end, struct ChargingAssociation *chargeAssoc);
|
||||
int ParseChargeIdentifier(struct asn1_parm *pc, u_char * p, u_char * end, int *chargeIdentifier);
|
||||
|
||||
int ParseBasicService(struct asn1_parm *pc, u_char *p, u_char *end, int *basicService);
|
||||
/* ------------------------------------------------------------------- */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __ASN1_H__ */
|
||||
/* ------------------------------------------------------------------- *//* end asn1.h */
|
||||
|
|
|
@ -1,233 +1,624 @@
|
|||
/* $Id: asn1_address.c,v 1.2 2006/08/16 14:15:52 nadi Exp $
|
||||
/* $Id$
|
||||
*
|
||||
* Addressing-Data-Elements ETS 300 196-1 D.3
|
||||
*
|
||||
* Addressing-Data-Elements encode/decode
|
||||
*/
|
||||
|
||||
#include "asn1.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
void buildnumber(char *num, int oc3, int oc3a, char *result, int version,
|
||||
int *provider, int *sondernummer, int *intern, int *local,
|
||||
int dir, int who);
|
||||
/* ------------------------------------------------------------------- */
|
||||
|
||||
|
||||
// ======================================================================
|
||||
// Address Types EN 300 196-1 D.3
|
||||
|
||||
int ParsePresentationRestricted(struct asn1_parm *pc, u_char *p, u_char *end, char *str)
|
||||
/* ******************************************************************* */
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Parse the NumberDigits PartyNumber 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 PartyNumber Parameter storage to fill.
|
||||
*
|
||||
* \retval length of buffer consumed
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
static int ParseNumberDigits_Full(struct asn1_parm *pc, u_char * p, u_char * end, struct FacPartyNumber *PartyNumber)
|
||||
{
|
||||
int ret;
|
||||
struct asn1ParseString Number;
|
||||
int LengthConsumed;
|
||||
|
||||
ret = ParseNull(pc, p, end, -1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
strcpy(str, "(presentation restricted)");
|
||||
return ret;
|
||||
}
|
||||
Number.buf = (char *)PartyNumber->Number;
|
||||
Number.maxSize = sizeof(PartyNumber->Number);
|
||||
Number.length = 0;
|
||||
LengthConsumed = ParseNumericString(pc, p, end, &Number);
|
||||
PartyNumber->LengthOfNumber = Number.length;
|
||||
return LengthConsumed;
|
||||
} /* end ParseNumberDigits_Full() */
|
||||
|
||||
int ParseNotAvailInterworking(struct asn1_parm *pc, u_char *p, u_char *end, char *str)
|
||||
/* ******************************************************************* */
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Parse the NSAP PartyNumber 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 PartyNumber Parameter storage to fill.
|
||||
*
|
||||
* \retval length of buffer consumed
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
static int ParseNSAPPartyNumber(struct asn1_parm *pc, u_char * p, u_char * end, struct FacPartyNumber *PartyNumber)
|
||||
{
|
||||
int ret;
|
||||
struct asn1ParseString Number;
|
||||
int LengthConsumed;
|
||||
|
||||
ret = ParseNull(pc, p, end, -1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
strcpy(str, "(not available)");
|
||||
return ret;
|
||||
}
|
||||
Number.buf = (char *)PartyNumber->Number;
|
||||
Number.maxSize = sizeof(PartyNumber->Number);
|
||||
Number.length = 0;
|
||||
LengthConsumed = ParseOctetString(pc, p, end, &Number);
|
||||
PartyNumber->LengthOfNumber = Number.length;
|
||||
return LengthConsumed;
|
||||
} /* end ParseNSAPPartyNumber() */
|
||||
|
||||
int ParsePresentedAddressScreened(struct asn1_parm *pc, u_char *p, u_char *end, char *str)
|
||||
/* ******************************************************************* */
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Encode the public or private network PartyNumber type.
|
||||
*
|
||||
* \param Dest Where to put the encoding
|
||||
* \param Number
|
||||
* \param LengthOfNumber
|
||||
* \param TypeOfNumber
|
||||
*
|
||||
* \retval length
|
||||
*/
|
||||
static int encodeNetworkPartyNumber(__u8 * Dest, const __s8 * Number, __u8 LengthOfNumber, __u8 TypeOfNumber)
|
||||
{
|
||||
__u8 *p;
|
||||
|
||||
Dest[0] = ASN1_TAG_SEQUENCE;
|
||||
p = &Dest[2];
|
||||
|
||||
p += encodeEnum(p, ASN1_TAG_ENUM, TypeOfNumber);
|
||||
p += encodeNumericString(p, ASN1_TAG_NUMERIC_STRING, Number, LengthOfNumber);
|
||||
|
||||
/* length */
|
||||
Dest[1] = p - &Dest[2];
|
||||
|
||||
return p - Dest;
|
||||
} /* end encodeNetworkPartyNumber() */
|
||||
|
||||
/* ******************************************************************* */
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Parse the public or private network PartyNumber 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 PartyNumber Parameter storage to fill.
|
||||
*
|
||||
* \retval length of buffer consumed
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
static int ParseNetworkPartyNumber(struct asn1_parm *pc, u_char * p, u_char * end, struct FacPartyNumber *PartyNumber)
|
||||
{
|
||||
int TypeOfNumber;
|
||||
INIT;
|
||||
|
||||
XCHOICE_1(ParseAddressScreened, ASN1_TAG_SEQUENCE, 0, str);
|
||||
XCHOICE_1(ParsePresentationRestricted, ASN1_TAG_NULL, 1, str);
|
||||
XCHOICE_1(ParseNotAvailInterworking, ASN1_TAG_NULL, 2, str);
|
||||
XCHOICE_1(ParseAddressScreened, ASN1_TAG_NULL, 3, str);
|
||||
XCHOICE_DEFAULT;
|
||||
}
|
||||
|
||||
int ParsePresentedNumberScreened(struct asn1_parm *pc, u_char *p, u_char *end, char *str)
|
||||
{
|
||||
INIT;
|
||||
|
||||
XCHOICE_1(ParseNumberScreened, ASN1_TAG_SEQUENCE, 0, str);
|
||||
XCHOICE_1(ParsePresentationRestricted, ASN1_TAG_NULL, 1, str);
|
||||
XCHOICE_1(ParseNotAvailInterworking, ASN1_TAG_NULL, 2, str);
|
||||
XCHOICE_1(ParseNumberScreened, ASN1_TAG_NULL, 3, str);
|
||||
XCHOICE_DEFAULT;
|
||||
}
|
||||
|
||||
int ParsePresentedNumberUnscreened(struct asn1_parm *pc, u_char *p, u_char *end, char *str)
|
||||
{
|
||||
struct PartyNumber partyNumber;
|
||||
INIT;
|
||||
|
||||
XCHOICE_1(ParsePartyNumber, ASN1_TAG_SEQUENCE, 0, &partyNumber); // FIXME EXP
|
||||
XCHOICE_1(ParsePresentationRestricted, ASN1_TAG_NULL, 1, str);
|
||||
XCHOICE_1(ParseNotAvailInterworking, ASN1_TAG_NULL, 2, str);
|
||||
XCHOICE_1(ParsePartyNumber, ASN1_TAG_SEQUENCE, 3, &partyNumber); // FIXME EXP
|
||||
XCHOICE_DEFAULT;
|
||||
}
|
||||
|
||||
int ParseNumberScreened(struct asn1_parm *pc, u_char *p, u_char *end, char *str)
|
||||
{
|
||||
struct PartyNumber partyNumber;
|
||||
char screeningIndicator[30];
|
||||
INIT;
|
||||
|
||||
XSEQUENCE_1(ParsePartyNumber, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &partyNumber);
|
||||
XSEQUENCE_1(ParseScreeningIndicator, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, screeningIndicator);
|
||||
|
||||
// str += sprintf(str, "%s", partyNumber);
|
||||
XSEQUENCE_1(ParseEnum, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, &TypeOfNumber);
|
||||
PartyNumber->TypeOfNumber = TypeOfNumber;
|
||||
XSEQUENCE_1(ParseNumberDigits_Full, ASN1_TAG_NUMERIC_STRING, ASN1_NOT_TAGGED, PartyNumber);
|
||||
|
||||
return p - beg;
|
||||
}
|
||||
} /* end ParseNetworkPartyNumber() */
|
||||
|
||||
int ParseAddressScreened(struct asn1_parm *pc, u_char *p, u_char *end, char *str)
|
||||
/* ******************************************************************* */
|
||||
/*!
|
||||
* \brief Encode the PartyNumber type.
|
||||
*
|
||||
* \param Dest Where to put the encoding
|
||||
* \param PartyNumber Number information to encode.
|
||||
*
|
||||
* \retval length
|
||||
*/
|
||||
int encodePartyNumber_Full(__u8 * Dest, const struct FacPartyNumber *PartyNumber)
|
||||
{
|
||||
struct PartyNumber partyNumber;
|
||||
char partySubaddress[30] = { 0, };
|
||||
char screeningIndicator[30];
|
||||
INIT;
|
||||
int Length;
|
||||
|
||||
XSEQUENCE_1(ParsePartyNumber, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &partyNumber);
|
||||
XSEQUENCE_1(ParseScreeningIndicator, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, screeningIndicator);
|
||||
XSEQUENCE_OPT_1(ParsePartySubaddress, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, partySubaddress);
|
||||
switch (PartyNumber->Type) {
|
||||
case 0: /* Unknown PartyNumber */
|
||||
Length =
|
||||
encodeNumericString(Dest, ASN1_TAG_CONTEXT_SPECIFIC | 0, (const __s8 *)PartyNumber->Number,
|
||||
PartyNumber->LengthOfNumber);
|
||||
break;
|
||||
case 1: /* Public PartyNumber */
|
||||
Length =
|
||||
encodeNetworkPartyNumber(Dest, (const __s8 *)PartyNumber->Number, PartyNumber->LengthOfNumber,
|
||||
PartyNumber->TypeOfNumber);
|
||||
Dest[0] &= ASN1_TAG_CONSTRUCTED;
|
||||
Dest[0] |= ASN1_TAG_CONTEXT_SPECIFIC | 1;
|
||||
break;
|
||||
case 2: /* NSAP encoded PartyNumber */
|
||||
Length =
|
||||
encodeOctetString(Dest, ASN1_TAG_CONTEXT_SPECIFIC | 2, (const __s8 *)PartyNumber->Number,
|
||||
PartyNumber->LengthOfNumber);
|
||||
break;
|
||||
case 3: /* Data PartyNumber (Not used) */
|
||||
Length =
|
||||
encodeNumericString(Dest, ASN1_TAG_CONTEXT_SPECIFIC | 3, (const __s8 *)PartyNumber->Number,
|
||||
PartyNumber->LengthOfNumber);
|
||||
break;
|
||||
case 4: /* Telex PartyNumber (Not used) */
|
||||
Length =
|
||||
encodeNumericString(Dest, ASN1_TAG_CONTEXT_SPECIFIC | 4, (const __s8 *)PartyNumber->Number,
|
||||
PartyNumber->LengthOfNumber);
|
||||
break;
|
||||
case 5: /* Private PartyNumber */
|
||||
Length =
|
||||
encodeNetworkPartyNumber(Dest, (const __s8 *)PartyNumber->Number, PartyNumber->LengthOfNumber,
|
||||
PartyNumber->TypeOfNumber);
|
||||
Dest[0] &= ASN1_TAG_CONSTRUCTED;
|
||||
Dest[0] |= ASN1_TAG_CONTEXT_SPECIFIC | 5;
|
||||
break;
|
||||
case 8: /* National Standard PartyNumber (Not used) */
|
||||
Length =
|
||||
encodeNumericString(Dest, ASN1_TAG_CONTEXT_SPECIFIC | 8, (const __s8 *)PartyNumber->Number,
|
||||
PartyNumber->LengthOfNumber);
|
||||
break;
|
||||
default:
|
||||
Length = 0;
|
||||
break;
|
||||
} /* end switch */
|
||||
|
||||
// str += sprintf(str, "%s", partyNumber);
|
||||
if (strlen(partySubaddress))
|
||||
str += sprintf(str, ".%s", partySubaddress);
|
||||
return Length;
|
||||
} /* end encodePartyNumber_Full() */
|
||||
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
int ParseAddress(struct asn1_parm *pc, u_char *p, u_char *end, struct Address *address)
|
||||
/* ******************************************************************* */
|
||||
/*!
|
||||
* \brief Parse the PartyNumber 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 PartyNumber Parameter storage to fill.
|
||||
*
|
||||
* \retval length of buffer consumed
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
int ParsePartyNumber_Full(struct asn1_parm *pc, u_char * p, u_char * end, struct FacPartyNumber *PartyNumber)
|
||||
{
|
||||
INIT;
|
||||
|
||||
address->partySubaddress[0] = 0;
|
||||
XSEQUENCE_1(ParsePartyNumber, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &address->partyNumber);
|
||||
|
||||
XSEQUENCE_OPT_1(ParsePartySubaddress, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, address->partySubaddress);
|
||||
PartyNumber->Type = 0; /* Unknown PartyNumber */
|
||||
XCHOICE_1(ParseNumberDigits_Full, ASN1_TAG_CONTEXT_SPECIFIC, 0, PartyNumber);
|
||||
PartyNumber->Type = 1; /* Public PartyNumber */
|
||||
XCHOICE_1(ParseNetworkPartyNumber, ASN1_TAG_CONTEXT_SPECIFIC | ASN1_TAG_CONSTRUCTED, 1, PartyNumber);
|
||||
PartyNumber->Type = 2; /* NSAP encoded PartyNumber */
|
||||
XCHOICE_1(ParseNSAPPartyNumber, ASN1_TAG_CONTEXT_SPECIFIC, 2, PartyNumber);
|
||||
PartyNumber->Type = 3; /* Data PartyNumber (Not used) */
|
||||
XCHOICE_1(ParseNumberDigits_Full, ASN1_TAG_CONTEXT_SPECIFIC, 3, PartyNumber);
|
||||
PartyNumber->Type = 4; /* Telex PartyNumber (Not used) */
|
||||
XCHOICE_1(ParseNumberDigits_Full, ASN1_TAG_CONTEXT_SPECIFIC, 4, PartyNumber);
|
||||
PartyNumber->Type = 5; /* Private PartyNumber */
|
||||
XCHOICE_1(ParseNetworkPartyNumber, ASN1_TAG_CONTEXT_SPECIFIC | ASN1_TAG_CONSTRUCTED, 5, PartyNumber);
|
||||
PartyNumber->Type = 8; /* National Standard PartyNumber (Not used) */
|
||||
XCHOICE_1(ParseNumberDigits_Full, ASN1_TAG_CONTEXT_SPECIFIC, 8, PartyNumber);
|
||||
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
int ParsePartyNumber(struct asn1_parm *pc, u_char *p, u_char *end, struct PartyNumber *partyNumber)
|
||||
{
|
||||
INIT;
|
||||
|
||||
partyNumber->type = 0;
|
||||
XCHOICE_1(ParseNumberDigits, ASN1_TAG_NUMERIC_STRING, 0, partyNumber->p.unknown); // unknownPartyNumber
|
||||
partyNumber->type = 1;
|
||||
XCHOICE_1(ParsePublicPartyNumber, ASN1_TAG_SEQUENCE, 1, &partyNumber->p.publicPartyNumber);
|
||||
#if 0
|
||||
XCHOICE_1(ParseNumberDigits, ASN1_TAG_NUMERIC_STRING, 3, str); // dataPartyNumber
|
||||
XCHOICE_1(ParseNumberDigits, ASN1_TAG_NUMERIC_STRING, 4, str); // telexPartyNumber
|
||||
XCHOICE_1(ParsePrivatePartyNumber, ASN1_TAG_SEQUENCE, 5, str);
|
||||
XCHOICE_1(ParseNumberDigits, ASN1_TAG_NUMERIC_STRING, 8, str); // nationalStandardPartyNumber
|
||||
#endif
|
||||
XCHOICE_DEFAULT;
|
||||
}
|
||||
} /* end ParsePartyNumber_Full() */
|
||||
|
||||
int ParsePublicPartyNumber(struct asn1_parm *pc, u_char *p, u_char *end, struct PublicPartyNumber *publicPartyNumber)
|
||||
/* ******************************************************************* */
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Parse the User information string PartySubaddress 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 PartySubaddress Parameter storage to fill.
|
||||
*
|
||||
* \retval length of buffer consumed
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
static int ParseUserSubaddressInfo(struct asn1_parm *pc, u_char * p, u_char * end, struct FacPartySubaddress *PartySubaddress)
|
||||
{
|
||||
struct asn1ParseString Subaddress;
|
||||
int LengthConsumed;
|
||||
|
||||
Subaddress.buf = (char *)PartySubaddress->u.UserSpecified.Information;
|
||||
Subaddress.maxSize = sizeof(PartySubaddress->u.UserSpecified.Information);
|
||||
Subaddress.length = 0;
|
||||
LengthConsumed = ParseOctetString(pc, p, end, &Subaddress);
|
||||
PartySubaddress->Length = Subaddress.length;
|
||||
return LengthConsumed;
|
||||
} /* end ParseUserSubaddressInfo() */
|
||||
|
||||
/* ******************************************************************* */
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Parse the User PartySubaddress 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 PartySubaddress Parameter storage to fill.
|
||||
*
|
||||
* \retval length of buffer consumed
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
static int ParseUserSubaddress(struct asn1_parm *pc, u_char * p, u_char * end, struct FacPartySubaddress *PartySubaddress)
|
||||
{
|
||||
int OddCount;
|
||||
INIT;
|
||||
|
||||
XSEQUENCE_1(ParsePublicTypeOfNumber, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, &publicPartyNumber->publicTypeOfNumber);
|
||||
XSEQUENCE_1(ParseNumberDigits, ASN1_TAG_NUMERIC_STRING, ASN1_NOT_TAGGED, publicPartyNumber->numberDigits);
|
||||
PartySubaddress->Type = 0; /* UserSpecified */
|
||||
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int ParsePrivatePartyNumber(struct asn1_parm *pc, u_char *p, u_char *end, char *str)
|
||||
{
|
||||
int privateTypeOfNumber;
|
||||
char numberDigits[20];
|
||||
INIT;
|
||||
|
||||
XSEQUENCE_1(ParsePrivateTypeOfNumber, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, &privateTypeOfNumber);
|
||||
XSEQUENCE_1(ParseNumberDigits, ASN1_TAG_NUMERIC_STRING, ASN1_NOT_TAGGED, numberDigits);
|
||||
|
||||
switch (privateTypeOfNumber) {
|
||||
case 0: str += sprintf(str, "(unknown)"); break;
|
||||
case 1: str += sprintf(str, "(regional2)"); break;
|
||||
case 2: str += sprintf(str, "(regional1)"); break;
|
||||
case 3: str += sprintf(str, "(ptn)"); break;
|
||||
case 4: str += sprintf(str, "(local)"); break;
|
||||
case 6: str += sprintf(str, "(abbrev)"); break;
|
||||
XSEQUENCE_1(ParseUserSubaddressInfo, ASN1_TAG_OCTET_STRING, ASN1_NOT_TAGGED, PartySubaddress);
|
||||
if (p < end) {
|
||||
XSEQUENCE_1(ParseBoolean, ASN1_TAG_BOOLEAN, ASN1_NOT_TAGGED, &OddCount);
|
||||
PartySubaddress->u.UserSpecified.OddCount = OddCount;
|
||||
PartySubaddress->u.UserSpecified.OddCountPresent = 1;
|
||||
} else {
|
||||
PartySubaddress->u.UserSpecified.OddCount = 0;
|
||||
PartySubaddress->u.UserSpecified.OddCountPresent = 0;
|
||||
}
|
||||
str += sprintf(str, numberDigits);
|
||||
|
||||
return p - beg;
|
||||
}
|
||||
#endif
|
||||
} /* end ParseUserSubaddress() */
|
||||
|
||||
int ParsePublicTypeOfNumber(struct asn1_parm *pc, u_char *p, u_char *end, int *publicTypeOfNumber)
|
||||
/* ******************************************************************* */
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Parse the NSAP PartySubaddress 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 PartySubaddress Parameter storage to fill.
|
||||
*
|
||||
* \retval length of buffer consumed
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
static int ParseNSAPSubaddress_Full(struct asn1_parm *pc, u_char * p, u_char * end, struct FacPartySubaddress *PartySubaddress)
|
||||
{
|
||||
return ParseEnum(pc, p, end, publicTypeOfNumber);
|
||||
}
|
||||
struct asn1ParseString Subaddress;
|
||||
int LengthConsumed;
|
||||
|
||||
#if 0
|
||||
int ParsePrivateTypeOfNumber(struct asn1_parm *pc, u_char *p, u_char *end, int *privateTypeOfNumber)
|
||||
PartySubaddress->Type = 1; /* NSAP */
|
||||
|
||||
Subaddress.buf = (char *)PartySubaddress->u.Nsap;
|
||||
Subaddress.maxSize = sizeof(PartySubaddress->u.Nsap);
|
||||
Subaddress.length = 0;
|
||||
LengthConsumed = ParseOctetString(pc, p, end, &Subaddress);
|
||||
PartySubaddress->Length = Subaddress.length;
|
||||
return LengthConsumed;
|
||||
} /* end ParseNSAPSubaddress_Full() */
|
||||
|
||||
/* ******************************************************************* */
|
||||
/*!
|
||||
* \brief Encode the PartySubaddress type.
|
||||
*
|
||||
* \param Dest Where to put the encoding
|
||||
* \param PartySubaddress Subaddress information to encode.
|
||||
*
|
||||
* \retval length
|
||||
*/
|
||||
int encodePartySubaddress_Full(__u8 * Dest, const struct FacPartySubaddress *PartySubaddress)
|
||||
{
|
||||
return ParseEnum(pc, p, end, privateTypeOfNumber);
|
||||
}
|
||||
#endif
|
||||
__u8 *p;
|
||||
int Length;
|
||||
|
||||
int ParsePartySubaddress(struct asn1_parm *pc, u_char *p, u_char *end, char *str)
|
||||
switch (PartySubaddress->Type) {
|
||||
case 0: /* UserSpecified */
|
||||
Dest[0] = ASN1_TAG_SEQUENCE;
|
||||
p = &Dest[2];
|
||||
|
||||
p += encodeOctetString(p, ASN1_TAG_OCTET_STRING, (const __s8 *)PartySubaddress->u.UserSpecified.Information,
|
||||
PartySubaddress->Length);
|
||||
if (PartySubaddress->u.UserSpecified.OddCountPresent) {
|
||||
p += encodeBoolean(p, ASN1_TAG_BOOLEAN, PartySubaddress->u.UserSpecified.OddCount);
|
||||
}
|
||||
|
||||
/* length */
|
||||
Dest[1] = p - &Dest[2];
|
||||
|
||||
Length = p - Dest;
|
||||
break;
|
||||
case 1: /* NSAP */
|
||||
Length =
|
||||
encodeOctetString(Dest, ASN1_TAG_OCTET_STRING, (const __s8 *)PartySubaddress->u.Nsap, PartySubaddress->Length);
|
||||
break;
|
||||
default:
|
||||
Length = 0;
|
||||
break;
|
||||
} /* end switch */
|
||||
|
||||
return Length;
|
||||
} /* end encodePartySubaddress_Full() */
|
||||
|
||||
/* ******************************************************************* */
|
||||
/*!
|
||||
* \brief Parse the PartySubaddress 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 PartySubaddress Parameter storage to fill.
|
||||
*
|
||||
* \retval length of buffer consumed
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
int ParsePartySubaddress_Full(struct asn1_parm *pc, u_char * p, u_char * end, struct FacPartySubaddress *PartySubaddress)
|
||||
{
|
||||
INIT;
|
||||
|
||||
XCHOICE_1(ParseUserSpecifiedSubaddress, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, str);
|
||||
XCHOICE_1(ParseNSAPSubaddress, ASN1_TAG_OCTET_STRING, ASN1_NOT_TAGGED, str);
|
||||
XCHOICE_1(ParseUserSubaddress, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, PartySubaddress);
|
||||
XCHOICE_1(ParseNSAPSubaddress_Full, ASN1_TAG_OCTET_STRING, ASN1_NOT_TAGGED, PartySubaddress);
|
||||
|
||||
XCHOICE_DEFAULT;
|
||||
}
|
||||
} /* end ParsePartySubaddress_Full() */
|
||||
|
||||
int ParseUserSpecifiedSubaddress(struct asn1_parm *pc, u_char *p, u_char *end, char *str)
|
||||
/* ******************************************************************* */
|
||||
/*!
|
||||
* \brief Encode the Address type.
|
||||
*
|
||||
* \param Dest Where to put the encoding
|
||||
* \param Address Address information to encode.
|
||||
*
|
||||
* \retval length
|
||||
*/
|
||||
int encodeAddress_Full(__u8 * Dest, const struct FacAddress *Address)
|
||||
{
|
||||
int oddCountIndicator;
|
||||
INIT;
|
||||
__u8 *p;
|
||||
|
||||
XSEQUENCE_1(ParseSubaddressInformation, ASN1_TAG_OCTET_STRING, ASN1_NOT_TAGGED, str);
|
||||
XSEQUENCE_OPT_1(ParseBoolean, ASN1_TAG_BOOLEAN, ASN1_NOT_TAGGED, &oddCountIndicator);
|
||||
|
||||
return p - beg;
|
||||
}
|
||||
Dest[0] = ASN1_TAG_SEQUENCE;
|
||||
p = &Dest[2];
|
||||
|
||||
int ParseNSAPSubaddress(struct asn1_parm *pc, u_char *p, u_char *end, char *str)
|
||||
{
|
||||
return ParseOctetString(pc, p, end, str);
|
||||
}
|
||||
|
||||
int ParseSubaddressInformation(struct asn1_parm *pc, u_char *p, u_char *end, char *str)
|
||||
{
|
||||
return ParseOctetString(pc, p, end, str);
|
||||
}
|
||||
|
||||
int ParseScreeningIndicator(struct asn1_parm *pc, u_char *p, u_char *end, char *str)
|
||||
{
|
||||
int ret;
|
||||
int screeningIndicator;
|
||||
|
||||
ret = ParseEnum(pc, p, end, &screeningIndicator);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
switch (screeningIndicator) {
|
||||
case 0: sprintf(str, "user provided, not screened"); break;
|
||||
case 1: sprintf(str, "user provided, passed"); break;
|
||||
case 2: sprintf(str, "user provided, failed"); break;
|
||||
case 3: sprintf(str, "network provided"); break;
|
||||
default: sprintf(str, "(%d)", screeningIndicator); break;
|
||||
p += encodePartyNumber_Full(p, &Address->Party);
|
||||
if (Address->Subaddress.Length) {
|
||||
p += encodePartySubaddress_Full(p, &Address->Subaddress);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
/* length */
|
||||
Dest[1] = p - &Dest[2];
|
||||
|
||||
int ParseNumberDigits(struct asn1_parm *pc, u_char *p, u_char *end, char *str)
|
||||
return p - Dest;
|
||||
} /* end encodeAddress_Full() */
|
||||
|
||||
/* ******************************************************************* */
|
||||
/*!
|
||||
* \brief Parse the Address 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 Address Parameter storage to fill.
|
||||
*
|
||||
* \retval length of buffer consumed
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
int ParseAddress_Full(struct asn1_parm *pc, u_char * p, u_char * end, struct FacAddress *Address)
|
||||
{
|
||||
return ParseNumericString(pc, p, end, str);
|
||||
}
|
||||
INIT;
|
||||
|
||||
XSEQUENCE_1(ParsePartyNumber_Full, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &Address->Party);
|
||||
if (p < end) {
|
||||
/* The optional subaddress must be present since there is something left. */
|
||||
XSEQUENCE_1(ParsePartySubaddress_Full, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &Address->Subaddress);
|
||||
} else {
|
||||
Address->Subaddress.Length = 0; /* Subaddress not present */
|
||||
}
|
||||
|
||||
return p - beg;
|
||||
} /* end ParseAddress_Full() */
|
||||
|
||||
/* ******************************************************************* */
|
||||
/*!
|
||||
* \brief Encode the PresentedNumberUnscreened type.
|
||||
*
|
||||
* \param Dest Where to put the encoding
|
||||
* \param Presented Number information to encode.
|
||||
*
|
||||
* \retval length
|
||||
*/
|
||||
int encodePresentedNumberUnscreened_Full(__u8 * Dest, const struct FacPresentedNumberUnscreened *Presented)
|
||||
{
|
||||
__u8 *p;
|
||||
__u8 *TagStart;
|
||||
|
||||
p = Dest;
|
||||
switch (Presented->Type) {
|
||||
case 0: /* presentationAllowedNumber */
|
||||
TagStart = p;
|
||||
TagStart[0] = ASN1_TAG_CONTEXT_SPECIFIC | ASN1_TAG_CONSTRUCTED | 0;
|
||||
p = &TagStart[2];
|
||||
|
||||
p += encodePartyNumber_Full(p, &Presented->Unscreened);
|
||||
|
||||
/* tag Length */
|
||||
TagStart[1] = p - &TagStart[2];
|
||||
break;
|
||||
case 1: /* presentationRestricted */
|
||||
p += encodeNull(p, ASN1_TAG_CONTEXT_SPECIFIC | 1);
|
||||
break;
|
||||
case 2: /* numberNotAvailableDueToInterworking */
|
||||
p += encodeNull(p, ASN1_TAG_CONTEXT_SPECIFIC | 2);
|
||||
break;
|
||||
case 3: /* presentationRestrictedNumber */
|
||||
TagStart = p;
|
||||
TagStart[0] = ASN1_TAG_CONTEXT_SPECIFIC | ASN1_TAG_CONSTRUCTED | 3;
|
||||
p = &TagStart[2];
|
||||
|
||||
p += encodePartyNumber_Full(p, &Presented->Unscreened);
|
||||
|
||||
/* tag Length */
|
||||
TagStart[1] = p - &TagStart[2];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
} /* end switch */
|
||||
|
||||
return p - Dest;
|
||||
} /* end encodePresentedNumberUnscreened_Full() */
|
||||
|
||||
/* ******************************************************************* */
|
||||
/*!
|
||||
* \brief Parse the PresentedNumberUnscreened 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 Presented Parameter storage to fill.
|
||||
*
|
||||
* \retval length of buffer consumed
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
int ParsePresentedNumberUnscreened_Full(struct asn1_parm *pc, u_char * p, u_char * end,
|
||||
struct FacPresentedNumberUnscreened *Presented)
|
||||
{
|
||||
INIT;
|
||||
|
||||
Presented->Type = 0;
|
||||
XCHOICE_1(ParsePartyNumber_Full, ASN1_TAG_EXPLICIT | ASN1_TAG_CONTEXT_SPECIFIC, 0, &Presented->Unscreened);
|
||||
Presented->Type = 1;
|
||||
XCHOICE(ParseNull, ASN1_TAG_CONTEXT_SPECIFIC, 1);
|
||||
Presented->Type = 2;
|
||||
XCHOICE(ParseNull, ASN1_TAG_CONTEXT_SPECIFIC, 2);
|
||||
Presented->Type = 3;
|
||||
XCHOICE_1(ParsePartyNumber_Full, ASN1_TAG_EXPLICIT | ASN1_TAG_CONTEXT_SPECIFIC, 3, &Presented->Unscreened);
|
||||
|
||||
XCHOICE_DEFAULT;
|
||||
} /* end ParsePresentedNumberUnscreened_Full() */
|
||||
|
||||
/* ******************************************************************* */
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Encode the AddressScreened type.
|
||||
*
|
||||
* \param Dest Where to put the encoding
|
||||
* \param Address Address information to encode.
|
||||
*
|
||||
* \retval length
|
||||
*/
|
||||
static int encodeAddressScreened_Full(__u8 * Dest, const struct FacAddressScreened *Address)
|
||||
{
|
||||
__u8 *p;
|
||||
|
||||
Dest[0] = ASN1_TAG_SEQUENCE;
|
||||
p = &Dest[2];
|
||||
|
||||
p += encodePartyNumber_Full(p, &Address->Party);
|
||||
p += encodeEnum(p, ASN1_TAG_ENUM, Address->ScreeningIndicator);
|
||||
if (Address->Subaddress.Length) {
|
||||
p += encodePartySubaddress_Full(p, &Address->Subaddress);
|
||||
}
|
||||
|
||||
/* length */
|
||||
Dest[1] = p - &Dest[2];
|
||||
|
||||
return p - Dest;
|
||||
} /* end encodeAddressScreened_Full() */
|
||||
|
||||
/* ******************************************************************* */
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Parse the AddressScreened 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 Address Parameter storage to fill.
|
||||
*
|
||||
* \retval length of buffer consumed
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
static int ParseAddressScreened_Full(struct asn1_parm *pc, u_char * p, u_char * end, struct FacAddressScreened *Address)
|
||||
{
|
||||
int Value;
|
||||
INIT;
|
||||
|
||||
XSEQUENCE_1(ParsePartyNumber_Full, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &Address->Party);
|
||||
XSEQUENCE_1(ParseEnum, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, &Value);
|
||||
Address->ScreeningIndicator = Value;
|
||||
if (p < end) {
|
||||
/* The optional subaddress must be present since there is something left. */
|
||||
XSEQUENCE_1(ParsePartySubaddress_Full, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &Address->Subaddress);
|
||||
} else {
|
||||
Address->Subaddress.Length = 0; /* Subaddress not present */
|
||||
}
|
||||
|
||||
return p - beg;
|
||||
} /* end ParseAddressScreened_Full() */
|
||||
|
||||
/* ******************************************************************* */
|
||||
/*!
|
||||
* \brief Encode the PresentedAddressScreened type.
|
||||
*
|
||||
* \param Dest Where to put the encoding
|
||||
* \param Presented Address information to encode.
|
||||
*
|
||||
* \retval length
|
||||
*/
|
||||
int encodePresentedAddressScreened_Full(__u8 * Dest, const struct FacPresentedAddressScreened *Presented)
|
||||
{
|
||||
__u8 *p;
|
||||
__u8 *TagStart;
|
||||
|
||||
p = Dest;
|
||||
switch (Presented->Type) {
|
||||
case 0: /* presentationAllowedAddress */
|
||||
TagStart = p;
|
||||
p += encodeAddressScreened_Full(p, &Presented->Address);
|
||||
TagStart[0] = ASN1_TAG_CONTEXT_SPECIFIC | ASN1_TAG_CONSTRUCTED | 0;
|
||||
break;
|
||||
case 1: /* presentationRestricted */
|
||||
p += encodeNull(p, ASN1_TAG_CONTEXT_SPECIFIC | 1);
|
||||
break;
|
||||
case 2: /* numberNotAvailableDueToInterworking */
|
||||
p += encodeNull(p, ASN1_TAG_CONTEXT_SPECIFIC | 2);
|
||||
break;
|
||||
case 3: /* presentationRestrictedAddress */
|
||||
TagStart = p;
|
||||
p += encodeAddressScreened_Full(p, &Presented->Address);
|
||||
TagStart[0] = ASN1_TAG_CONTEXT_SPECIFIC | ASN1_TAG_CONSTRUCTED | 3;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
} /* end switch */
|
||||
|
||||
return p - Dest;
|
||||
} /* end encodePresentedAddressScreened_Full() */
|
||||
|
||||
/* ******************************************************************* */
|
||||
/*!
|
||||
* \brief Parse the PresentedAddressScreened 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 Presented Parameter storage to fill.
|
||||
*
|
||||
* \retval length of buffer consumed
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
int ParsePresentedAddressScreened_Full(struct asn1_parm *pc, u_char * p, u_char * end,
|
||||
struct FacPresentedAddressScreened *Presented)
|
||||
{
|
||||
INIT;
|
||||
|
||||
Presented->Type = 0;
|
||||
XCHOICE_1(ParseAddressScreened_Full, ASN1_TAG_CONTEXT_SPECIFIC | ASN1_TAG_CONSTRUCTED, 0, &Presented->Address);
|
||||
Presented->Type = 1;
|
||||
XCHOICE(ParseNull, ASN1_TAG_CONTEXT_SPECIFIC, 1);
|
||||
Presented->Type = 2;
|
||||
XCHOICE(ParseNull, ASN1_TAG_CONTEXT_SPECIFIC, 2);
|
||||
Presented->Type = 3;
|
||||
XCHOICE_1(ParseAddressScreened_Full, ASN1_TAG_CONTEXT_SPECIFIC | ASN1_TAG_CONSTRUCTED, 3, &Presented->Address);
|
||||
|
||||
XCHOICE_DEFAULT;
|
||||
} /* end ParsePresentedAddressScreened_Full() */
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
/* end asn1_address.c */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: asn1_aoc.c,v 1.3 2006/08/16 14:15:52 nadi Exp $
|
||||
/* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -8,118 +8,133 @@
|
|||
// ======================================================================
|
||||
// AOC EN 300 182-1 V1.3.3
|
||||
|
||||
int
|
||||
ParseAOCDCurrency(struct asn1_parm *pc, u_char *p, u_char *end, struct FacAOCDCurrency *cur)
|
||||
int ParseAOCDCurrency(struct asn1_parm *pc, u_char * p, u_char * end, struct FacAOCCurrency *cur)
|
||||
{
|
||||
INIT;
|
||||
|
||||
cur->InvokeID = pc->u.inv.invokeId;
|
||||
|
||||
cur->chargeNotAvailable = 1;
|
||||
cur->freeOfCharge = 0;
|
||||
memset(cur->currency, 0 , sizeof(cur->currency));
|
||||
memset(cur->currency, 0, sizeof(cur->currency));
|
||||
cur->currencyAmount = 0;
|
||||
cur->multiplier = 0;
|
||||
cur->typeOfChargingInfo = -1;
|
||||
cur->billingId = -1;
|
||||
XCHOICE(ParseNull, ASN1_TAG_NULL, ASN1_NOT_TAGGED); // chargeNotAvail
|
||||
XCHOICE(ParseNull, ASN1_TAG_NULL, ASN1_NOT_TAGGED); // chargeNotAvail
|
||||
cur->chargeNotAvailable = 0;
|
||||
XCHOICE_1(ParseAOCDCurrencyInfo, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, cur);
|
||||
XCHOICE_DEFAULT;
|
||||
}
|
||||
|
||||
int
|
||||
ParseAOCDChargingUnit(struct asn1_parm *pc, u_char *p, u_char *end, struct FacAOCDChargingUnit *chu)
|
||||
int ParseAOCDChargingUnit(struct asn1_parm *pc, u_char * p, u_char * end, struct FacAOCChargingUnit *chu)
|
||||
{
|
||||
INIT;
|
||||
|
||||
chu->InvokeID = pc->u.inv.invokeId;
|
||||
|
||||
chu->chargeNotAvailable = 1;
|
||||
chu->freeOfCharge = 0;
|
||||
chu->recordedUnits = 0;
|
||||
chu->typeOfChargingInfo = -1;
|
||||
chu->billingId = -1;
|
||||
XCHOICE(ParseNull, ASN1_TAG_NULL, ASN1_NOT_TAGGED); // chargeNotAvail
|
||||
memset(chu->chargeNumber, 0, sizeof(chu->chargeNumber));
|
||||
XCHOICE(ParseNull, ASN1_TAG_NULL, ASN1_NOT_TAGGED); // chargeNotAvail
|
||||
chu->chargeNotAvailable = 0;
|
||||
XCHOICE_1(ParseAOCDChargingUnitInfo, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, chu);
|
||||
XCHOICE_DEFAULT;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// AOCECurrency
|
||||
|
||||
int
|
||||
ParseAOCECurrency(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
int ParseAOCECurrency(struct asn1_parm *pc, u_char * p, u_char * end, struct FacAOCCurrency *cur)
|
||||
{
|
||||
INIT;
|
||||
|
||||
XCHOICE(ParseNull, ASN1_TAG_NULL, ASN1_NOT_TAGGED); // chargeNotAvail
|
||||
XCHOICE(ParseAOCECurrencyInfo, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED);
|
||||
cur->InvokeID = pc->u.inv.invokeId;
|
||||
|
||||
cur->chargeNotAvailable = 1;
|
||||
cur->freeOfCharge = 0;
|
||||
memset(cur->currency, 0, sizeof(cur->currency));
|
||||
cur->currencyAmount = 0;
|
||||
cur->multiplier = 0;
|
||||
cur->typeOfChargingInfo = -1;
|
||||
cur->billingId = -1;
|
||||
|
||||
XCHOICE(ParseNull, ASN1_TAG_NULL, ASN1_NOT_TAGGED); // chargeNotAvail
|
||||
cur->chargeNotAvailable = 0;
|
||||
XCHOICE_1(ParseAOCECurrencyInfo, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, cur);
|
||||
XCHOICE_DEFAULT;
|
||||
}
|
||||
#endif
|
||||
|
||||
// AOCEChargingUnit
|
||||
|
||||
int
|
||||
ParseAOCEChargingUnit(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
int ParseAOCEChargingUnit(struct asn1_parm *pc, u_char * p, u_char * end, struct FacAOCChargingUnit *chu)
|
||||
{
|
||||
INIT;
|
||||
|
||||
XCHOICE(ParseNull, ASN1_TAG_NULL, ASN1_NOT_TAGGED); // chargeNotAvail
|
||||
XCHOICE(ParseAOCEChargingUnitInfo, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED);
|
||||
chu->InvokeID = pc->u.inv.invokeId;
|
||||
|
||||
chu->chargeNotAvailable = 1;
|
||||
chu->freeOfCharge = 0;
|
||||
chu->recordedUnits = 0;
|
||||
chu->typeOfChargingInfo = -1;
|
||||
chu->billingId = -1;
|
||||
memset(chu->chargeNumber, 0, sizeof(chu->chargeNumber));
|
||||
|
||||
XCHOICE(ParseNull, ASN1_TAG_NULL, ASN1_NOT_TAGGED); // chargeNotAvail
|
||||
XCHOICE_1(ParseAOCEChargingUnitInfo, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, chu);
|
||||
XCHOICE_DEFAULT;
|
||||
}
|
||||
|
||||
// AOCDCurrencyInfo
|
||||
|
||||
int
|
||||
ParseAOCDSpecificCurrency(struct asn1_parm *pc, u_char *p, u_char *end, struct FacAOCDCurrency *cur)
|
||||
int ParseAOCDSpecificCurrency(struct asn1_parm *pc, u_char * p, u_char * end, struct FacAOCCurrency *cur)
|
||||
{
|
||||
INIT;
|
||||
|
||||
XSEQUENCE_1(ParseRecordedCurrency, ASN1_TAG_SEQUENCE, 1, cur);
|
||||
XSEQUENCE_1(ParseTypeOfChargingInfo, ASN1_TAG_ENUM, 2, &cur->typeOfChargingInfo);
|
||||
XSEQUENCE_OPT_1(ParseAOCDBillingId, ASN1_TAG_ENUM, 3, &cur->billingId);
|
||||
XSEQUENCE_1(ParseRecordedCurrency, ASN1_TAG_CONTEXT_SPECIFIC | ASN1_TAG_CONSTRUCTED, 1, cur);
|
||||
XSEQUENCE_1(ParseTypeOfChargingInfo, ASN1_TAG_CONTEXT_SPECIFIC, 2, &cur->typeOfChargingInfo);
|
||||
XSEQUENCE_OPT_1(ParseAOCDBillingId, ASN1_TAG_CONTEXT_SPECIFIC, 3, &cur->billingId);
|
||||
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
int
|
||||
ParseAOCDCurrencyInfo(struct asn1_parm *pc, u_char *p, u_char *end, struct FacAOCDCurrency *cur)
|
||||
int ParseAOCDCurrencyInfo(struct asn1_parm *pc, u_char * p, u_char * end, struct FacAOCCurrency *cur)
|
||||
{
|
||||
INIT;
|
||||
|
||||
XCHOICE_1(ParseAOCDSpecificCurrency, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, cur);
|
||||
|
||||
cur->freeOfCharge = 1;
|
||||
XCHOICE(ParseNull, ASN1_TAG_NULL, 1); // freeOfCharge
|
||||
XCHOICE(ParseNull, ASN1_TAG_CONTEXT_SPECIFIC, 1); // freeOfCharge
|
||||
cur->freeOfCharge = 0;
|
||||
XCHOICE_DEFAULT;
|
||||
}
|
||||
|
||||
// AOCDChargingUnitInfo
|
||||
|
||||
int
|
||||
ParseAOCDSpecificChargingUnits(struct asn1_parm *pc, u_char *p, u_char *end, struct FacAOCDChargingUnit *chu)
|
||||
int ParseAOCDSpecificChargingUnits(struct asn1_parm *pc, u_char * p, u_char * end, struct FacAOCChargingUnit *chu)
|
||||
{
|
||||
INIT;
|
||||
|
||||
XSEQUENCE_1(ParseRecordedUnitsList, ASN1_TAG_SEQUENCE, 1, &chu->recordedUnits);
|
||||
XSEQUENCE_1(ParseTypeOfChargingInfo, ASN1_TAG_ENUM, 2, &chu->typeOfChargingInfo);
|
||||
XSEQUENCE_OPT_1(ParseAOCDBillingId, ASN1_TAG_ENUM, 3, &chu->billingId);
|
||||
XSEQUENCE_1(ParseRecordedUnitsList, ASN1_TAG_CONTEXT_SPECIFIC | ASN1_TAG_CONSTRUCTED, 1, &chu->recordedUnits);
|
||||
XSEQUENCE_1(ParseTypeOfChargingInfo, ASN1_TAG_CONTEXT_SPECIFIC, 2, &chu->typeOfChargingInfo);
|
||||
XSEQUENCE_OPT_1(ParseAOCDBillingId, ASN1_TAG_CONTEXT_SPECIFIC, 3, &chu->billingId);
|
||||
|
||||
// p_L3L4(pc, CC_CHARGE | INDICATION, &recordedUnits);
|
||||
// p_L3L4(pc, CC_CHARGE | INDICATION, &recordedUnits);
|
||||
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
int
|
||||
ParseAOCDChargingUnitInfo(struct asn1_parm *pc, u_char *p, u_char *end, struct FacAOCDChargingUnit *chu)
|
||||
int ParseAOCDChargingUnitInfo(struct asn1_parm *pc, u_char * p, u_char * end, struct FacAOCChargingUnit *chu)
|
||||
{
|
||||
INIT;
|
||||
|
||||
XCHOICE_1(ParseAOCDSpecificChargingUnits, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, chu);
|
||||
|
||||
chu->freeOfCharge = 1;
|
||||
XCHOICE(ParseNull, ASN1_TAG_NULL, 1); // freeOfCharge
|
||||
XCHOICE(ParseNull, ASN1_TAG_CONTEXT_SPECIFIC, 1); // freeOfCharge
|
||||
chu->freeOfCharge = 0;
|
||||
|
||||
XCHOICE_DEFAULT;
|
||||
|
@ -127,21 +142,19 @@ ParseAOCDChargingUnitInfo(struct asn1_parm *pc, u_char *p, u_char *end, struct F
|
|||
|
||||
// RecordedCurrency
|
||||
|
||||
int
|
||||
ParseRecordedCurrency(struct asn1_parm *pc, u_char *p, u_char *end, struct FacAOCDCurrency *cur)
|
||||
int ParseRecordedCurrency(struct asn1_parm *pc, u_char * p, u_char * end, struct FacAOCCurrency *cur)
|
||||
{
|
||||
INIT;
|
||||
|
||||
XSEQUENCE_1(ParseCurrency, ASN1_TAG_IA5_STRING, 1, (char *)cur->currency);
|
||||
XSEQUENCE_1(ParseAmount, ASN1_TAG_SEQUENCE, 2, cur);
|
||||
XSEQUENCE_1(ParseCurrency, ASN1_TAG_CONTEXT_SPECIFIC, 1, (char *)cur->currency);
|
||||
XSEQUENCE_1(ParseAmount, ASN1_TAG_CONTEXT_SPECIFIC | ASN1_TAG_CONSTRUCTED, 2, cur);
|
||||
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
// RecordedUnitsList
|
||||
|
||||
int
|
||||
ParseRecordedUnitsList(struct asn1_parm *pc, u_char *p, u_char *end, int *recordedUnits)
|
||||
int ParseRecordedUnitsList(struct asn1_parm *pc, u_char * p, u_char * end, int *recordedUnits)
|
||||
{
|
||||
int i;
|
||||
int units;
|
||||
|
@ -160,26 +173,23 @@ ParseRecordedUnitsList(struct asn1_parm *pc, u_char *p, u_char *end, int *record
|
|||
|
||||
// TypeOfChargingInfo
|
||||
|
||||
int
|
||||
ParseTypeOfChargingInfo(struct asn1_parm *pc, u_char *p, u_char *end, int *typeOfChargingInfo)
|
||||
int ParseTypeOfChargingInfo(struct asn1_parm *pc, u_char * p, u_char * end, int *typeOfChargingInfo)
|
||||
{
|
||||
return ParseEnum(pc, p, end, typeOfChargingInfo);
|
||||
}
|
||||
|
||||
// RecordedUnits
|
||||
|
||||
int
|
||||
ParseRecordedUnitsChoice(struct asn1_parm *pc, u_char *p, u_char *end, int *recordedUnits)
|
||||
int ParseRecordedUnitsChoice(struct asn1_parm *pc, u_char * p, u_char * end, int *recordedUnits)
|
||||
{
|
||||
INIT;
|
||||
|
||||
XCHOICE_1(ParseNumberOfUnits, ASN1_TAG_INTEGER, ASN1_NOT_TAGGED, recordedUnits);
|
||||
XCHOICE(ParseNull, ASN1_TAG_NULL, ASN1_NOT_TAGGED); // not available
|
||||
XCHOICE(ParseNull, ASN1_TAG_NULL, ASN1_NOT_TAGGED); // not available
|
||||
XCHOICE_DEFAULT;
|
||||
}
|
||||
|
||||
int
|
||||
ParseRecordedUnits(struct asn1_parm *pc, u_char *p, u_char *end, int *recordedUnits)
|
||||
int ParseRecordedUnits(struct asn1_parm *pc, u_char * p, u_char * end, int *recordedUnits)
|
||||
{
|
||||
int typeOfUnit;
|
||||
INIT;
|
||||
|
@ -192,167 +202,154 @@ ParseRecordedUnits(struct asn1_parm *pc, u_char *p, u_char *end, int *recordedUn
|
|||
|
||||
// AOCDBillingId
|
||||
|
||||
int
|
||||
ParseAOCDBillingId(struct asn1_parm *pc, u_char *p, u_char *end, int *billingId)
|
||||
int ParseAOCDBillingId(struct asn1_parm *pc, u_char * p, u_char * end, int *billingId)
|
||||
{
|
||||
return ParseEnum(pc, p, end, billingId);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* #if 0 */
|
||||
// AOCECurrencyInfo
|
||||
|
||||
int
|
||||
ParseAOCESpecificCurrency(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
int ParseAOCESpecificCurrency(struct asn1_parm *pc, u_char * p, u_char * end, struct FacAOCCurrency *cur)
|
||||
{
|
||||
int billingId;
|
||||
INIT;
|
||||
|
||||
XSEQUENCE(ParseRecordedCurrency, ASN1_TAG_SEQUENCE, 1);
|
||||
XSEQUENCE_OPT_1(ParseAOCEBillingId, ASN1_TAG_ENUM, 2, &billingId);
|
||||
XSEQUENCE_1(ParseRecordedCurrency, ASN1_TAG_CONTEXT_SPECIFIC | ASN1_TAG_CONSTRUCTED, 1, cur);
|
||||
XSEQUENCE_OPT_1(ParseAOCEBillingId, ASN1_TAG_CONTEXT_SPECIFIC, 2, &cur->billingId);
|
||||
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
int
|
||||
ParseAOCECurrencyInfoChoice(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
int ParseAOCECurrencyInfoChoice(struct asn1_parm *pc, u_char * p, u_char * end, struct FacAOCCurrency *cur)
|
||||
{
|
||||
INIT;
|
||||
|
||||
XCHOICE(ParseAOCESpecificCurrency, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED);
|
||||
XCHOICE(ParseNull, ASN1_TAG_NULL, 1); // freeOfCharge
|
||||
XCHOICE_1(ParseAOCESpecificCurrency, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, cur);
|
||||
XCHOICE(ParseNull, ASN1_TAG_CONTEXT_SPECIFIC, 1); // freeOfCharge
|
||||
XCHOICE_DEFAULT;
|
||||
}
|
||||
|
||||
int
|
||||
ParseAOCECurrencyInfo(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
int ParseAOCECurrencyInfo(struct asn1_parm *pc, u_char * p, u_char * end, struct FacAOCCurrency *cur)
|
||||
{
|
||||
INIT;
|
||||
|
||||
XSEQUENCE(ParseAOCECurrencyInfoChoice, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED);
|
||||
XSEQUENCE_OPT(ParseChargingAssociation, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED);
|
||||
XSEQUENCE_1(ParseAOCECurrencyInfoChoice, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, cur);
|
||||
XSEQUENCE_OPT_1(ParseChargingAssociation, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &cur->chargeAssoc);
|
||||
XCHOICE_DEFAULT;
|
||||
}
|
||||
#endif
|
||||
|
||||
// AOCEChargingUnitInfo
|
||||
|
||||
int
|
||||
ParseAOCESpecificChargingUnits(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
int ParseAOCESpecificChargingUnits(struct asn1_parm *pc, u_char * p, u_char * end, struct FacAOCChargingUnit *chu)
|
||||
{
|
||||
int recordedUnits;
|
||||
int billingId;
|
||||
|
||||
INIT;
|
||||
|
||||
XSEQUENCE_1(ParseRecordedUnitsList, ASN1_TAG_SEQUENCE, 1, &recordedUnits);
|
||||
XSEQUENCE_OPT_1(ParseAOCEBillingId, ASN1_TAG_ENUM, 2, &billingId);
|
||||
|
||||
// p_L3L4(pc, CC_CHARGE | INDICATION, &recordedUnits);
|
||||
XSEQUENCE_1(ParseRecordedUnitsList, ASN1_TAG_CONTEXT_SPECIFIC | ASN1_TAG_CONSTRUCTED, 1, &chu->recordedUnits);
|
||||
XSEQUENCE_OPT_1(ParseAOCEBillingId, ASN1_TAG_CONTEXT_SPECIFIC, 2, &chu->billingId);
|
||||
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
int
|
||||
ParseAOCEChargingUnitInfoChoice(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
int ParseAOCEChargingUnitInfoChoice(struct asn1_parm *pc, u_char * p, u_char * end, struct FacAOCChargingUnit *chu)
|
||||
{
|
||||
INIT;
|
||||
|
||||
XCHOICE(ParseAOCESpecificChargingUnits, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED);
|
||||
XCHOICE(ParseNull, ASN1_TAG_NULL, 1); // freeOfCharge
|
||||
XCHOICE_1(ParseAOCESpecificChargingUnits, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, chu);
|
||||
XCHOICE(ParseNull, ASN1_TAG_CONTEXT_SPECIFIC, 1); // freeOfCharge
|
||||
XCHOICE_DEFAULT;
|
||||
}
|
||||
|
||||
int
|
||||
ParseAOCEChargingUnitInfo(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
int ParseAOCEChargingUnitInfo(struct asn1_parm *pc, u_char * p, u_char * end, struct FacAOCChargingUnit *chu)
|
||||
{
|
||||
INIT;
|
||||
|
||||
XSEQUENCE(ParseAOCEChargingUnitInfoChoice, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED);
|
||||
XSEQUENCE_OPT(ParseChargingAssociation, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED);
|
||||
|
||||
return p - beg;
|
||||
XSEQUENCE_1(ParseAOCEChargingUnitInfoChoice, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, chu);
|
||||
XSEQUENCE_OPT_1(ParseChargingAssociation, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &chu->chargeAssoc);
|
||||
}
|
||||
|
||||
// AOCEBillingId
|
||||
|
||||
int
|
||||
ParseAOCEBillingId(struct asn1_parm *pc, u_char *p, u_char *end, int *billingId)
|
||||
int ParseAOCEBillingId(struct asn1_parm *pc, u_char * p, u_char * end, int *billingId)
|
||||
{
|
||||
return ParseEnum(pc, p, end, billingId);
|
||||
}
|
||||
|
||||
// Currency
|
||||
|
||||
int
|
||||
ParseCurrency(struct asn1_parm *pc, u_char *p, u_char *end, char *currency)
|
||||
int ParseCurrency(struct asn1_parm *pc, u_char * p, u_char * end, char *currency)
|
||||
{
|
||||
return ParseIA5String(pc, p, end, currency);
|
||||
struct asn1ParseString str;
|
||||
|
||||
str.buf = currency;
|
||||
str.maxSize = 11; /* sizeof(struct FacAOCCurrency.currency) */
|
||||
return ParseIA5String(pc, p, end, &str);
|
||||
}
|
||||
|
||||
// Amount
|
||||
|
||||
int
|
||||
ParseAmount(struct asn1_parm *pc, u_char *p, u_char *end, struct FacAOCDCurrency *cur)
|
||||
int ParseAmount(struct asn1_parm *pc, u_char * p, u_char * end, struct FacAOCCurrency *cur)
|
||||
{
|
||||
INIT;
|
||||
|
||||
XSEQUENCE_1(ParseCurrencyAmount, ASN1_TAG_INTEGER, 1, &cur->currencyAmount);
|
||||
XSEQUENCE_1(ParseMultiplier, ASN1_TAG_INTEGER, 2, &cur->multiplier);
|
||||
XSEQUENCE_1(ParseCurrencyAmount, ASN1_TAG_CONTEXT_SPECIFIC, 1, &cur->currencyAmount);
|
||||
XSEQUENCE_1(ParseMultiplier, ASN1_TAG_CONTEXT_SPECIFIC, 2, &cur->multiplier);
|
||||
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
// CurrencyAmount
|
||||
|
||||
int
|
||||
ParseCurrencyAmount(struct asn1_parm *pc, u_char *p, u_char *end, int *currencyAmount)
|
||||
int ParseCurrencyAmount(struct asn1_parm *pc, u_char * p, u_char * end, unsigned int *currencyAmount)
|
||||
{
|
||||
return ParseInteger(pc, p, end, currencyAmount);
|
||||
return ParseUnsignedInteger(pc, p, end, currencyAmount);
|
||||
}
|
||||
|
||||
// Multiplier
|
||||
|
||||
int
|
||||
ParseMultiplier(struct asn1_parm *pc, u_char *p, u_char *end, int *multiplier)
|
||||
int ParseMultiplier(struct asn1_parm *pc, u_char * p, u_char * end, unsigned int *multiplier)
|
||||
{
|
||||
return ParseEnum(pc, p, end, multiplier);
|
||||
}
|
||||
|
||||
// TypeOfUnit
|
||||
|
||||
int
|
||||
ParseTypeOfUnit(struct asn1_parm *pc, u_char *p, u_char *end, int *typeOfUnit)
|
||||
int ParseTypeOfUnit(struct asn1_parm *pc, u_char * p, u_char * end, unsigned int *typeOfUnit)
|
||||
{
|
||||
return ParseInteger(pc, p, end, typeOfUnit);
|
||||
return ParseUnsignedInteger(pc, p, end, typeOfUnit);
|
||||
}
|
||||
|
||||
// NumberOfUnits
|
||||
|
||||
int
|
||||
ParseNumberOfUnits(struct asn1_parm *pc, u_char *p, u_char *end, int *numberOfUnits)
|
||||
int ParseNumberOfUnits(struct asn1_parm *pc, u_char * p, u_char * end, unsigned int *numberOfUnits)
|
||||
{
|
||||
return ParseInteger(pc, p, end, numberOfUnits);
|
||||
return ParseUnsignedInteger(pc, p, end, numberOfUnits);
|
||||
}
|
||||
|
||||
// Charging Association
|
||||
|
||||
int
|
||||
ParseChargingAssociation(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
int ParseChargingAssociation(struct asn1_parm *pc, u_char * p, u_char * end, struct ChargingAssociation *chargeAssoc)
|
||||
{
|
||||
// char partyNumber[30];
|
||||
INIT;
|
||||
struct FacPartyNumber partyNumber;
|
||||
|
||||
partyNumber.LengthOfNumber = 0;
|
||||
partyNumber.Number[0] = '\0';
|
||||
|
||||
XCHOICE_1(ParsePartyNumber_Full, ASN1_TAG_SEQUENCE, 0, &partyNumber);
|
||||
|
||||
if ((partyNumber.LengthOfNumber) && (partyNumber.LengthOfNumber <= 30)
|
||||
&& (partyNumber.Number[0] != '\0'))
|
||||
strcpy(chargeAssoc->chargeNumber, partyNumber.Number);
|
||||
|
||||
XCHOICE_1(ParseChargeIdentifier, ASN1_TAG_INTEGER, ASN1_NOT_TAGGED, &chargeAssoc->chargeIdentifier);
|
||||
|
||||
// XCHOICE_1(ParsePartyNumber, ASN1_TAG_SEQUENCE, 0, partyNumber);
|
||||
XCHOICE(ParseChargeIdentifier, ASN1_TAG_INTEGER, ASN1_NOT_TAGGED);
|
||||
XCHOICE_DEFAULT;
|
||||
}
|
||||
|
||||
// ChargeIdentifier
|
||||
|
||||
int
|
||||
ParseChargeIdentifier(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
int ParseChargeIdentifier(struct asn1_parm *pc, u_char * p, u_char * end, int *chargeIdentifier)
|
||||
{
|
||||
int chargeIdentifier;
|
||||
|
||||
return ParseInteger(pc, p, end, &chargeIdentifier);
|
||||
return ParseSignedInteger(pc, p, end, chargeIdentifier);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,8 +7,7 @@
|
|||
// ======================================================================
|
||||
// Basic Service Elements EN 300 196-1 D.6
|
||||
|
||||
int ParseBasicService(struct asn1_parm *pc, u_char *p, u_char *end, int *basicService)
|
||||
int ParseBasicService(struct asn1_parm *pc, u_char * p, u_char * end, int *basicService)
|
||||
{
|
||||
return ParseEnum(pc, p, end, basicService);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,67 +1,287 @@
|
|||
/* $Id: asn1_comp.c,v 1.3 2006/08/16 14:15:52 nadi Exp $
|
||||
/* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
#include "asn1.h"
|
||||
#include <stdio.h>
|
||||
#include "asn1_diversion.h"
|
||||
#include "asn1_ccbs.h"
|
||||
#include "asn1_ect.h"
|
||||
#include <string.h>
|
||||
|
||||
// ======================================================================
|
||||
// Component EN 300 196-1 D.1
|
||||
|
||||
int
|
||||
ParseInvokeId(struct asn1_parm *pc, u_char *p, u_char *end, int *invokeId)
|
||||
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[])
|
||||
{
|
||||
return ParseInteger(pc, p, end, invokeId);
|
||||
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, 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, 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;
|
||||
}
|
||||
|
||||
int
|
||||
ParseErrorValue(struct asn1_parm *pc, u_char *p, u_char *end, int *errorValue)
|
||||
static int ParseInvokeComponent(struct asn1_parm *pc, u_char * p, u_char * end, int dummy)
|
||||
{
|
||||
return ParseInteger(pc, p, end, errorValue);
|
||||
}
|
||||
|
||||
int
|
||||
ParseOperationValue(struct asn1_parm *pc, u_char *p, u_char *end, int *operationValue)
|
||||
{
|
||||
return ParseInteger(pc, p, end, operationValue);
|
||||
}
|
||||
|
||||
int
|
||||
ParseInvokeComponent(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
{
|
||||
int invokeId, operationValue;
|
||||
signed int invokeId;
|
||||
signed int linkedId;
|
||||
unsigned int operationValue;
|
||||
INIT;
|
||||
|
||||
pc->comp = invoke;
|
||||
XSEQUENCE_1(ParseInvokeId, ASN1_TAG_INTEGER, ASN1_NOT_TAGGED, &invokeId);
|
||||
// XSEQUENCE_OPT(ParseLinkedId, ASN1_TAG_INTEGER, 0);
|
||||
XSEQUENCE_1(ParseOperationValue, ASN1_TAG_INTEGER, ASN1_NOT_TAGGED, &operationValue);
|
||||
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_ActivationDiversion:
|
||||
XSEQUENCE_1(ParseActivationDiversion_ARG, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &pc->u.inv.o.ActivationDiversion);
|
||||
break;
|
||||
case Fac_DeactivationDiversion:
|
||||
XSEQUENCE_1(ParseDeactivationDiversion_ARG, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &pc->u.inv.o.DeactivationDiversion);
|
||||
break;
|
||||
case Fac_ActivationStatusNotificationDiv:
|
||||
XSEQUENCE_1(ParseActivationStatusNotificationDiv_ARG, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED,
|
||||
&pc->u.inv.o.ActivationStatusNotificationDiv);
|
||||
break;
|
||||
case Fac_DeactivationStatusNotificationDiv:
|
||||
XSEQUENCE_1(ParseDeactivationStatusNotificationDiv_ARG, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED,
|
||||
&pc->u.inv.o.DeactivationStatusNotificationDiv);
|
||||
break;
|
||||
case Fac_InterrogationDiversion:
|
||||
XSEQUENCE_1(ParseInterrogationDiversion_ARG, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED,
|
||||
&pc->u.inv.o.InterrogationDiversion);
|
||||
break;
|
||||
case Fac_DiversionInformation:
|
||||
XSEQUENCE_1(ParseDiversionInformation_ARG, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &pc->u.inv.o.DiversionInformation);
|
||||
break;
|
||||
case Fac_CallDeflection:
|
||||
XSEQUENCE_1(ParseCallDeflection_ARG, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &pc->u.inv.o.CallDeflection);
|
||||
break;
|
||||
case Fac_CallRerouteing:
|
||||
XSEQUENCE_1(ParseCallRerouteing_ARG, 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_ARG, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED,
|
||||
&pc->u.inv.o.DivertingLegInformation1);
|
||||
break;
|
||||
case Fac_DivertingLegInformation2:
|
||||
XSEQUENCE_1(ParseDivertingLegInformation2_ARG, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED,
|
||||
&pc->u.inv.o.DivertingLegInformation2);
|
||||
break;
|
||||
case Fac_DivertingLegInformation3:
|
||||
XSEQUENCE_1(ParseDivertingLegInformation3_ARG, 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_ARG, 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_ARG, 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_ARG, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &pc->u.inv.o.EctInform);
|
||||
break;
|
||||
case Fac_EctLoopTest:
|
||||
XSEQUENCE_1(ParseEctLoopTest_ARG, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &pc->u.inv.o.EctLoopTest);
|
||||
break;
|
||||
|
||||
/* AOC support */
|
||||
#if 0
|
||||
case 7: XSEQUENCE(ParseARGActivationDiversion, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED); break;
|
||||
case 8: XSEQUENCE(ParseARGDeactivationDiversion, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED); break;
|
||||
#endif
|
||||
case 9: XSEQUENCE_1(ParseARGActivationStatusNotificationDiv, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &pc->u.inv.o.actNot); break;
|
||||
case 10: XSEQUENCE_1(ParseARGDeactivationStatusNotificationDiv, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &pc->u.inv.o.deactNot); break;
|
||||
#if 0
|
||||
case 11: XSEQUENCE(ParseARGInterrogationDiversion, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED); break;
|
||||
case 12: XSEQUENCE(ParseARGDiversionInformation, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED); break;
|
||||
#endif
|
||||
case 13: XSEQUENCE_1(ParseARGReqCallDeflection, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &pc->u.inv.o.reqCD); break;
|
||||
#if 0
|
||||
case 17: XSEQUENCE(ParseARGInterrogateServedUserNumbers, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED); break;
|
||||
// case 30: XSEQUENCE(ParseChargingRequest, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED); break;
|
||||
// case 31: XSEQUENCE(ParseAOCSCurrency, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED); break;
|
||||
// case 32: XSEQUENCE(ParseAOCSSpecialArr, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED); break;
|
||||
#endif
|
||||
case 33: XSEQUENCE_1(ParseAOCDCurrency, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &pc->u.inv.o.AOCDcur); break;
|
||||
case 34: XSEQUENCE_1(ParseAOCDChargingUnit, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &pc->u.inv.o.AOCDchu); break;
|
||||
#if 0
|
||||
case 35: XSEQUENCE(ParseAOCECurrency, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED); break;
|
||||
case 36: XSEQUENCE(ParseAOCEChargingUnit, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED); break;
|
||||
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_ARG, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &pc->u.inv.o.StatusRequest);
|
||||
break;
|
||||
|
||||
/* CCBS/CCNR support */
|
||||
case Fac_CallInfoRetain:
|
||||
XSEQUENCE_1(ParseCallInfoRetain_ARG, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &pc->u.inv.o.CallInfoRetain);
|
||||
break;
|
||||
case Fac_CCBSRequest:
|
||||
XSEQUENCE_1(ParseCCBSRequest_ARG, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &pc->u.inv.o.CCBSRequest);
|
||||
break;
|
||||
case Fac_CCBSDeactivate:
|
||||
XSEQUENCE_1(ParseCCBSDeactivate_ARG, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &pc->u.inv.o.CCBSDeactivate);
|
||||
break;
|
||||
case Fac_CCBSInterrogate:
|
||||
XSEQUENCE_1(ParseCCBSInterrogate_ARG, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &pc->u.inv.o.CCBSInterrogate);
|
||||
break;
|
||||
case Fac_CCBSErase:
|
||||
XSEQUENCE_1(ParseCCBSErase_ARG, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &pc->u.inv.o.CCBSErase);
|
||||
break;
|
||||
case Fac_CCBSRemoteUserFree:
|
||||
XSEQUENCE_1(ParseCCBSRemoteUserFree_ARG, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &pc->u.inv.o.CCBSRemoteUserFree);
|
||||
break;
|
||||
case Fac_CCBSCall:
|
||||
XSEQUENCE_1(ParseCCBSCall_ARG, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &pc->u.inv.o.CCBSCall);
|
||||
break;
|
||||
case Fac_CCBSStatusRequest:
|
||||
XSEQUENCE_1(ParseCCBSStatusRequest_ARG, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &pc->u.inv.o.CCBSStatusRequest);
|
||||
break;
|
||||
case Fac_CCBSBFree:
|
||||
XSEQUENCE_1(ParseCCBSBFree_ARG, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &pc->u.inv.o.CCBSBFree);
|
||||
break;
|
||||
case Fac_EraseCallLinkageID:
|
||||
XSEQUENCE_1(ParseEraseCallLinkageID_ARG, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &pc->u.inv.o.EraseCallLinkageID);
|
||||
break;
|
||||
case Fac_CCBSStopAlerting:
|
||||
XSEQUENCE_1(ParseCCBSStopAlerting_ARG, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &pc->u.inv.o.CCBSStopAlerting);
|
||||
break;
|
||||
case Fac_CCNRRequest:
|
||||
XSEQUENCE_1(ParseCCNRRequest_ARG, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &pc->u.inv.o.CCNRRequest);
|
||||
break;
|
||||
case Fac_CCNRInterrogate:
|
||||
XSEQUENCE_1(ParseCCNRInterrogate_ARG, 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_ARG, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &pc->u.inv.o.CCBS_T_Request);
|
||||
break;
|
||||
case Fac_CCNR_T_Request:
|
||||
XSEQUENCE_1(ParseCCNR_T_Request_ARG, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &pc->u.inv.o.CCNR_T_Request);
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
@ -69,92 +289,247 @@ ParseInvokeComponent(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
|||
return p - beg;
|
||||
}
|
||||
|
||||
int
|
||||
ParseReturnResultComponentSequence(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
int ParseReturnResultComponentSequence(struct asn1_parm *pc, u_char * p, u_char * end, int dummy)
|
||||
{
|
||||
int operationValue;
|
||||
INIT;
|
||||
|
||||
XSEQUENCE_1(ParseOperationValue, ASN1_TAG_INTEGER, ASN1_NOT_TAGGED, &operationValue);
|
||||
switch (operationValue) {
|
||||
case 11: XSEQUENCE(ParseRESInterrogationDiversion, ASN1_TAG_SET, ASN1_NOT_TAGGED); break;
|
||||
case 17: XSEQUENCE(ParseRESInterrogateServedUserNumbers, ASN1_TAG_SET, ASN1_NOT_TAGGED); break;
|
||||
default: return -1;
|
||||
XSEQUENCE_1(ParseOperationValue, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &pc->u.retResult.operationValue);
|
||||
pc->u.retResult.operationValuePresent = 1;
|
||||
|
||||
switch (pc->u.retResult.operationValue) {
|
||||
/* 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;
|
||||
|
||||
#if 0
|
||||
/* AOC support */
|
||||
case Fac_ChargingRequest:
|
||||
break;
|
||||
#endif
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
int
|
||||
ParseReturnResultComponent(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
static int ParseReturnResultComponent(struct asn1_parm *pc, u_char * p, u_char * end, int dummy)
|
||||
{
|
||||
int invokeId;
|
||||
signed int invokeId;
|
||||
INIT;
|
||||
|
||||
pc->comp = returnResult;
|
||||
XSEQUENCE_1(ParseInvokeId, ASN1_TAG_INTEGER, ASN1_NOT_TAGGED, &invokeId);
|
||||
XSEQUENCE_OPT(ParseReturnResultComponentSequence, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED);
|
||||
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;
|
||||
}
|
||||
|
||||
int
|
||||
ParseReturnErrorComponent(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
static int ParseErrorOid(struct asn1_parm *pc, u_char * p, u_char * end, int *errorValue)
|
||||
{
|
||||
int invokeId;
|
||||
int errorValue;
|
||||
char error[80];
|
||||
INIT;
|
||||
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, 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;
|
||||
int errorValue;
|
||||
#if defined(ASN1_DEBUG)
|
||||
char *error;
|
||||
char msg[20];
|
||||
#endif /* defined(ASN1_DEBUG) */
|
||||
INIT;
|
||||
|
||||
pc->comp = returnError;
|
||||
|
||||
XSEQUENCE_1(ParseInvokeId, ASN1_TAG_INTEGER, ASN1_NOT_TAGGED, &invokeId);
|
||||
XSEQUENCE_1(ParseErrorValue, ASN1_TAG_INTEGER, ASN1_NOT_TAGGED, &errorValue);
|
||||
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;
|
||||
|
||||
#if defined(ASN1_DEBUG)
|
||||
switch (errorValue) {
|
||||
case 0: sprintf(error, "not subscribed"); break;
|
||||
case 3: sprintf(error, "not available"); break;
|
||||
case 4: sprintf(error, "not implemented"); break;
|
||||
case 6: sprintf(error, "invalid served user nr"); break;
|
||||
case 7: sprintf(error, "invalid call state"); break;
|
||||
case 8: sprintf(error, "basic service not provided"); break;
|
||||
case 9: sprintf(error, "not incoming call"); break;
|
||||
case 10: sprintf(error, "supplementary service interaction not allowed"); break;
|
||||
case 11: sprintf(error, "resource unavailable"); break;
|
||||
case 12: sprintf(error, "invalid diverted-to nr"); break;
|
||||
case 14: sprintf(error, "special service nr"); break;
|
||||
case 15: sprintf(error, "diversion to served user nr"); break;
|
||||
case 23: sprintf(error, "incoming call accepted"); break;
|
||||
case 24: sprintf(error, "number of diversions exceeded"); break;
|
||||
case 46: sprintf(error, "not activated"); break;
|
||||
case 48: sprintf(error, "request already accepted"); break;
|
||||
default: sprintf(error, "(%d)", errorValue); break;
|
||||
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;
|
||||
}
|
||||
print_asn1msg(PRT_DEBUG_DECODE, "ReturnError: %s\n", error);
|
||||
print_asn1msg(PRT_DEBUG_DECODE, "%s Decoded-Error: %s\n", __FUNCTION__, error);
|
||||
#endif /* defined(ASN1_DEBUG) */
|
||||
|
||||
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);
|
||||
print_asn1msg(PRT_DEBUG_DECODE, "ParseProblemValue: %d %d, rval:%d\n", prob, pc->u.reject.problemValue, rval);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
int
|
||||
ParseProblemValue(struct asn1_parm *pc, u_char *p, u_char *end, asn1Problem prob)
|
||||
int ParseRejectProblem(struct asn1_parm *pc, u_char * p, u_char * end, int dummy)
|
||||
{
|
||||
INIT;
|
||||
|
||||
pc->u.reject.problem = prob;
|
||||
|
||||
print_asn1msg(PRT_DEBUG_DECODE, "ParseProblemValue: %d %d\n", prob, *p);
|
||||
pc->u.reject.problemValue = *p++;
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
int
|
||||
ParseRejectProblem(struct asn1_parm *pc, u_char *p, u_char *end)
|
||||
{
|
||||
INIT;
|
||||
|
||||
XCHOICE_1(ParseProblemValue, ASN1_TAG_CONTEXT_SPECIFIC, 0, GeneralP);
|
||||
XCHOICE_1(ParseProblemValue, ASN1_TAG_CONTEXT_SPECIFIC, 1, InvokeP);
|
||||
|
@ -163,62 +538,43 @@ ParseRejectProblem(struct asn1_parm *pc, u_char *p, u_char *end)
|
|||
XCHOICE_DEFAULT;
|
||||
}
|
||||
|
||||
int
|
||||
ParseRejectComponent(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
static int ParseRejectInvokeId(struct asn1_parm *pc, u_char * p, u_char * end, int dummy)
|
||||
{
|
||||
int invokeId = -1;
|
||||
int rval;
|
||||
INIT;
|
||||
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 = reject;
|
||||
|
||||
XSEQUENCE_OPT_1(ParseInvokeId, ASN1_TAG_INTEGER, ASN1_NOT_TAGGED, &invokeId);
|
||||
XSEQUENCE_OPT(ParseNull, ASN1_TAG_NULL, ASN1_NOT_TAGGED);
|
||||
|
||||
print_asn1msg(PRT_DEBUG_DECODE, "ParseRejectComponent: invokeId %d\n", invokeId);
|
||||
XSEQUENCE(ParseRejectInvokeId, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED);
|
||||
if (pc->u.reject.invokeIdPresent) {
|
||||
print_asn1msg(PRT_DEBUG_DECODE, "ParseRejectComponent: invokeId %d\n", pc->u.reject.invokeId);
|
||||
}
|
||||
|
||||
pc->u.reject.invokeId = invokeId;
|
||||
|
||||
rval = ParseRejectProblem(pc, p, end);
|
||||
|
||||
print_asn1msg(PRT_DEBUG_DECODE, "ParseRejectComponent: rval %d\n", rval);
|
||||
|
||||
if (rval > 0)
|
||||
p += rval;
|
||||
else
|
||||
return(-1);
|
||||
XSEQUENCE(ParseRejectProblem, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED);
|
||||
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
int
|
||||
ParseUnknownComponent(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
int ParseComponent(struct asn1_parm *pc, u_char * p, u_char * end)
|
||||
{
|
||||
INIT;
|
||||
|
||||
pc->comp = tag;
|
||||
return end - beg;
|
||||
}
|
||||
|
||||
int
|
||||
ParseComponent(struct asn1_parm *pc, u_char *p, u_char *end)
|
||||
{
|
||||
INIT;
|
||||
|
||||
XCHOICE(ParseInvokeComponent, ASN1_TAG_SEQUENCE, 1);
|
||||
XCHOICE(ParseReturnResultComponent, ASN1_TAG_SEQUENCE, 2);
|
||||
XCHOICE(ParseReturnErrorComponent, ASN1_TAG_SEQUENCE, 3);
|
||||
XCHOICE(ParseRejectComponent, ASN1_TAG_SEQUENCE, 4);
|
||||
XCHOICE(ParseUnknownComponent, ASN1_TAG_SEQUENCE, 5);
|
||||
XCHOICE(ParseUnknownComponent, ASN1_TAG_SEQUENCE, 6);
|
||||
XCHOICE(ParseUnknownComponent, ASN1_TAG_SEQUENCE, 7);
|
||||
XCHOICE(ParseUnknownComponent, ASN1_TAG_SEQUENCE, 8);
|
||||
XCHOICE(ParseUnknownComponent, ASN1_TAG_SEQUENCE, 9);
|
||||
XCHOICE(ParseUnknownComponent, ASN1_TAG_SEQUENCE, 10);
|
||||
XCHOICE(ParseUnknownComponent, ASN1_TAG_SEQUENCE, 11);
|
||||
XCHOICE(ParseUnknownComponent, ASN1_TAG_SEQUENCE, 12);
|
||||
XCHOICE(ParseUnknownComponent, ASN1_TAG_SEQUENCE, 13);
|
||||
XCHOICE(ParseUnknownComponent, ASN1_TAG_SEQUENCE, 14);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,9 +1,79 @@
|
|||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Diversion Supplementary Services ETS 300 207-1 Table 3
|
||||
*
|
||||
* Diversion Facility ie encode/decode header
|
||||
*/
|
||||
|
||||
#ifndef __ASN1_DIVERSION_H__
|
||||
#define __ASN1_DIVERSION_H__
|
||||
|
||||
int encodeActivationDiversion(__u8 *dest, struct FacCFActivate *CFActivate);
|
||||
int encodeDeactivationDiversion(__u8 *dest, struct FacCFDeactivate *CFDeactivate);
|
||||
int encodeInterrogationDiversion(__u8 *dest, struct FacCFInterrogateParameters *params);
|
||||
int encodeInvokeDeflection(__u8 *dest, struct FacCDeflection *CD);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
|
||||
int encodeFacActivationDiversion(__u8 * Dest, const struct FacActivationDiversion *ActivationDiversion);
|
||||
int ParseActivationDiversion_ARG(struct asn1_parm *pc, u_char * p, u_char * end,
|
||||
struct FacActivationDiversion_ARG *ActivationDiversion);
|
||||
|
||||
int encodeFacDeactivationDiversion(__u8 * Dest, const struct FacDeactivationDiversion *DeactivationDiversion);
|
||||
int ParseDeactivationDiversion_ARG(struct asn1_parm *pc, u_char * p, u_char * end,
|
||||
struct FacDeactivationDiversion_ARG *DeactivationDiversion);
|
||||
|
||||
int encodeFacActivationStatusNotificationDiv(__u8 * Dest,
|
||||
const struct FacActivationStatusNotificationDiv
|
||||
*ActivationStatusNotificationDiv);
|
||||
int ParseActivationStatusNotificationDiv_ARG(struct asn1_parm *pc, u_char * p, u_char * end,
|
||||
struct FacActivationStatusNotificationDiv *ActivationStatusNotificationDiv);
|
||||
|
||||
int encodeFacDeactivationStatusNotificationDiv(__u8 * Dest,
|
||||
const struct FacDeactivationStatusNotificationDiv
|
||||
*DeactivationStatusNotificationDiv);
|
||||
int ParseDeactivationStatusNotificationDiv_ARG(struct asn1_parm *pc, u_char * p, u_char * end,
|
||||
struct FacDeactivationStatusNotificationDiv
|
||||
*DeactivationStatusNotificationDiv);
|
||||
|
||||
int encodeFacInterrogationDiversion(__u8 * Dest, const struct FacInterrogationDiversion *InterrogationDiversion);
|
||||
int ParseInterrogationDiversion_ARG(struct asn1_parm *pc, u_char * p, u_char * end,
|
||||
struct FacInterrogationDiversion_ARG *InterrogationDiversion);
|
||||
#define ParseInterrogationDiversion_RES ParseIntResultList
|
||||
int ParseIntResultList(struct asn1_parm *pc, u_char * p, u_char * end, struct FacForwardingList *IntResultList);
|
||||
|
||||
int encodeFacDiversionInformation(__u8 * Dest, const struct FacDiversionInformation *DiversionInformation);
|
||||
int ParseDiversionInformation_ARG(struct asn1_parm *pc, u_char * p, u_char * end,
|
||||
struct FacDiversionInformation *DiversionInformation);
|
||||
|
||||
int encodeFacCallDeflection(__u8 * Dest, const struct FacCallDeflection *CallDeflection);
|
||||
int ParseCallDeflection_ARG(struct asn1_parm *pc, u_char * p, u_char * end, struct FacCallDeflection_ARG *CallDeflection);
|
||||
|
||||
int encodeFacCallRerouteing(__u8 * Dest, const struct FacCallRerouteing *CallRerouteing);
|
||||
int ParseCallRerouteing_ARG(struct asn1_parm *pc, u_char * p, u_char * end, struct FacCallRerouteing_ARG *CallRerouteing);
|
||||
|
||||
int encodeFacInterrogateServedUserNumbers(__u8 * Dest,
|
||||
const struct FacInterrogateServedUserNumbers *InterrogateServedUserNumbers);
|
||||
#define ParseInterrogateServedUserNumbers_RES ParseServedUserNumberList
|
||||
int ParseServedUserNumberList(struct asn1_parm *pc, u_char * p, u_char * end,
|
||||
struct FacServedUserNumberList *ServedUserNumberList);
|
||||
|
||||
int encodeFacDivertingLegInformation1(__u8 * Dest, const struct FacDivertingLegInformation1 *DivertingLegInformation1);
|
||||
int ParseDivertingLegInformation1_ARG(struct asn1_parm *pc, u_char * p, u_char * end,
|
||||
struct FacDivertingLegInformation1 *DivertingLegInformation1);
|
||||
|
||||
int encodeFacDivertingLegInformation2(__u8 * Dest, const struct FacDivertingLegInformation2 *DivertingLegInformation2);
|
||||
int ParseDivertingLegInformation2_ARG(struct asn1_parm *pc, u_char * p, u_char * end,
|
||||
struct FacDivertingLegInformation2 *DivertingLegInformation2);
|
||||
|
||||
int encodeFacDivertingLegInformation3(__u8 * Dest, const struct FacDivertingLegInformation3 *DivertingLegInformation3);
|
||||
int ParseDivertingLegInformation3_ARG(struct asn1_parm *pc, u_char * p, u_char * end,
|
||||
struct FacDivertingLegInformation3 *DivertingLegInformation3);
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __ASN1_DIVERSION_H__ */
|
||||
/* ------------------------------------------------------------------- *//* end asn1_diversion.h */
|
||||
|
|
|
@ -1,134 +1,161 @@
|
|||
/* $Id: asn1_enc.c,v 1.2 2006/08/16 14:15:52 nadi Exp $
|
||||
/* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
#include "asn1.h"
|
||||
#include <string.h>
|
||||
|
||||
int encodeNull(__u8 *dest)
|
||||
int encodeLen_Long_u8(__u8 * dest, __u8 length)
|
||||
{
|
||||
dest[0] = 0x05; // null
|
||||
dest[1] = 0; // length
|
||||
dest[0] = 0x80 + ASN1_NUM_OCTETS_LONG_LENGTH_u8 - 1;
|
||||
dest[1] = length;
|
||||
return ASN1_NUM_OCTETS_LONG_LENGTH_u8;
|
||||
} /* end encodeLen_Long_u8() */
|
||||
|
||||
int encodeLen_Long_u16(__u8 * dest, __u16 length)
|
||||
{
|
||||
dest[0] = 0x80 + ASN1_NUM_OCTETS_LONG_LENGTH_u16 - 1;
|
||||
dest[1] = (length >> 8) & 0xFF;
|
||||
dest[2] = length & 0xFF;
|
||||
return ASN1_NUM_OCTETS_LONG_LENGTH_u16;
|
||||
} /* end encodeLen_Long_u16() */
|
||||
|
||||
int encodeNull(__u8 * dest, __u8 tagType)
|
||||
{
|
||||
dest[0] = tagType;
|
||||
dest[1] = 0; /* length */
|
||||
return 2;
|
||||
}
|
||||
|
||||
int encodeBoolean(__u8 *dest, __u32 i)
|
||||
int encodeBoolean(__u8 * dest, __u8 tagType, __u32 i)
|
||||
{
|
||||
dest[0] = 0x01; // BOOLEAN
|
||||
dest[1] = 1; // length 1
|
||||
dest[2] = i ? 1:0; // Value
|
||||
dest[0] = tagType;
|
||||
dest[1] = 1; /* length */
|
||||
dest[2] = i ? 1 : 0; /* value */
|
||||
return 3;
|
||||
}
|
||||
|
||||
int encodeInt(__u8 *dest, __u32 i)
|
||||
int encodeInt(__u8 * dest, __u8 tagType, __s32 i)
|
||||
{
|
||||
unsigned count;
|
||||
__u32 test_mask;
|
||||
__u32 value;
|
||||
__u8 *p;
|
||||
|
||||
dest[0] = 0x02; // integer
|
||||
dest[1] = 0; // length
|
||||
dest[0] = tagType;
|
||||
|
||||
/* Find most significant octet of 32 bit integer that carries meaning. */
|
||||
test_mask = 0xFF800000;
|
||||
value = (__u32) i;
|
||||
for (count = 4; --count;) {
|
||||
if ((value & test_mask) != test_mask && (value & test_mask) != 0) {
|
||||
/*
|
||||
* The first 9 bits of a multiple octet integer is not
|
||||
* all ones or zeroes.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
test_mask >>= 8;
|
||||
} /* end for */
|
||||
|
||||
/* length */
|
||||
dest[1] = count + 1;
|
||||
|
||||
/* Store value */
|
||||
p = &dest[2];
|
||||
do {
|
||||
*p++ = i;
|
||||
i >>= 8;
|
||||
} while (i);
|
||||
value = (__u32) i;
|
||||
value >>= (8 * count);
|
||||
*p++ = value & 0xFF;
|
||||
} while (count--);
|
||||
|
||||
dest[1] = p - &dest[2];
|
||||
return p - dest;
|
||||
}
|
||||
|
||||
int encodeEnum(__u8 *dest, __u32 i)
|
||||
int encodeEnum(__u8 * dest, __u8 tagType, __s32 i)
|
||||
{
|
||||
__u8 *p;
|
||||
|
||||
dest[0] = 0x0a; // integer
|
||||
dest[1] = 0; // length
|
||||
p = &dest[2];
|
||||
do {
|
||||
*p++ = i;
|
||||
i >>= 8;
|
||||
} while (i);
|
||||
|
||||
dest[1] = p - &dest[2];
|
||||
return p - dest;
|
||||
return encodeInt(dest, tagType, i);
|
||||
}
|
||||
|
||||
int encodeNumberDigits(__u8 *dest, __s8 *nd, __u8 len)
|
||||
/*
|
||||
* Use to encode the following string types:
|
||||
* ASN1_TAG_OCTET_STRING
|
||||
* ASN1_TAG_NUMERIC_STRING
|
||||
* ASN1_TAG_PRINTABLE_STRING
|
||||
* ASN1_TAG_IA5_STRING
|
||||
*
|
||||
* Note The string length MUST be less than 128 characters.
|
||||
*/
|
||||
static int encodeString(__u8 * dest, __u8 tagType, const __s8 * str, __u8 len)
|
||||
{
|
||||
__u8 *p;
|
||||
int i;
|
||||
|
||||
dest[0] = 0x12; // numeric string
|
||||
dest[1] = 0x0; // length
|
||||
dest[0] = tagType;
|
||||
|
||||
/* Store value */
|
||||
p = &dest[2];
|
||||
for (i = 0; i < len; i++)
|
||||
*p++ = *nd++;
|
||||
*p++ = *str++;
|
||||
|
||||
/* length */
|
||||
dest[1] = p - &dest[2];
|
||||
|
||||
return p - dest;
|
||||
}
|
||||
|
||||
int encodePublicPartyNumber(__u8 *dest, __s8 *facilityPartyNumber)
|
||||
int encodeOctetString(__u8 * dest, __u8 tagType, const __s8 * str, __u8 len)
|
||||
{
|
||||
return encodeString(dest, tagType, str, len);
|
||||
} /* end encodeOctetString() */
|
||||
|
||||
int encodeNumericString(__u8 * dest, __u8 tagType, const __s8 * str, __u8 len)
|
||||
{
|
||||
return encodeString(dest, tagType, str, len);
|
||||
} /* end encodeNumericString() */
|
||||
|
||||
int encodePrintableString(__u8 * dest, __u8 tagType, const __s8 * str, __u8 len)
|
||||
{
|
||||
return encodeString(dest, tagType, str, len);
|
||||
} /* end encodePrintableString() */
|
||||
|
||||
int encodeIA5String(__u8 * dest, __u8 tagType, const __s8 * str, __u8 len)
|
||||
{
|
||||
return encodeString(dest, tagType, str, len);
|
||||
} /* end encodeIA5String() */
|
||||
|
||||
int encodeOid(__u8 * dest, __u8 tagType, const struct asn1Oid *oid)
|
||||
{
|
||||
unsigned numValues;
|
||||
unsigned count;
|
||||
__u32 value;
|
||||
__u8 *p;
|
||||
|
||||
dest[0] = 0x20; // sequence
|
||||
dest[1] = 0; // length
|
||||
dest[0] = tagType;
|
||||
|
||||
/* For all OID subidentifer values */
|
||||
p = &dest[2];
|
||||
p += encodeEnum(p, (facilityPartyNumber[2] & 0x70) >> 4);
|
||||
p += encodeNumberDigits(p, &facilityPartyNumber[4], facilityPartyNumber[0] - 3);
|
||||
for (numValues = 0; numValues < oid->numValues; ++numValues) {
|
||||
/*
|
||||
* Count the number of 7 bit chunks that are needed
|
||||
* to encode the integer.
|
||||
*/
|
||||
value = oid->value[numValues] >> 7;
|
||||
for (count = 0; value; ++count) {
|
||||
/* There are bits still set */
|
||||
value >>= 7;
|
||||
} /* end for */
|
||||
|
||||
/* Store OID subidentifier value */
|
||||
do {
|
||||
value = oid->value[numValues];
|
||||
value >>= (7 * count);
|
||||
*p++ = (value & 0x7F) | (count ? 0x80 : 0);
|
||||
} while (count--);
|
||||
} /* end for */
|
||||
|
||||
/* length */
|
||||
dest[1] = p - &dest[2];
|
||||
|
||||
return p - dest;
|
||||
}
|
||||
|
||||
int encodePartyNumber(__u8 *dest, __s8 *facilityPartyNumber)
|
||||
{
|
||||
__u8 *p = dest;
|
||||
|
||||
p += encodeNumberDigits(p, facilityPartyNumber, strlen((char *)facilityPartyNumber));
|
||||
dest[0] = 0x80;
|
||||
#if 0
|
||||
switch (facilityPartyNumber[1]) {
|
||||
case 0: // unknown
|
||||
p += encodeNumberDigits(p, &facilityPartyNumber[4], facilityPartyNumber[0] - 3);
|
||||
dest[0] &= 0x20;
|
||||
dest[0] |= 0x81;
|
||||
break;
|
||||
case 1: // publicPartyNumber
|
||||
p += encodePublicPartyNumber(p, facilityPartyNumber);
|
||||
dest[0] &= 0x20;
|
||||
dest[0] |= 0x81;
|
||||
break;
|
||||
default:
|
||||
int_error();
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
return p - dest;
|
||||
}
|
||||
|
||||
int encodeServedUserNumber(__u8 *dest, __s8 *servedUserNumber)
|
||||
{
|
||||
if (servedUserNumber[0])
|
||||
return encodePartyNumber(dest, servedUserNumber);
|
||||
else
|
||||
return encodeNull(dest);
|
||||
}
|
||||
|
||||
int encodeAddress(__u8 *dest, __s8 *facilityPartyNumber, __s8 *calledPartySubaddress)
|
||||
{
|
||||
__u8 *p = dest;
|
||||
|
||||
dest[0] = 0x30; // invoke id tag, integer
|
||||
dest[1] = 0; // length
|
||||
p = &dest[2];
|
||||
|
||||
p += encodePartyNumber(p, facilityPartyNumber);
|
||||
#if 0 // FIXME
|
||||
if (calledPartySubaddress[0])
|
||||
p += encodePartySubaddress(p, calledPartySubaddress);
|
||||
#endif
|
||||
dest[1] = p - &dest[2];
|
||||
return p - dest;
|
||||
}
|
||||
|
||||
} /* end encodeOid() */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: asn1_generic.c,v 1.3 2006/08/16 14:15:52 nadi Exp $
|
||||
/* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -7,106 +7,231 @@
|
|||
// ======================================================================
|
||||
// general ASN.1
|
||||
|
||||
int
|
||||
ParseBoolean(struct asn1_parm *pc, u_char *p, u_char *end, int *i)
|
||||
int ParseBoolean(struct asn1_parm *pc, u_char * p, u_char * end, int *i)
|
||||
{
|
||||
INIT;
|
||||
|
||||
*i = 0;
|
||||
while (len--) {
|
||||
CHECK_P;
|
||||
*i = (*i >> 8) + *p;
|
||||
p++;
|
||||
}
|
||||
CHECK_P;
|
||||
*i = *p ? 1 : 0;
|
||||
print_asn1msg(PRT_DEBUG_DECODE, " DEBUG> BOOL = %d %#x\n", *i, *i);
|
||||
return p - beg;
|
||||
return end - beg;
|
||||
}
|
||||
|
||||
int
|
||||
ParseNull(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
int ParseNull(struct asn1_parm *pc, u_char * p, u_char * end, int dummy)
|
||||
{
|
||||
INIT;
|
||||
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
int
|
||||
ParseInteger(struct asn1_parm *pc, u_char *p, u_char *end, int *i)
|
||||
static int ParseUInt(struct asn1_parm *pc, u_char * p, u_char * end, unsigned int *i)
|
||||
{
|
||||
INIT;
|
||||
|
||||
CHECK_P;
|
||||
*i = 0;
|
||||
while (len--) {
|
||||
CHECK_P;
|
||||
*i = (*i << 8) + *p;
|
||||
*i = (*i << 8) | *p;
|
||||
p++;
|
||||
}
|
||||
return p - beg;
|
||||
} /* end ParseInt() */
|
||||
|
||||
static int ParseSInt(struct asn1_parm *pc, u_char * p, u_char * end, signed int *i)
|
||||
{
|
||||
INIT;
|
||||
|
||||
CHECK_P;
|
||||
/* Read value as signed */
|
||||
if (*p & 0x80) {
|
||||
/* The value is negative */
|
||||
*i = -1;
|
||||
} else {
|
||||
*i = 0;
|
||||
}
|
||||
while (len--) {
|
||||
*i = (*i << 8) | *p;
|
||||
p++;
|
||||
}
|
||||
return p - beg;
|
||||
} /* end ParseInt() */
|
||||
|
||||
int ParseUnsignedInteger(struct asn1_parm *pc, u_char * p, u_char * end, unsigned int *i)
|
||||
{
|
||||
int length;
|
||||
|
||||
length = ParseUInt(pc, p, end, i);
|
||||
print_asn1msg(PRT_DEBUG_DECODE, " DEBUG> INT = %d %#x\n", *i, *i);
|
||||
return p - beg;
|
||||
return length;
|
||||
}
|
||||
|
||||
int
|
||||
ParseEnum(struct asn1_parm *pc, u_char *p, u_char *end, int *i)
|
||||
int ParseSignedInteger(struct asn1_parm *pc, u_char * p, u_char * end, signed int *i)
|
||||
{
|
||||
INIT;
|
||||
int length;
|
||||
|
||||
*i = 0;
|
||||
while (len--) {
|
||||
CHECK_P;
|
||||
*i = (*i << 8) + *p;
|
||||
p++;
|
||||
}
|
||||
length = ParseSInt(pc, p, end, i);
|
||||
print_asn1msg(PRT_DEBUG_DECODE, " DEBUG> INT = %d %#x\n", *i, *i);
|
||||
return length;
|
||||
}
|
||||
|
||||
int ParseEnum(struct asn1_parm *pc, u_char * p, u_char * end, unsigned int *i)
|
||||
{
|
||||
int length;
|
||||
|
||||
length = ParseUInt(pc, p, end, i);
|
||||
print_asn1msg(PRT_DEBUG_DECODE, " DEBUG> ENUM = %d %#x\n", *i, *i);
|
||||
return p - beg;
|
||||
return length;
|
||||
}
|
||||
|
||||
int
|
||||
ParseIA5String(struct asn1_parm *pc, u_char *p, u_char *end, char *str)
|
||||
int ParseIA5String(struct asn1_parm *pc, u_char * p, u_char * end, struct asn1ParseString *str)
|
||||
{
|
||||
char *buf;
|
||||
int numChars;
|
||||
INIT;
|
||||
|
||||
if (len < 0) {
|
||||
/* We do not handle indefinite length strings */
|
||||
return -1;
|
||||
}
|
||||
|
||||
print_asn1msg(PRT_DEBUG_DECODE, " DEBUG> IA5 = ");
|
||||
while (len--) {
|
||||
CHECK_P;
|
||||
print_asn1msg(PRT_DEBUG_DECODE, "%c", *p);
|
||||
*str++ = *p;
|
||||
p++;
|
||||
if (str->maxSize < len + 1) {
|
||||
numChars = str->maxSize - 1;
|
||||
} else {
|
||||
numChars = len;
|
||||
}
|
||||
len -= numChars;
|
||||
str->length = numChars;
|
||||
buf = str->buf;
|
||||
while (numChars--) {
|
||||
print_asn1msg(PRT_DEBUG_DECODE, "%c", *p);
|
||||
*buf++ = *p++;
|
||||
} /* end while */
|
||||
print_asn1msg(PRT_DEBUG_DECODE, "\n");
|
||||
*str = 0;
|
||||
*buf = 0;
|
||||
if (0 < len) {
|
||||
/* Discard the remainder of the string. We have no room left. */
|
||||
p += len;
|
||||
}
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
int
|
||||
ParseNumericString(struct asn1_parm *pc, u_char *p, u_char *end, char *str)
|
||||
int ParseNumericString(struct asn1_parm *pc, u_char * p, u_char * end, struct asn1ParseString *str)
|
||||
{
|
||||
char *buf;
|
||||
int numChars;
|
||||
INIT;
|
||||
|
||||
if (len < 0) {
|
||||
/* We do not handle indefinite length strings */
|
||||
return -1;
|
||||
}
|
||||
|
||||
print_asn1msg(PRT_DEBUG_DECODE, " DEBUG> NumStr = ");
|
||||
while (len--) {
|
||||
CHECK_P;
|
||||
print_asn1msg(PRT_DEBUG_DECODE, "%c", *p);
|
||||
*str++ = *p;
|
||||
p++;
|
||||
if (str->maxSize < len + 1) {
|
||||
numChars = str->maxSize - 1;
|
||||
} else {
|
||||
numChars = len;
|
||||
}
|
||||
len -= numChars;
|
||||
str->length = numChars;
|
||||
buf = str->buf;
|
||||
while (numChars--) {
|
||||
print_asn1msg(PRT_DEBUG_DECODE, "%c", *p);
|
||||
*buf++ = *p++;
|
||||
} /* end while */
|
||||
print_asn1msg(PRT_DEBUG_DECODE, "\n");
|
||||
*str = 0;
|
||||
*buf = 0;
|
||||
if (0 < len) {
|
||||
/* Discard the remainder of the string. We have no room left. */
|
||||
p += len;
|
||||
}
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
int
|
||||
ParseOctetString(struct asn1_parm *pc, u_char *p, u_char *end, char *str)
|
||||
int ParseOctetString(struct asn1_parm *pc, u_char * p, u_char * end, struct asn1ParseString *str)
|
||||
{
|
||||
char *buf;
|
||||
INIT;
|
||||
|
||||
print_asn1msg(PRT_DEBUG_DECODE, " DEBUG> Octets = ");
|
||||
while (len--) {
|
||||
CHECK_P;
|
||||
print_asn1msg(PRT_DEBUG_DECODE, " %02x", *p);
|
||||
*str++ = *p;
|
||||
p++;
|
||||
if (len < 0) {
|
||||
/* We do not handle indefinite length strings */
|
||||
return -1;
|
||||
}
|
||||
if (str->maxSize < len + 1) {
|
||||
/*
|
||||
* The octet string will not fit in the available buffer
|
||||
* and truncating it is not a good idea in all cases.
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
print_asn1msg(PRT_DEBUG_DECODE, " DEBUG> Octets = ");
|
||||
str->length = len;
|
||||
buf = str->buf;
|
||||
while (len--) {
|
||||
print_asn1msg(PRT_DEBUG_DECODE, " %02x", *p);
|
||||
*buf++ = *p++;
|
||||
} /* end while */
|
||||
print_asn1msg(PRT_DEBUG_DECODE, "\n");
|
||||
*str = 0;
|
||||
*buf = 0;
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
int ParseOid(struct asn1_parm *pc, u_char * p, u_char * end, struct asn1Oid *oid)
|
||||
{
|
||||
int numValues;
|
||||
int value;
|
||||
#if defined(ASN1_DEBUG)
|
||||
int delimiter;
|
||||
#endif /* defined(ASN1_DEBUG) */
|
||||
INIT;
|
||||
|
||||
print_asn1msg(PRT_DEBUG_DECODE, " DEBUG> OID =");
|
||||
#if defined(ASN1_DEBUG)
|
||||
delimiter = ' ';
|
||||
#endif /* defined(ASN1_DEBUG) */
|
||||
numValues = 0;
|
||||
while (len) {
|
||||
value = 0;
|
||||
for (;;) {
|
||||
--len;
|
||||
value = (value << 7) | (*p & 0x7F);
|
||||
if (!(*p++ & 0x80)) {
|
||||
/* Last octet in the OID subidentifier value */
|
||||
if (numValues < sizeof(oid->value) / sizeof(oid->value[0])) {
|
||||
oid->value[numValues] = value;
|
||||
#if defined(ASN1_DEBUG)
|
||||
print_asn1msg(PRT_DEBUG_DECODE, "%c%d", delimiter, value);
|
||||
delimiter = '.';
|
||||
#endif /* defined(ASN1_DEBUG) */
|
||||
} else {
|
||||
/* Too many OID subidentifier values */
|
||||
#if defined(ASN1_DEBUG)
|
||||
delimiter = '~';
|
||||
print_asn1msg(PRT_DEBUG_DECODE, "%c%d", delimiter, value);
|
||||
#endif /* defined(ASN1_DEBUG) */
|
||||
}
|
||||
++numValues;
|
||||
break;
|
||||
}
|
||||
if (!len) {
|
||||
oid->numValues = 0;
|
||||
print_asn1msg(PRT_DEBUG_DECODE, "\n");
|
||||
print_asn1msg(PRT_DEBUG_DECODE, " DEBUG> Last OID subidentifier value not terminated!\n");
|
||||
return -1;
|
||||
}
|
||||
} /* end for */
|
||||
} /* end while */
|
||||
print_asn1msg(PRT_DEBUG_DECODE, "\n");
|
||||
|
||||
if (numValues <= sizeof(oid->value) / sizeof(oid->value[0])) {
|
||||
oid->numValues = numValues;
|
||||
return p - beg;
|
||||
} else {
|
||||
/* Need to increase the size of the OID subidentifier list. */
|
||||
oid->numValues = 0;
|
||||
print_asn1msg(PRT_DEBUG_DECODE, " DEBUG> Too many OID values!\n");
|
||||
return -1;
|
||||
}
|
||||
} /* end ParseOid() */
|
||||
|
|
988
suppserv/fac.c
988
suppserv/fac.c
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue