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:
nadi 2006-08-15 16:29:12 +00:00
parent e02e62d0ed
commit 0e72ef1805
15 changed files with 2159 additions and 0 deletions

View File

@ -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

View File

@ -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

27
suppserv/Makefile Normal file
View File

@ -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

80
suppserv/asn1.c Normal file
View File

@ -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;
}

345
suppserv/asn1.h Normal file
View File

@ -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

233
suppserv/asn1_address.c Normal file
View File

@ -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);
}

350
suppserv/asn1_aoc.c Normal file
View File

@ -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);
}

View File

@ -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);
}

222
suppserv/asn1_comp.c Normal file
View File

@ -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;
}

324
suppserv/asn1_diversion.c Normal file
View File

@ -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;
}

View File

@ -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

134
suppserv/asn1_enc.c Normal file
View File

@ -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;
}

114
suppserv/asn1_generic.c Normal file
View File

@ -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;
}

145
suppserv/fac.c Normal file
View File

@ -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;
}

155
suppserv/suppserv.h Normal file
View File

@ -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