Moving the asn1 parse and encoding code from the mISDN sources to mISDNuser.
suppserv.h specifies the interface. libsuppserv.so is the lib. So far, only one portion of CallDeflection is implemented.
This commit is contained in:
parent
e02e62d0ed
commit
0e72ef1805
1
Makefile
1
Makefile
|
@ -36,6 +36,7 @@ SUBDIRS := lib example
|
|||
SUBDIRS += $(shell if test -d i4lnet ; then echo i4lnet; fi)
|
||||
SUBDIRS += $(shell if test -d tenovis ; then echo tenovis; fi)
|
||||
SUBDIRS += $(shell if test -d voip ; then echo voip; fi)
|
||||
SUBDIRS += $(shell if test -d suppserv ; then echo suppserv; fi)
|
||||
|
||||
LIBS := lib/libmISDN.a
|
||||
|
||||
|
|
|
@ -3,6 +3,12 @@
|
|||
|
||||
/* API library to use with /dev/mISDN */
|
||||
|
||||
#define MISDNUSER_MAJOR_VERSION 1
|
||||
#define MISDNUSER_MINOR_VERSION 0
|
||||
#define MISDNUSER_PATCHLEVEL 3
|
||||
#define MISDNUSER_VERSION_CODE ((MISDNUSER_MAJOR_VERSION<<24) | (MISDNUSER_MINOR_VERSION<<16) | MISDNUSER_PATCHLEVEL)
|
||||
#define MISDNUSER_VERSION(x,y,z) ((x<<24) | (y<<16) | z)
|
||||
|
||||
/* we need somme extentions */
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
|
||||
#CFLAGS += -DASN1_DEBUG
|
||||
|
||||
SUPPSERVOBJ = asn1.o asn1_enc.o asn1_generic.o asn1_aoc.o asn1_basic_service.o asn1_comp.o asn1_diversion.o asn1_address.o fac.o
|
||||
|
||||
all: libsuppserv.a libsuppserv.so
|
||||
|
||||
main: $(SUPPSERVOBJ)
|
||||
|
||||
install:
|
||||
install -m 644 libsuppserv.so $(INSTALL_PREFIX)/usr/lib
|
||||
cp *.h $(INSTALL_PREFIX)/usr/include/mISDNuser/
|
||||
|
||||
libsuppserv.so: $(SUPPSERVOBJ)
|
||||
rm -f $@
|
||||
$(CC) -shared -Xlinker -x -o $@ $(SUPPSERVOBJ)
|
||||
|
||||
libsuppserv.a: $(SUPPSERVOBJ)
|
||||
rm -f $@
|
||||
ar cr $@ $(SUPPSERVOBJ)
|
||||
|
||||
clean:
|
||||
rm -f *.o *~ DEADJOE
|
||||
rm -f libsuppserv.a libsuppserv.so
|
||||
|
||||
distclean: clean
|
||||
rm -f *.a
|
|
@ -0,0 +1,80 @@
|
|||
/* $Id: asn1.c,v 1.1 2006/08/15 16:29:13 nadi Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include "asn1.h"
|
||||
|
||||
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 l, i;
|
||||
|
||||
if (*p == 0x80) { // indefinite
|
||||
*len = -1;
|
||||
return 1;
|
||||
}
|
||||
if (!(*p & 0x80)) { // one byte
|
||||
*len = *p;
|
||||
return 1;
|
||||
}
|
||||
*len = 0;
|
||||
l = *p & ~0x80;
|
||||
p++;
|
||||
for (i = 0; i < l; i++) {
|
||||
*len = (*len << 8) + *p;
|
||||
p++;
|
||||
}
|
||||
return l+1;
|
||||
}
|
||||
|
||||
int
|
||||
ParseASN1(u_char *p, u_char *end, int level)
|
||||
{
|
||||
int tag, len;
|
||||
int ret;
|
||||
int j;
|
||||
u_char *tag_end, *beg;
|
||||
|
||||
beg = p;
|
||||
|
||||
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, " ");
|
||||
print_asn1msg(PRT_DEBUG_DECODE, "TAG 0x%02x LEN %3d\n", tag, len);
|
||||
#endif
|
||||
|
||||
if (tag & ASN1_TAG_CONSTRUCTED) {
|
||||
if (len == -1) { // indefinite
|
||||
while (*p) {
|
||||
CallASN1(ret, p, end, ParseASN1(p, end, level + 1));
|
||||
}
|
||||
p++;
|
||||
if (*p)
|
||||
return -1;
|
||||
p++;
|
||||
} else {
|
||||
tag_end = p + len;
|
||||
while (p < tag_end) {
|
||||
CallASN1(ret, p, end, ParseASN1(p, end, level +1));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
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);
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,345 @@
|
|||
#ifndef __ASN1_H__
|
||||
#define __ASN1_H__
|
||||
|
||||
#include <asm/types.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef enum {
|
||||
invoke = 1,
|
||||
returnResult = 2,
|
||||
returnError = 3,
|
||||
reject = 4,
|
||||
} asn1Component;
|
||||
|
||||
typedef enum {
|
||||
GeneralP = 0,
|
||||
InvokeP = 1,
|
||||
ReturnResultP= 2,
|
||||
ReturnErrorP = 3,
|
||||
} asn1Problem;
|
||||
|
||||
struct PublicPartyNumber {
|
||||
int publicTypeOfNumber;
|
||||
char numberDigits[30];
|
||||
};
|
||||
|
||||
struct PartyNumber {
|
||||
int type;
|
||||
union {
|
||||
char unknown[30];
|
||||
struct PublicPartyNumber publicPartyNumber;
|
||||
} p;
|
||||
};
|
||||
|
||||
struct Address {
|
||||
struct PartyNumber partyNumber;
|
||||
char partySubaddress[30];
|
||||
};
|
||||
|
||||
struct ServedUserNr {
|
||||
int all;
|
||||
struct PartyNumber partyNumber;
|
||||
};
|
||||
|
||||
struct ActDivNotification {
|
||||
int procedure;
|
||||
int basicService;
|
||||
struct ServedUserNr servedUserNr;
|
||||
struct Address address;
|
||||
};
|
||||
|
||||
struct DeactDivNotification {
|
||||
int procedure;
|
||||
int basicService;
|
||||
struct ServedUserNr servedUserNr;
|
||||
};
|
||||
|
||||
struct ReqCallDeflection {
|
||||
struct Address address;
|
||||
int pres;
|
||||
};
|
||||
|
||||
struct ServedUserNumberList {
|
||||
struct PartyNumber partyNumber[10];
|
||||
};
|
||||
|
||||
struct IntResult {
|
||||
struct ServedUserNr servedUserNr;
|
||||
int procedure;
|
||||
int basicService;
|
||||
struct Address address;
|
||||
};
|
||||
|
||||
struct IntResultList {
|
||||
struct IntResult intResult[10];
|
||||
};
|
||||
|
||||
struct asn1Invoke {
|
||||
__u16 invokeId;
|
||||
__u16 operationValue;
|
||||
union {
|
||||
struct ActDivNotification actNot;
|
||||
struct DeactDivNotification deactNot;
|
||||
struct ReqCallDeflection reqCD;
|
||||
} o;
|
||||
};
|
||||
|
||||
struct asn1ReturnResult {
|
||||
__u16 invokeId;
|
||||
union {
|
||||
struct ServedUserNumberList list;
|
||||
struct IntResultList resultList;
|
||||
} o;
|
||||
};
|
||||
|
||||
struct asn1ReturnError {
|
||||
__u16 invokeId;
|
||||
__u16 errorValue;
|
||||
};
|
||||
|
||||
struct asn1Reject {
|
||||
int invokeId;
|
||||
asn1Problem problem;
|
||||
__u16 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)
|
||||
#else
|
||||
#define print_asn1msg(dummy, fmt, args...)
|
||||
#endif
|
||||
|
||||
#define int_error() \
|
||||
printf("mISDN: INTERNAL ERROR in %s:%d\n", \
|
||||
__FILE__, __LINE__)
|
||||
|
||||
|
||||
int ParseASN1(u_char *p, u_char *end, int level);
|
||||
|
||||
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_CONSTRUCTED (0x20)
|
||||
#define ASN1_TAG_CONTEXT_SPECIFIC (0x80)
|
||||
|
||||
#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)
|
||||
|
||||
#define INIT \
|
||||
int tag, len; \
|
||||
int ret; \
|
||||
u_char *beg; \
|
||||
\
|
||||
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__); \
|
||||
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)
|
||||
|
||||
#define XSEQUENCE(todo, act_tag, the_tag) XSEQUENCE_1(todo, act_tag, the_tag, -1)
|
||||
#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); \
|
||||
} \
|
||||
}
|
||||
|
||||
#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 CHECK_P do { \
|
||||
if (p >= end) \
|
||||
return -1; \
|
||||
} while (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);
|
||||
|
||||
/*
|
||||
** 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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
int ParseAOCDCurrency(struct asn1_parm *pc, u_char *p, u_char *end, int dummy);
|
||||
int ParseAOCDChargingUnit(struct asn1_parm *pc,u_char *p, u_char *end, int dummy);
|
||||
int ParseAOCECurrency(struct asn1_parm *pc, u_char *p, u_char *end, int dummy);
|
||||
int ParseAOCEChargingUnit(struct asn1_parm *pc,u_char *p, u_char *end, int dummy);
|
||||
int ParseAOCDCurrencyInfo(struct asn1_parm *pc,u_char *p, u_char *end, int dummy);
|
||||
int ParseAOCDChargingUnitInfo(struct asn1_parm *pc,u_char *p, u_char *end, int dummy);
|
||||
int ParseRecordedCurrency(struct asn1_parm *pc,u_char *p, u_char *end, int dummy);
|
||||
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, int dummy);
|
||||
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);
|
||||
|
||||
int ParseBasicService(struct asn1_parm *pc, u_char *p, u_char *end, int *basicService);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,233 @@
|
|||
/* $Id: asn1_address.c,v 1.1 2006/08/15 16:29:13 nadi Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "suppserv.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)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ParseNull(pc, p, end, -1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
strcpy(str, "(presentation restricted)");
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ParseNotAvailInterworking(struct asn1_parm *pc, u_char *p, u_char *end, char *str)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ParseNull(pc, p, end, -1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
strcpy(str, "(not available)");
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ParsePresentedAddressScreened(struct asn1_parm *pc, u_char *p, u_char *end, char *str)
|
||||
{
|
||||
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);
|
||||
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
int ParseAddressScreened(struct asn1_parm *pc, u_char *p, u_char *end, char *str)
|
||||
{
|
||||
struct PartyNumber partyNumber;
|
||||
char partySubaddress[30] = { 0, };
|
||||
char screeningIndicator[30];
|
||||
INIT;
|
||||
|
||||
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);
|
||||
|
||||
// str += sprintf(str, "%s", partyNumber);
|
||||
if (strlen(partySubaddress))
|
||||
str += sprintf(str, ".%s", partySubaddress);
|
||||
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
int ParseAddress(struct asn1_parm *pc, u_char *p, u_char *end, struct Address *address)
|
||||
{
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int ParsePublicPartyNumber(struct asn1_parm *pc, u_char *p, u_char *end, struct PublicPartyNumber *publicPartyNumber)
|
||||
{
|
||||
INIT;
|
||||
|
||||
XSEQUENCE_1(ParsePublicTypeOfNumber, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, &publicPartyNumber->publicTypeOfNumber);
|
||||
XSEQUENCE_1(ParseNumberDigits, ASN1_TAG_NUMERIC_STRING, ASN1_NOT_TAGGED, publicPartyNumber->numberDigits);
|
||||
|
||||
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;
|
||||
}
|
||||
str += sprintf(str, numberDigits);
|
||||
|
||||
return p - beg;
|
||||
}
|
||||
#endif
|
||||
|
||||
int ParsePublicTypeOfNumber(struct asn1_parm *pc, u_char *p, u_char *end, int *publicTypeOfNumber)
|
||||
{
|
||||
return ParseEnum(pc, p, end, publicTypeOfNumber);
|
||||
}
|
||||
|
||||
#if 0
|
||||
int ParsePrivateTypeOfNumber(struct asn1_parm *pc, u_char *p, u_char *end, int *privateTypeOfNumber)
|
||||
{
|
||||
return ParseEnum(pc, p, end, privateTypeOfNumber);
|
||||
}
|
||||
#endif
|
||||
|
||||
int ParsePartySubaddress(struct asn1_parm *pc, u_char *p, u_char *end, char *str)
|
||||
{
|
||||
INIT;
|
||||
|
||||
XCHOICE_1(ParseUserSpecifiedSubaddress, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, str);
|
||||
XCHOICE_1(ParseNSAPSubaddress, ASN1_TAG_OCTET_STRING, ASN1_NOT_TAGGED, str);
|
||||
XCHOICE_DEFAULT;
|
||||
}
|
||||
|
||||
int ParseUserSpecifiedSubaddress(struct asn1_parm *pc, u_char *p, u_char *end, char *str)
|
||||
{
|
||||
int oddCountIndicator;
|
||||
INIT;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ParseNumberDigits(struct asn1_parm *pc, u_char *p, u_char *end, char *str)
|
||||
{
|
||||
return ParseNumericString(pc, p, end, str);
|
||||
}
|
|
@ -0,0 +1,350 @@
|
|||
/* $Id: asn1_aoc.c,v 1.1 2006/08/15 16:29:13 nadi Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include "suppserv.h"
|
||||
|
||||
// ======================================================================
|
||||
// AOC EN 300 182-1 V1.3.3
|
||||
|
||||
#if 0
|
||||
// AOCDCurrency
|
||||
|
||||
int
|
||||
ParseAOCDCurrency(struct Channel *chanp, u_char *p, u_char *end, int dummy)
|
||||
{
|
||||
INIT;
|
||||
|
||||
XCHOICE(ParseNull, ASN1_TAG_NULL, ASN1_NOT_TAGGED); // chargeNotAvail
|
||||
XCHOICE(ParseAOCDCurrencyInfo, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED);
|
||||
XCHOICE_DEFAULT;
|
||||
}
|
||||
#endif
|
||||
// AOCDChargingUnit
|
||||
|
||||
int
|
||||
ParseAOCDChargingUnit(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
{
|
||||
INIT;
|
||||
|
||||
XCHOICE(ParseNull, ASN1_TAG_NULL, ASN1_NOT_TAGGED); // chargeNotAvail
|
||||
XCHOICE(ParseAOCDChargingUnitInfo, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED);
|
||||
XCHOICE_DEFAULT;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// AOCECurrency
|
||||
|
||||
int
|
||||
ParseAOCECurrency(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
{
|
||||
INIT;
|
||||
|
||||
XCHOICE(ParseNull, ASN1_TAG_NULL, ASN1_NOT_TAGGED); // chargeNotAvail
|
||||
XCHOICE(ParseAOCECurrencyInfo, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED);
|
||||
XCHOICE_DEFAULT;
|
||||
}
|
||||
#endif
|
||||
|
||||
// AOCEChargingUnit
|
||||
|
||||
int
|
||||
ParseAOCEChargingUnit(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
{
|
||||
INIT;
|
||||
|
||||
XCHOICE(ParseNull, ASN1_TAG_NULL, ASN1_NOT_TAGGED); // chargeNotAvail
|
||||
XCHOICE(ParseAOCEChargingUnitInfo, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED);
|
||||
XCHOICE_DEFAULT;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// AOCDCurrencyInfo
|
||||
|
||||
int
|
||||
ParseAOCDSpecificCurrency(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
{
|
||||
int typeOfChargingInfo;
|
||||
int billingId;
|
||||
INIT;
|
||||
|
||||
XSEQUENCE(ParseRecordedCurrency, ASN1_TAG_SEQUENCE, 1);
|
||||
XSEQUENCE_1(ParseTypeOfChargingInfo, ASN1_TAG_ENUM, 2, &typeOfChargingInfo);
|
||||
XSEQUENCE_OPT_1(ParseAOCDBillingId, ASN1_TAG_ENUM, 3, &billingId);
|
||||
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
int
|
||||
ParseAOCDCurrencyInfo(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
{
|
||||
INIT;
|
||||
|
||||
XCHOICE(ParseAOCDSpecificCurrency, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED);
|
||||
XCHOICE(ParseNull, ASN1_TAG_NULL, 1); // freeOfCharge
|
||||
XCHOICE_DEFAULT;
|
||||
}
|
||||
#endif
|
||||
|
||||
// AOCDChargingUnitInfo
|
||||
|
||||
int
|
||||
ParseAOCDSpecificChargingUnits(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
{
|
||||
int recordedUnits;
|
||||
int typeOfChargingInfo;
|
||||
int billingId;
|
||||
INIT;
|
||||
|
||||
XSEQUENCE_1(ParseRecordedUnitsList, ASN1_TAG_SEQUENCE, 1, &recordedUnits);
|
||||
XSEQUENCE_1(ParseTypeOfChargingInfo, ASN1_TAG_ENUM, 2, &typeOfChargingInfo);
|
||||
XSEQUENCE_OPT_1(ParseAOCDBillingId, ASN1_TAG_ENUM, 3, &billingId);
|
||||
|
||||
// p_L3L4(pc, CC_CHARGE | INDICATION, &recordedUnits);
|
||||
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
int
|
||||
ParseAOCDChargingUnitInfo(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
{
|
||||
INIT;
|
||||
|
||||
XCHOICE(ParseAOCDSpecificChargingUnits, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED);
|
||||
XCHOICE(ParseNull, ASN1_TAG_NULL, 1); // freeOfCharge
|
||||
XCHOICE_DEFAULT;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// RecordedCurrency
|
||||
|
||||
int
|
||||
ParseRecordedCurrency(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
{
|
||||
char currency[11];
|
||||
INIT;
|
||||
|
||||
XSEQUENCE_1(ParseCurrency, ASN1_TAG_IA5_STRING, 1, currency);
|
||||
XSEQUENCE(ParseAmount, ASN1_TAG_SEQUENCE, 2);
|
||||
|
||||
return p - beg;
|
||||
}
|
||||
#endif
|
||||
|
||||
// RecordedUnitsList
|
||||
|
||||
int
|
||||
ParseRecordedUnitsList(struct asn1_parm *pc, u_char *p, u_char *end, int *recordedUnits)
|
||||
{
|
||||
int i;
|
||||
INIT;
|
||||
|
||||
XSEQUENCE_1(ParseRecordedUnits, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, recordedUnits);
|
||||
for (i = 0; i < 31; i++)
|
||||
XSEQUENCE_OPT_1(ParseRecordedUnits, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, recordedUnits);
|
||||
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
INIT;
|
||||
|
||||
XCHOICE_1(ParseNumberOfUnits, ASN1_TAG_INTEGER, ASN1_NOT_TAGGED, recordedUnits);
|
||||
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 typeOfUnit;
|
||||
INIT;
|
||||
|
||||
XSEQUENCE_1(ParseRecordedUnitsChoice, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, recordedUnits);
|
||||
XSEQUENCE_OPT_1(ParseTypeOfUnit, ASN1_TAG_INTEGER, ASN1_NOT_TAGGED, &typeOfUnit);
|
||||
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
// AOCDBillingId
|
||||
|
||||
int
|
||||
ParseAOCDBillingId(struct asn1_parm *pc, u_char *p, u_char *end, int *billingId)
|
||||
{
|
||||
return ParseEnum(pc, p, end, billingId);
|
||||
}
|
||||
|
||||
#if 0
|
||||
// AOCECurrencyInfo
|
||||
|
||||
int
|
||||
ParseAOCESpecificCurrency(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
{
|
||||
int billingId;
|
||||
INIT;
|
||||
|
||||
XSEQUENCE(ParseRecordedCurrency, ASN1_TAG_SEQUENCE, 1);
|
||||
XSEQUENCE_OPT_1(ParseAOCEBillingId, ASN1_TAG_ENUM, 2, &billingId);
|
||||
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
int
|
||||
ParseAOCECurrencyInfoChoice(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
{
|
||||
INIT;
|
||||
|
||||
XCHOICE(ParseAOCESpecificCurrency, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED);
|
||||
XCHOICE(ParseNull, ASN1_TAG_NULL, 1); // freeOfCharge
|
||||
XCHOICE_DEFAULT;
|
||||
}
|
||||
|
||||
int
|
||||
ParseAOCECurrencyInfo(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
{
|
||||
INIT;
|
||||
|
||||
XSEQUENCE(ParseAOCECurrencyInfoChoice, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED);
|
||||
XSEQUENCE_OPT(ParseChargingAssociation, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED);
|
||||
XCHOICE_DEFAULT;
|
||||
}
|
||||
#endif
|
||||
|
||||
// AOCEChargingUnitInfo
|
||||
|
||||
int
|
||||
ParseAOCESpecificChargingUnits(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
{
|
||||
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);
|
||||
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
int
|
||||
ParseAOCEChargingUnitInfoChoice(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
{
|
||||
INIT;
|
||||
|
||||
XCHOICE(ParseAOCESpecificChargingUnits, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED);
|
||||
XCHOICE(ParseNull, ASN1_TAG_NULL, 1); // freeOfCharge
|
||||
XCHOICE_DEFAULT;
|
||||
}
|
||||
|
||||
int
|
||||
ParseAOCEChargingUnitInfo(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
{
|
||||
INIT;
|
||||
|
||||
XSEQUENCE(ParseAOCEChargingUnitInfoChoice, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED);
|
||||
XSEQUENCE_OPT(ParseChargingAssociation, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED);
|
||||
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
// AOCEBillingId
|
||||
|
||||
int
|
||||
ParseAOCEBillingId(struct asn1_parm *pc, u_char *p, u_char *end, int *billingId)
|
||||
{
|
||||
return ParseEnum(pc, p, end, billingId);
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Currency
|
||||
|
||||
int
|
||||
ParseCurrency(struct asn1_parm *pc, u_char *p, u_char *end, char *currency)
|
||||
{
|
||||
return ParseIA5String(chanp, p, end, currency);
|
||||
}
|
||||
|
||||
// Amount
|
||||
|
||||
int
|
||||
ParseAmount(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
{
|
||||
int amount;
|
||||
int multiplier;
|
||||
INIT;
|
||||
|
||||
XSEQUENCE_1(ParseCurrencyAmount, ASN1_TAG_INTEGER, 1, &amount);
|
||||
XSEQUENCE_1(ParseMultiplier, ASN1_TAG_INTEGER, 2, &multiplier);
|
||||
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
// CurrencyAmount
|
||||
|
||||
int
|
||||
ParseCurrencyAmount(struct asn1_parm *pc, u_char *p, u_char *end, int *currencyAmount)
|
||||
{
|
||||
return ParseInteger(chanp, p, end, currencyAmount);
|
||||
}
|
||||
|
||||
// Multiplier
|
||||
|
||||
int
|
||||
ParseMultiplier(struct asn1_parm *pc, u_char *p, u_char *end, int *multiplier)
|
||||
{
|
||||
return ParseEnum(chanp, p, end, multiplier);
|
||||
}
|
||||
#endif
|
||||
|
||||
// TypeOfUnit
|
||||
|
||||
int
|
||||
ParseTypeOfUnit(struct asn1_parm *pc, u_char *p, u_char *end, int *typeOfUnit)
|
||||
{
|
||||
return ParseInteger(pc, p, end, typeOfUnit);
|
||||
}
|
||||
|
||||
// NumberOfUnits
|
||||
|
||||
int
|
||||
ParseNumberOfUnits(struct asn1_parm *pc, u_char *p, u_char *end, int *numberOfUnits)
|
||||
{
|
||||
return ParseInteger(pc, p, end, numberOfUnits);
|
||||
}
|
||||
|
||||
// Charging Association
|
||||
|
||||
int
|
||||
ParseChargingAssociation(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
{
|
||||
// char partyNumber[30];
|
||||
INIT;
|
||||
|
||||
// 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 chargeIdentifier;
|
||||
|
||||
return ParseInteger(pc, p, end, &chargeIdentifier);
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
/* $Id: asn1_basic_service.c,v 1.1 2006/08/15 16:29:13 nadi Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include "suppserv.h"
|
||||
|
||||
// ======================================================================
|
||||
// Basic Service Elements EN 300 196-1 D.6
|
||||
|
||||
int ParseBasicService(struct asn1_parm *pc, u_char *p, u_char *end, int *basicService)
|
||||
{
|
||||
return ParseEnum(pc, p, end, basicService);
|
||||
}
|
||||
|
|
@ -0,0 +1,222 @@
|
|||
/* $Id: asn1_comp.c,v 1.1 2006/08/15 16:29:13 nadi Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "suppserv.h"
|
||||
|
||||
// ======================================================================
|
||||
// Component EN 300 196-1 D.1
|
||||
|
||||
int
|
||||
ParseInvokeId(struct asn1_parm *pc, u_char *p, u_char *end, int *invokeId)
|
||||
{
|
||||
return ParseInteger(pc, p, end, invokeId);
|
||||
}
|
||||
|
||||
int
|
||||
ParseErrorValue(struct asn1_parm *pc, u_char *p, u_char *end, int *errorValue)
|
||||
{
|
||||
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;
|
||||
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);
|
||||
pc->u.inv.invokeId = invokeId;
|
||||
pc->u.inv.operationValue = operationValue;
|
||||
switch (operationValue) {
|
||||
#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;
|
||||
case 33: XSEQUENCE(ParseAOCDCurrency, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED); break;
|
||||
case 34: XSEQUENCE(ParseAOCDChargingUnit, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED); break;
|
||||
case 35: XSEQUENCE(ParseAOCECurrency, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED); break;
|
||||
case 36: XSEQUENCE(ParseAOCEChargingUnit, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED); break;
|
||||
#endif
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
int
|
||||
ParseReturnResultComponent(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
{
|
||||
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);
|
||||
pc->u.retResult.invokeId = invokeId;
|
||||
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
int
|
||||
ParseReturnErrorComponent(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
{
|
||||
int invokeId;
|
||||
int errorValue;
|
||||
char error[80];
|
||||
INIT;
|
||||
|
||||
pc->comp = returnError;
|
||||
|
||||
XSEQUENCE_1(ParseInvokeId, ASN1_TAG_INTEGER, ASN1_NOT_TAGGED, &invokeId);
|
||||
XSEQUENCE_1(ParseErrorValue, ASN1_TAG_INTEGER, ASN1_NOT_TAGGED, &errorValue);
|
||||
|
||||
pc->u.retError.invokeId = invokeId;
|
||||
pc->u.retError.errorValue = errorValue;
|
||||
|
||||
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;
|
||||
}
|
||||
print_asn1msg(PRT_DEBUG_DECODE, "ReturnError: %s\n", error);
|
||||
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
int
|
||||
ParseProblemValue(struct asn1_parm *pc, u_char *p, u_char *end, asn1Problem prob)
|
||||
{
|
||||
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);
|
||||
XCHOICE_1(ParseProblemValue, ASN1_TAG_CONTEXT_SPECIFIC, 2, ReturnResultP);
|
||||
XCHOICE_1(ParseProblemValue, ASN1_TAG_CONTEXT_SPECIFIC, 3, ReturnErrorP);
|
||||
XCHOICE_DEFAULT;
|
||||
}
|
||||
|
||||
int
|
||||
ParseRejectComponent(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
{
|
||||
int invokeId = -1;
|
||||
int rval;
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
int
|
||||
ParseUnknownComponent(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
{
|
||||
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_DEFAULT;
|
||||
}
|
||||
|
|
@ -0,0 +1,324 @@
|
|||
/* $Id: asn1_diversion.c,v 1.1 2006/08/15 16:29:13 nadi Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "suppserv.h"
|
||||
|
||||
// ======================================================================
|
||||
// Diversion Supplementary Services ETS 300 207-1 Table 3
|
||||
|
||||
int
|
||||
ParseARGReqCallDeflection(struct asn1_parm *pc, u_char *p, u_char *end, struct ReqCallDeflection *reqCD)
|
||||
{
|
||||
INIT;
|
||||
|
||||
XSEQUENCE_1(ParseAddress, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &reqCD->address);
|
||||
XSEQUENCE_1(ParseBoolean, ASN1_TAG_BOOLEAN, ASN1_NOT_TAGGED, &reqCD->pres);
|
||||
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int
|
||||
ParseARGActivationDiversion(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
{
|
||||
int procedure, basicService;
|
||||
struct ServedUserNr servedUserNr;
|
||||
struct Address address;
|
||||
INIT;
|
||||
|
||||
XSEQUENCE_1(ParseProcedure, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, &procedure);
|
||||
XSEQUENCE_1(ParseBasicService, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, &basicService);
|
||||
XSEQUENCE_1(ParseAddress, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &address);
|
||||
XSEQUENCE_1(ParseServedUserNr, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &servedUserNr);
|
||||
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
int
|
||||
ParseARGDeactivationDiversion(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
{
|
||||
int procedure, basicService;
|
||||
struct ServedUserNr servedUserNr;
|
||||
INIT;
|
||||
|
||||
XSEQUENCE_1(ParseProcedure, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, &procedure);
|
||||
XSEQUENCE_1(ParseBasicService, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, &basicService);
|
||||
XSEQUENCE_1(ParseServedUserNr, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &servedUserNr);
|
||||
|
||||
print_asn1msg(PRT_SHOWNUMBERS, "Deactivation Diversion %d (%d), \n",
|
||||
procedure, basicService);
|
||||
return p - beg;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
ParseARGActivationStatusNotificationDiv(struct asn1_parm *pc, u_char *p, u_char *end, struct ActDivNotification *actNot)
|
||||
{
|
||||
INIT;
|
||||
|
||||
XSEQUENCE_1(ParseProcedure, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, &actNot->procedure);
|
||||
XSEQUENCE_1(ParseBasicService, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, &actNot->basicService);
|
||||
XSEQUENCE_1(ParseAddress, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &actNot->address);
|
||||
XSEQUENCE_1(ParseServedUserNr, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &actNot->servedUserNr);
|
||||
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
int
|
||||
ParseARGDeactivationStatusNotificationDiv(struct asn1_parm *pc, u_char *p, u_char *end, struct DeactDivNotification *deactNot)
|
||||
{
|
||||
INIT;
|
||||
|
||||
XSEQUENCE_1(ParseProcedure, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, &deactNot->procedure);
|
||||
XSEQUENCE_1(ParseBasicService, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, &deactNot->basicService);
|
||||
XSEQUENCE_1(ParseServedUserNr, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &deactNot->servedUserNr);
|
||||
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int
|
||||
ParseARGInterrogationDiversion(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
{
|
||||
int procedure, basicService;
|
||||
struct ServedUserNr servedUserNr;
|
||||
INIT;
|
||||
|
||||
XSEQUENCE_1(ParseProcedure, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, &procedure);
|
||||
XSEQUENCE_1(ParseBasicService, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, &basicService);
|
||||
XSEQUENCE_1(ParseServedUserNr, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &servedUserNr);
|
||||
|
||||
print_asn1msg(PRT_SHOWNUMBERS, "Interrogation Diversion %d (%d), \n",
|
||||
procedure, basicService);
|
||||
return p - beg;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
ParseRESInterrogationDiversion(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
{
|
||||
print_asn1msg(PRT_SHOWNUMBERS, "Interrogation Diversion Result\n");
|
||||
return ParseIntResultList(pc, p, end, &pc->u.retResult.o.resultList);
|
||||
}
|
||||
|
||||
#if 0
|
||||
int
|
||||
ParseARGInterrogateServedUserNumbers(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
{
|
||||
print_asn1msg(PRT_SHOWNUMBERS, "Interrogate Served User Numbers\n");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
ParseRESInterrogateServedUserNumbers(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ParseServedUserNumberList(pc, p, end, &pc->u.retResult.o.list);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
print_asn1msg(PRT_SHOWNUMBERS, "Interrogate Served User Numbers:\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
ParseARGDiversionInformation(struct asn1_parm *pc, u_char *p, u_char *end, int dummy)
|
||||
{
|
||||
char diversionReason[20];
|
||||
int basicService;
|
||||
char servedUserSubaddress[30];
|
||||
char callingAddress[80];
|
||||
char originalCalledNr[80];
|
||||
char lastDivertingNr[80];
|
||||
char lastDivertingReason[20];
|
||||
INIT;
|
||||
|
||||
servedUserSubaddress[0] = 0;
|
||||
callingAddress[0] = 0;
|
||||
originalCalledNr[0] = 0;
|
||||
lastDivertingNr[0] = 0;
|
||||
lastDivertingReason[0] = 0;
|
||||
|
||||
XSEQUENCE_1(ParseDiversionReason, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, diversionReason);
|
||||
XSEQUENCE_1(ParseBasicService, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, &basicService);
|
||||
XSEQUENCE_OPT_1(ParsePartySubaddress, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, servedUserSubaddress);
|
||||
XSEQUENCE_OPT_1(ParsePresentedAddressScreened, ASN1_NOT_TAGGED, 0 | ASN1_TAG_EXPLICIT, callingAddress);
|
||||
XSEQUENCE_OPT_1(ParsePresentedNumberUnscreened, ASN1_NOT_TAGGED, 1 | ASN1_TAG_EXPLICIT, originalCalledNr);
|
||||
XSEQUENCE_OPT_1(ParsePresentedNumberUnscreened, ASN1_NOT_TAGGED, 2 | ASN1_TAG_EXPLICIT, lastDivertingNr);
|
||||
XSEQUENCE_OPT_1(ParseDiversionReason, ASN1_TAG_ENUM, 3 | ASN1_TAG_EXPLICIT, lastDivertingReason);
|
||||
// XSEQUENCE_OPT_1(ParseQ931InformationElement, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, userInfo);
|
||||
print_asn1msg(PRT_SHOWNUMBERS, "Diversion Information %s(%d) %s\n"
|
||||
" callingAddress %s originalCalled Nr %s\n"
|
||||
" lastDivertingNr %s lastDiverting Reason %s\n",
|
||||
diversionReason, basicService, servedUserSubaddress, callingAddress,
|
||||
originalCalledNr, lastDivertingNr, lastDivertingReason);
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
int
|
||||
ParseIntResultList(struct asn1_parm *pc, u_char *p, u_char *end, struct IntResultList *intResultList)
|
||||
{
|
||||
int i;
|
||||
INIT;
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
intResultList->intResult[i].basicService = -1;
|
||||
XSEQUENCE_OPT_1(ParseIntResult, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED,
|
||||
&intResultList->intResult[i] );
|
||||
}
|
||||
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
int
|
||||
ParseIntResult(struct asn1_parm *pc, u_char *p, u_char *end, struct IntResult *intResult)
|
||||
{
|
||||
INIT;
|
||||
|
||||
XSEQUENCE_1(ParseServedUserNr, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &intResult->servedUserNr);
|
||||
XSEQUENCE_1(ParseBasicService, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, &intResult->basicService);
|
||||
XSEQUENCE_1(ParseProcedure, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, &intResult->procedure);
|
||||
XSEQUENCE_1(ParseAddress, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, &intResult->address);
|
||||
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
int
|
||||
ParseServedUserNrAll(struct asn1_parm *pc, u_char *p, u_char *end, struct ServedUserNr *servedUserNr)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ParseNull(pc, p, end, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
servedUserNr->all = 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
ParseServedUserNr(struct asn1_parm *pc, u_char *p, u_char *end, struct ServedUserNr *servedUserNr)
|
||||
{
|
||||
INIT;
|
||||
|
||||
servedUserNr->all = 0;
|
||||
XCHOICE_1(ParseServedUserNrAll, ASN1_TAG_NULL, ASN1_NOT_TAGGED, servedUserNr);
|
||||
XCHOICE_1(ParsePartyNumber, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &servedUserNr->partyNumber);
|
||||
XCHOICE_DEFAULT;
|
||||
}
|
||||
|
||||
int
|
||||
ParseProcedure(struct asn1_parm *pc, u_char *p, u_char *end, int *procedure)
|
||||
{
|
||||
return ParseEnum(pc, p, end, procedure);
|
||||
}
|
||||
|
||||
int ParseServedUserNumberList(struct asn1_parm *pc, u_char *p, u_char *end, struct ServedUserNumberList *list)
|
||||
{
|
||||
int i;
|
||||
INIT;
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
list->partyNumber[i].type = -1;
|
||||
XSEQUENCE_OPT_1(ParsePartyNumber, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, &list->partyNumber[i]);
|
||||
}
|
||||
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
int
|
||||
ParseDiversionReason(struct asn1_parm *pc, u_char *p, u_char *end, char *str)
|
||||
{
|
||||
int ret;
|
||||
int diversionReason;
|
||||
|
||||
ret = ParseEnum(pc, p, end, &diversionReason);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
switch (diversionReason) {
|
||||
case 0: sprintf(str, "unknown"); break;
|
||||
case 1: sprintf(str, "CFU"); break;
|
||||
case 2: sprintf(str, "CFB"); break;
|
||||
case 3: sprintf(str, "CFNR"); break;
|
||||
case 4: sprintf(str, "CD (Alerting)"); break;
|
||||
case 5: sprintf(str, "CD (Immediate)"); break;
|
||||
default: sprintf(str, "(%d)", diversionReason); break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int encodeActivationDiversion(__u8 *dest, struct FacReqCFActivate *CFActivate)
|
||||
{
|
||||
__u8 *p;
|
||||
|
||||
dest[0] = 0x30; // sequence
|
||||
dest[1] = 0; // length
|
||||
p = &dest[2];
|
||||
|
||||
p += encodeEnum(p, CFActivate->Procedure);
|
||||
p += encodeEnum(p, CFActivate->BasicService);
|
||||
p += encodeAddress(p, CFActivate->ForwardedToNumber, CFActivate->ForwardedToSubaddress);
|
||||
p += encodeServedUserNumber(p, CFActivate->ServedUserNumber);
|
||||
|
||||
dest[1] = p - &dest[2];
|
||||
return p - dest;
|
||||
}
|
||||
|
||||
int encodeDeactivationDiversion(__u8 *dest, struct FacReqCFDeactivate *CFDeactivate)
|
||||
{
|
||||
__u8 *p;
|
||||
|
||||
dest[0] = 0x30; // sequence
|
||||
dest[1] = 0; // length
|
||||
p = &dest[2];
|
||||
|
||||
p += encodeEnum(p, CFDeactivate->Procedure);
|
||||
p += encodeEnum(p, CFDeactivate->BasicService);
|
||||
p += encodeServedUserNumber(p, CFDeactivate->ServedUserNumber);
|
||||
|
||||
dest[1] = p - &dest[2];
|
||||
return p - dest;
|
||||
}
|
||||
|
||||
int encodeInterrogationDiversion(__u8 *dest, struct FacReqCFInterrogateParameters *params)
|
||||
{
|
||||
__u8 *p;
|
||||
|
||||
dest[0] = 0x30; // sequence
|
||||
dest[1] = 0; // length
|
||||
p = &dest[2];
|
||||
|
||||
p += encodeEnum(p, params->Procedure);
|
||||
#if 0
|
||||
if (basicService == 0)
|
||||
p += encodeNull(p);
|
||||
else
|
||||
#endif
|
||||
p += encodeEnum(p, params->BasicService);
|
||||
p += encodeServedUserNumber(p, params->ServedUserNumber);
|
||||
|
||||
dest[1] = p - &dest[2];
|
||||
return p - dest;
|
||||
}
|
||||
|
||||
int encodeInvokeDeflection(__u8 *dest, struct FacReqCDeflection *CD)
|
||||
{
|
||||
__u8 *p;
|
||||
|
||||
dest[0] = 0x30; // sequence
|
||||
dest[1] = 0; // length
|
||||
p = &dest[2];
|
||||
|
||||
p += encodeAddress(p, CD->DeflectedToNumber, CD->DeflectedToSubaddress);
|
||||
p += encodeBoolean(p, CD->PresentationAllowed);
|
||||
|
||||
dest[1] = p - &dest[2];
|
||||
return p - dest;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
#ifndef __ASN1_DIVERSION_H__
|
||||
#define __ASN1_DIVERSION_H__
|
||||
|
||||
int encodeActivationDiversion(__u8 *dest, struct FacReqCFActivate *CFActivate);
|
||||
int encodeDeactivationDiversion(__u8 *dest, struct FacReqCFDeactivate *CFDeactivate);
|
||||
int encodeInterrogationDiversion(__u8 *dest, struct FacReqCFInterrogateParameters *params);
|
||||
int encodeInvokeDeflection(__u8 *dest, struct FacReqCDeflection *CD);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,134 @@
|
|||
/* $Id: asn1_enc.c,v 1.1 2006/08/15 16:29:13 nadi Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include "suppserv.h"
|
||||
#include <string.h>
|
||||
|
||||
int encodeNull(__u8 *dest)
|
||||
{
|
||||
dest[0] = 0x05; // null
|
||||
dest[1] = 0; // length
|
||||
return 2;
|
||||
}
|
||||
|
||||
int encodeBoolean(__u8 *dest, __u32 i)
|
||||
{
|
||||
dest[0] = 0x01; // BOOLEAN
|
||||
dest[1] = 1; // length 1
|
||||
dest[2] = i ? 1:0; // Value
|
||||
return 3;
|
||||
}
|
||||
|
||||
int encodeInt(__u8 *dest, __u32 i)
|
||||
{
|
||||
__u8 *p;
|
||||
|
||||
dest[0] = 0x02; // integer
|
||||
dest[1] = 0; // length
|
||||
p = &dest[2];
|
||||
do {
|
||||
*p++ = i;
|
||||
i >>= 8;
|
||||
} while (i);
|
||||
|
||||
dest[1] = p - &dest[2];
|
||||
return p - dest;
|
||||
}
|
||||
|
||||
int encodeEnum(__u8 *dest, __u32 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;
|
||||
}
|
||||
|
||||
int encodeNumberDigits(__u8 *dest, __s8 *nd, __u8 len)
|
||||
{
|
||||
__u8 *p;
|
||||
int i;
|
||||
|
||||
dest[0] = 0x12; // numeric string
|
||||
dest[1] = 0x0; // length
|
||||
p = &dest[2];
|
||||
for (i = 0; i < len; i++)
|
||||
*p++ = *nd++;
|
||||
|
||||
dest[1] = p - &dest[2];
|
||||
return p - dest;
|
||||
}
|
||||
|
||||
int encodePublicPartyNumber(__u8 *dest, __s8 *facilityPartyNumber)
|
||||
{
|
||||
__u8 *p;
|
||||
|
||||
dest[0] = 0x20; // sequence
|
||||
dest[1] = 0; // length
|
||||
p = &dest[2];
|
||||
p += encodeEnum(p, (facilityPartyNumber[2] & 0x70) >> 4);
|
||||
p += encodeNumberDigits(p, &facilityPartyNumber[4], facilityPartyNumber[0] - 3);
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
/* $Id: asn1_generic.c,v 1.1 2006/08/15 16:29:13 nadi Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include "suppserv.h"
|
||||
|
||||
// ======================================================================
|
||||
// general ASN.1
|
||||
|
||||
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++;
|
||||
}
|
||||
print_asn1msg(PRT_DEBUG_DECODE, " DEBUG> BOOL = %d %#x\n", *i, *i);
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
INIT;
|
||||
|
||||
*i = 0;
|
||||
while (len--) {
|
||||
CHECK_P;
|
||||
*i = (*i << 8) + *p;
|
||||
p++;
|
||||
}
|
||||
print_asn1msg(PRT_DEBUG_DECODE, " DEBUG> INT = %d %#x\n", *i, *i);
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
int
|
||||
ParseEnum(struct asn1_parm *pc, u_char *p, u_char *end, int *i)
|
||||
{
|
||||
INIT;
|
||||
|
||||
*i = 0;
|
||||
while (len--) {
|
||||
CHECK_P;
|
||||
*i = (*i << 8) + *p;
|
||||
p++;
|
||||
}
|
||||
print_asn1msg(PRT_DEBUG_DECODE, " DEBUG> ENUM = %d %#x\n", *i, *i);
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int
|
||||
ParseIA5String(struct asn1_parm *pc, u_char *p, u_char *end, char *str)
|
||||
{
|
||||
INIT;
|
||||
|
||||
print_asn1msg(PRT_DEBUG_DECODE, " DEBUG> IA5 = ");
|
||||
while (len--) {
|
||||
CHECK_P;
|
||||
print_asn1msg(PRT_DEBUG_DECODE, "%c", *p);
|
||||
*str++ = *p;
|
||||
p++;
|
||||
}
|
||||
print_asn1msg(PRT_DEBUG_DECODE, "\n");
|
||||
*str = 0;
|
||||
return p - beg;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
ParseNumericString(struct asn1_parm *pc, u_char *p, u_char *end, char *str)
|
||||
{
|
||||
INIT;
|
||||
|
||||
print_asn1msg(PRT_DEBUG_DECODE, " DEBUG> NumStr = ");
|
||||
while (len--) {
|
||||
CHECK_P;
|
||||
print_asn1msg(PRT_DEBUG_DECODE, "%c", *p);
|
||||
*str++ = *p;
|
||||
p++;
|
||||
}
|
||||
print_asn1msg(PRT_DEBUG_DECODE, "\n");
|
||||
*str = 0;
|
||||
return p - beg;
|
||||
}
|
||||
|
||||
int
|
||||
ParseOctetString(struct asn1_parm *pc, u_char *p, u_char *end, char *str)
|
||||
{
|
||||
INIT;
|
||||
|
||||
print_asn1msg(PRT_DEBUG_DECODE, " DEBUG> Octets = ");
|
||||
while (len--) {
|
||||
CHECK_P;
|
||||
print_asn1msg(PRT_DEBUG_DECODE, " %02x", *p);
|
||||
*str++ = *p;
|
||||
p++;
|
||||
}
|
||||
print_asn1msg(PRT_DEBUG_DECODE, "\n");
|
||||
*str = 0;
|
||||
return p - beg;
|
||||
}
|
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
* fac.c
|
||||
*
|
||||
* Copyright (C) 2006, Nadi Sarrar
|
||||
* Nadi Sarrar <nadi@beronet.com>
|
||||
*
|
||||
* Portions of this file are based on the mISDN sources
|
||||
* by Karsten Keil.
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License, Version 2.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "suppserv.h"
|
||||
#include "asn1_diversion.h"
|
||||
#include "l3dss1.h"
|
||||
#include <string.h>
|
||||
|
||||
enum {
|
||||
SUPPLEMENTARY_SERVICE = 0x91,
|
||||
} SERVICE_DISCRIMINATOR;
|
||||
|
||||
enum {
|
||||
INVOKE = 0xa1,
|
||||
RETURN_RESULT = 0xa2,
|
||||
RETURN_ERROR = 0xa3,
|
||||
REJECT = 0xa4,
|
||||
} COMPONENT_TYPE_TAG;
|
||||
|
||||
enum {
|
||||
CALL_DEFLECT = 0x0d,
|
||||
AOC = 0x22,
|
||||
} OPERATION_CODE;
|
||||
|
||||
/*
|
||||
* Facility IE Encoding
|
||||
*/
|
||||
|
||||
static __u8* encodeInvokeComponentHead (__u8 *p, __u8 ie_id)
|
||||
{
|
||||
*p++ = ie_id; // IE identifier
|
||||
*p++ = 0; // length -- not known yet
|
||||
*p++ = 0x91; // remote operations protocol
|
||||
*p++ = 0xa1; // invoke component
|
||||
*p++ = 0; // length -- not known yet
|
||||
return p;
|
||||
}
|
||||
|
||||
static int encodeInvokeComponentLength (__u8 *msg, __u8 *p)
|
||||
{
|
||||
msg[4] = p - &msg[5];
|
||||
msg[1] = p - &msg[2];
|
||||
return msg[1] + 2;
|
||||
}
|
||||
|
||||
static int encodeFacCDeflection (__u8 *dest, struct FacReqCDeflection *CD)
|
||||
{
|
||||
__u8 *p;
|
||||
p = encodeInvokeComponentHead(dest, IE_FACILITY);
|
||||
p += encodeInt(p, 0x02);
|
||||
p += encodeInt(p, 13); // Calldefection
|
||||
p += encodeInvokeDeflection(p, CD);
|
||||
return encodeInvokeComponentLength(dest, p);
|
||||
}
|
||||
|
||||
int encodeFacReq (__u8 *dest, struct FacReqParm *fac)
|
||||
{
|
||||
int len = -1;
|
||||
|
||||
switch (fac->Function) {
|
||||
case FacReq_None:
|
||||
case FacReq_GetSupportedServices:
|
||||
case FacReq_Listen:
|
||||
case FacReq_Suspend:
|
||||
case FacReq_Resume:
|
||||
case FacReq_CFActivate:
|
||||
case FacReq_CFDeactivate:
|
||||
case FacReq_CFInterrogateParameters:
|
||||
case FacReq_CFInterrogateNumbers:
|
||||
break;
|
||||
case FacReq_CD:
|
||||
len = encodeFacCDeflection(dest, &(fac->u.CDeflection));
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Facility IE Decoding
|
||||
*/
|
||||
|
||||
int decodeFacReq (__u8 *src, struct FacReqParm *fac)
|
||||
{
|
||||
struct asn1_parm pc;
|
||||
int fac_len,
|
||||
offset;
|
||||
__u8 *end,
|
||||
*p = src;
|
||||
|
||||
if (!p)
|
||||
goto _dec_err;
|
||||
|
||||
offset = ParseLen(p, p + 3, &fac_len);
|
||||
if (offset < 0)
|
||||
goto _dec_err;
|
||||
p += offset;
|
||||
end = p + fac_len;
|
||||
|
||||
/* ParseASN1(p + 1, end, 0); */
|
||||
|
||||
if (*p++ != SUPPLEMENTARY_SERVICE)
|
||||
goto _dec_err;
|
||||
|
||||
if (ParseComponent(&pc, p, end) == -1)
|
||||
goto _dec_err;
|
||||
|
||||
switch (pc.comp) {
|
||||
case invoke:
|
||||
switch (pc.u.inv.operationValue) {
|
||||
case CALL_DEFLECT:
|
||||
fac->Function = FacReq_CD;
|
||||
if (pc.u.inv.o.reqCD.address.partyNumber.type == 0)
|
||||
strncpy((char *)fac->u.CDeflection.DeflectedToNumber,
|
||||
pc.u.inv.o.reqCD.address.partyNumber.p.unknown,
|
||||
sizeof(fac->u.CDeflection.DeflectedToNumber));
|
||||
else
|
||||
strncpy((char *)fac->u.CDeflection.DeflectedToNumber,
|
||||
pc.u.inv.o.reqCD.address.partyNumber.p.publicPartyNumber.numberDigits,
|
||||
sizeof(fac->u.CDeflection.DeflectedToNumber));
|
||||
fac->u.CDeflection.PresentationAllowed = pc.u.inv.o.reqCD.pres;
|
||||
*(fac->u.CDeflection.DeflectedToSubaddress) = 0;
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case returnResult:
|
||||
case returnError:
|
||||
case reject:
|
||||
goto _dec_err;
|
||||
}
|
||||
|
||||
_dec_err:
|
||||
fac->Function = FacReq_None;
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
* suppserv.h
|
||||
*
|
||||
* Copyright (C) 2006, Nadi Sarrar
|
||||
* Nadi Sarrar <nadi@beronet.com>
|
||||
*
|
||||
* Portions of this file are based on the mISDN sources
|
||||
* by Karsten Keil.
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License, Version 2.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SUPPSERV_H__
|
||||
#define __SUPPSERV_H__
|
||||
|
||||
#include "asn1.h"
|
||||
#include <asm/types.h>
|
||||
|
||||
/*
|
||||
* Structs for Facility Requests
|
||||
*/
|
||||
|
||||
enum FacReqFunction {
|
||||
FacReq_None = 0xffff,
|
||||
FacReq_GetSupportedServices = 0x0000,
|
||||
FacReq_Listen = 0x0001,
|
||||
FacReq_Suspend = 0x0004,
|
||||
FacReq_Resume = 0x0005,
|
||||
FacReq_CFActivate = 0x0009,
|
||||
FacReq_CFDeactivate = 0x000a,
|
||||
FacReq_CFInterrogateParameters = 0x000b,
|
||||
FacReq_CFInterrogateNumbers = 0x000c,
|
||||
FacReq_CD = 0x000d,
|
||||
};
|
||||
|
||||
struct FacReqListen {
|
||||
__u32 NotificationMask;
|
||||
};
|
||||
|
||||
struct FacReqSuspend {
|
||||
__s8 CallIdentity[16];
|
||||
};
|
||||
|
||||
struct FacReqResume {
|
||||
__s8 CallIdentity[16];
|
||||
};
|
||||
|
||||
struct FacReqCFActivate {
|
||||
__u32 Handle;
|
||||
__u16 Procedure;
|
||||
__u16 BasicService;
|
||||
__s8 ServedUserNumber[16];
|
||||
__s8 ForwardedToNumber[16];
|
||||
__s8 ForwardedToSubaddress[16];
|
||||
};
|
||||
|
||||
struct FacReqCFDeactivate {
|
||||
__u32 Handle;
|
||||
__u16 Procedure;
|
||||
__u16 BasicService;
|
||||
__s8 ServedUserNumber[16];
|
||||
};
|
||||
|
||||
struct FacReqCDeflection {
|
||||
__u16 PresentationAllowed;
|
||||
__s8 DeflectedToNumber[16];
|
||||
__s8 DeflectedToSubaddress[16];
|
||||
};
|
||||
|
||||
#define FacReqCFInterrogateParameters FacReqCFDeactivate
|
||||
|
||||
struct FacReqCFInterrogateNumbers {
|
||||
__u32 Handle;
|
||||
};
|
||||
|
||||
struct FacReqParm {
|
||||
enum FacReqFunction Function;
|
||||
union {
|
||||
struct FacReqListen Listen;
|
||||
struct FacReqSuspend Suspend;
|
||||
struct FacReqResume Resume;
|
||||
struct FacReqCFActivate CFActivate;
|
||||
struct FacReqCFDeactivate CFDeactivate;
|
||||
struct FacReqCFInterrogateParameters CFInterrogateParameters;
|
||||
struct FacReqCFInterrogateNumbers CFInterrogateNumbers;
|
||||
struct FacReqCDeflection CDeflection;
|
||||
} u;
|
||||
};
|
||||
|
||||
/*
|
||||
* Structs for Facility Confirms
|
||||
*/
|
||||
|
||||
enum FacConfFunction {
|
||||
FacConf_GetSupportedServices = 0x0000,
|
||||
FacConf_Listen = 0x0001,
|
||||
FacConf_Hold = 0x0002,
|
||||
FacConf_Retrieve = 0x0003,
|
||||
FacConf_Suspend = 0x0004,
|
||||
FacConf_Resume = 0x0005,
|
||||
FacConf_CFActivate = 0x0009,
|
||||
FacConf_CFDeactivate = 0x000a,
|
||||
FacConf_CFInterrogateParameters = 0x000b,
|
||||
FacConf_CFInterrogateNumbers = 0x000c,
|
||||
FacConf_CD = 0x000d,
|
||||
};
|
||||
|
||||
struct FacConfGetSupportedServices {
|
||||
__u16 SupplementaryServiceInfo;
|
||||
__u32 SupportedServices;
|
||||
};
|
||||
|
||||
struct FacConfInfo {
|
||||
__u16 SupplementaryServiceInfo;
|
||||
};
|
||||
|
||||
struct FacConfParm {
|
||||
enum FacConfFunction Function;
|
||||
union {
|
||||
struct FacConfGetSupportedServices GetSupportedServices;
|
||||
struct FacConfInfo Info;
|
||||
} u;
|
||||
};
|
||||
|
||||
/*
|
||||
* encodeFacReq (__u8 *dest, struct FacReqParm *fac)
|
||||
*
|
||||
* encode the facility (fac) into the buffer (dest)
|
||||
*
|
||||
* parameter:
|
||||
* dest - destination buffer
|
||||
* fac - facility to encode
|
||||
*
|
||||
* returns:
|
||||
* length of the encoded facility, or -1 on error
|
||||
*/
|
||||
int encodeFacReq (__u8 *dest, struct FacReqParm *fac);
|
||||
|
||||
/*
|
||||
* decodeFacReq (__u8 *src, struct FacReqParm *fac)
|
||||
*
|
||||
* decode the facility (src) and write the result to (fac)
|
||||
*
|
||||
* parameter:
|
||||
* src - encoded facility
|
||||
* fac - where to store the result
|
||||
*
|
||||
* returns:
|
||||
* 0 on success, -1 on error
|
||||
*/
|
||||
int decodeFacReq (__u8 *src, struct FacReqParm *fac);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue