rewrote the ASN.1 parsing stuff. No known problems so far, apart from the

following:

I don't use buildnumber() anymore to translate the numbers to aliases, because
it apparently did never work quite right. If someone knows how to handle
buildnumber(), we can go ahead and fix this.
This commit is contained in:
kai 2000-01-20 07:30:09 +00:00
parent c972a91eea
commit 450863ca2b
15 changed files with 1433 additions and 1668 deletions

View File

@ -1,4 +1,4 @@
/* $Id: asn1.c,v 1.3 1999/12/31 13:30:01 akool Exp $
/* $Id: asn1.c,v 1.4 2000/01/20 07:30:09 kai Exp $
*
* ISDN accounting for isdn4linux. (ASN.1 parser)
*
@ -21,6 +21,14 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: asn1.c,v $
* Revision 1.4 2000/01/20 07:30:09 kai
* rewrote the ASN.1 parsing stuff. No known problems so far, apart from the
* following:
*
* I don't use buildnumber() anymore to translate the numbers to aliases, because
* it apparently did never work quite right. If someone knows how to handle
* buildnumber(), we can go ahead and fix this.
*
* Revision 1.3 1999/12/31 13:30:01 akool
* isdnlog-4.00 (Millenium-Edition)
* - Oracle support added by Jan Bolt (Jan.Bolt@t-online.de)
@ -41,154 +49,132 @@
*
*/
#include "asn1.h"
int splitASN1(char **asnp, int lev, Element* el)
#define ASN1_DEBUG
int ParseTag(u_char *p, u_char *end, int *tag)
{
uchar c, l;
int ll, result;
char s[BUF_SIZE];
char *px;
int len = 0;
strcpy(s, " ");
px = s + lev;
el->tag = strtol(*asnp += 3, NIL, 16); len++;
sprintf(px, "ASN TAG = %2x", el->tag);
aoc_debug(el->tag, s);
l = strtol(*asnp += 3, NIL, 16); len++;
sprintf(px, "ASN l0 = %2x", l);
aoc_debug(l, s);
if (l == 0x80) { // indefinite length
el->length = -1;
} else if (l & 0x80) {
l &= ~0x80;
el->length = 0;
while (l-- > 0) {
c = strtol(*asnp += 3, NIL, 16); len++;
sprintf(px, "ASN l1 = %2x", c);
aoc_debug(c, s);
el->length = (el->length >> 8) + c;
}
} else {
el->length = l;
}
sprintf(px, "ASN length = %d", el->length);
aoc_debug(-2, s);
if (el->tag & 0x20) { // constructed
el->content.elements = calloc(10, sizeof(Element));
if (el->length == -1) { // indefinite length
el->length = 0;
while ((c = strtol(*asnp + 3, NIL, 16)) != 0x00) {
len += splitASN1(asnp, lev + 1, &el->content.elements[el->length++]);
}
*asnp += 3; len ++;
sprintf(px, "ASN ENDTAG = %2x", c);
aoc_debug(c, s);
c = strtol(*asnp += 3, NIL, 16); len++;
sprintf(px, "ASN ENDTAG = %2x", c);
aoc_debug(c, s);
if (c != 0x00) return -1;
} else {
ll = el->length;
el->length = 0;
while (ll > 0) {
result = splitASN1(asnp, lev + 1, &el->content.elements[el->length++]);
ll -= result;
len += result;
}
}
} else {
el->content.octets = calloc(200, sizeof(uchar));
ll = el->length;
el->length = 0;
while (ll--) {
c = strtol(*asnp += 3, NIL, 16); len++;
sprintf(px, "ASN contents = %2x", c);
aoc_debug(c, s);
el->content.octets[el->length++] = c;
}
}
sprintf(px, "ASN parsed len = %d", len);
aoc_debug(-2, s);
return len;
*tag = *p;
return 1;
}
int octets2Int(Element el)
int ParseLen(u_char *p, u_char *end, int *len)
{
int integer = 0;
int i;
int l, i;
for (i = 0; i < el.length; i++) {
integer = (integer >> 8) + el.content.octets[i];
}
return integer;
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;
}
void printASN1(Element el, int lev)
int
ParseASN1(u_char *p, u_char *end, int level)
{
char s[BUF_SIZE];
char *px;
int i;
int tag, len;
int ret;
int j;
u_char *tag_end, *beg;
strcpy(s, " ");
px = s + lev;
beg = p;
switch (el.tag) {
case 0x02:
sprintf(px, "Integer = %d", octets2Int(el));
aoc_debug(-2, s);
return;
case 0x0a:
sprintf(px, "Enum = %d", octets2Int(el));
aoc_debug(-2, s);
return;
case 0x12:
strcpy(px, "NumberDigits = ");
px += strlen(px);
for (i = 0; i < el.length; i++) {
*px++ = el.content.octets[i];
}
*px = 0;
aoc_debug(-2, s);
return;
case 0x30:
sprintf(px, "SEQUENCE");
break;
case 0x31:
sprintf(px, "SET");
break;
default:
sprintf(px, "TAG = %2x", el.tag);
}
aoc_debug(-2, s);
sprintf(px, "LENGTH = %d", el.length);
aoc_debug(-2, s);
if (el.tag & 0x20) { // constructed
for (i = 0; i < el.length; i++) {
printASN1(el.content.elements[i], lev+1);
}
} else { // primitive
strcpy(px, "CONTENT = ");
for (i = 0; i < el.length; i++) {
px += strlen(px);
sprintf(px, "%2x ", el.content.octets[i]);
}
aoc_debug(-2, s);
}
CallASN1(ret, p, end, ParseTag(p, end, &tag));
CallASN1(ret, p, end, ParseLen(p, end, &len));
for (j = 0; j < level*5; j++) print_msg(PRT_DEBUG_DECODE, " ");
print_msg(PRT_DEBUG_DECODE, "TAG 0x%02x LEN %3d\n", tag, len);
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_msg(PRT_DEBUG_DECODE, " ");
while (len--) {
print_msg(PRT_DEBUG_DECODE, "%02x ", *p);
p++;
}
print_msg(PRT_DEBUG_DECODE, "\n");
}
for (j = 0; j < level*5; j++) print_msg(PRT_DEBUG_DECODE, " ");
print_msg(PRT_DEBUG_DECODE, "END (%d)\n", p - beg - 2);
return p - beg;
}
#if 0
#if 0
u_char data[] = {"\xA2\x03\x02\x01\xA3"};
#endif
#if 0 // ActNotDiv
u_char data[] = {"\xA1\x2C\x02\x01\x7E\x02\x01\x09\x30\x24\x0A"
"\x01\x02\x0A\x01\x03\x30\x0C\x80\x0A\x30\x31"
"\x33\x30\x31\x34\x34\x37\x37\x30\xA1\x0E\x0A"
"\x01\x02\x12\x09\x32\x31\x31\x33\x34\x31\x38\x33\x30"};
#endif
#if 0 // ActDiv
u_char data[] = {"\xA1\x24\x02\x01\xA1\x02\x01\x07\x30\x1C\x0A"
"\x01\x02\x0A\x01\x01\x30\x0C\x80\x0A\x30"
"\x31\x33\x30\x31\x34\x34\x37\x37\x30\x80"
"\x06\x33\x34\x31\x38\x33\x30"};
#endif
#if 0 // DeactNotDiv
u_char data[] = {"\xA1\x1E\x02\x01\x08\x02\x01\x0A\x30\x16\x0A"
"\x01\x02\x0A\x01\x03\xA1\x0E\x0A\x01\x02\x12"
"\x09\x32\x31\x31\x33\x34\x31\x38\x33\x30"};
#endif
#if 1 // DeactDiv
u_char data[] = {"\xA1\x16\x02\x01\xB1\x02\x01\x08\x30\x0E\x0A"
"\x01\x02\x0A\x01\x01\x80\x06\x33\x34\x31\x38\x33\x30"};
#endif
#if 0 // AOCE, 0 Einheiten
u_char data[] = {"\xA1\x15\x02\x02\x00\xDC\x02\x01\x24\x30\x0C"
"\x30\x0A\xA1\x05\x30\x03\x02\x01\x00\x82\x01\x00"};
#endif
#if 0 // AOCE, 1 Einheit
u_char data[] = {"\xA1\x15\x02\x02\x00\xBC\x02\x01\x24\x30\x0C\x30"
"\x0A\xA1\x05\x30\x03\x02\x01\x01\x82\x01\x00"};
#endif
#if 0 // AOCD currency
u_char data[] = {"\xA1\x1A\x02\x02\x1C\x65\x02\x01\x21\x30\x11\xA1\x0C\x81\x02\x44\x4D\xA2\x06\x81\x01\x18\x82\x01\x01\x82\x01\x00"};
#endif
u_char *end = data + 47;
#include "asn1_component.h"
void
main()
{
struct Aoc chan;
#ifdef ASN1_DEBUG
ParseASN1(data, end, 0);
#endif
ParseComponent(&chan, data, end);
}
#endif

View File

@ -1,4 +1,4 @@
/* $Id: asn1.h,v 1.6 1999/12/31 13:30:01 akool Exp $
/* $Id: asn1.h,v 1.7 2000/01/20 07:30:09 kai Exp $
*
* ISDN accounting for isdn4linux. (ASN.1 parser)
*
@ -21,6 +21,14 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: asn1.h,v $
* Revision 1.7 2000/01/20 07:30:09 kai
* rewrote the ASN.1 parsing stuff. No known problems so far, apart from the
* following:
*
* I don't use buildnumber() anymore to translate the numbers to aliases, because
* it apparently did never work quite right. If someone knows how to handle
* buildnumber(), we can go ahead and fix this.
*
* Revision 1.6 1999/12/31 13:30:01 akool
* isdnlog-4.00 (Millenium-Edition)
* - Oracle support added by Jan Bolt (Jan.Bolt@t-online.de)
@ -60,52 +68,13 @@
*
*/
#ifndef __ASN1_H__
#define __ASN1_H__
#ifndef ASN1_H
#define ASN1_H
#include "isdnlog.h"
void buildnumber(char *num, int oc3, int oc3a,
char *result, int version, int *provider,
int *sondernummer, int *intern, int *internetnumber,
int dir, int who);
#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 (0x10)
#define ASN1_TAG_SET (0x11)
#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_NOT_TAGGED (-1)
typedef unsigned char uchar;
struct Element;
union Content;
typedef struct Element Element;
typedef union Content Content;
union Content {
Element *elements;
uchar *octets;
};
struct Element {
uchar tag;
int length;
Content content;
};
// TODO:
// - displaying numbers does not use the provided isdnlog capabilities
// at this time
// - documentation
struct Aoc {
int type;
@ -116,193 +85,135 @@ struct Aoc {
int type_of_charging_info;
};
typedef struct Aoc Aoc;
#ifdef _PROCESSOR_C_
#define _EXTERN
#else
#define _EXTERN extern
#endif
#include <stdio.h>
#include <sys/types.h>
#include "isdnlog.h" // for print_msg
_EXTERN char aoc_deb[BUF_SIZE];
#undef _EXTERN
int ParseASN1(u_char *p, u_char *end, int level);
void aoc_debug(int val, char *s);
int splitASN1(char **asnp, int lev, Element* el);
int octets2Int(Element el);
void printASN1(Element el, int lev);
int ParseTag(u_char *p, u_char *end, int *tag);
int ParseLen(u_char *p, u_char *end, int *len);
// -- Makros
#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 ELEMENT(name) \
int name(Element el, int tag)
#define ASN1_TAG_CONSTRUCTED (0x20)
#define ASN1_TAG_CONTEXT_SPECIFIC (0x80)
#define ELEMENT_1(name, type, parm) \
int name(Element el, int tag, type *parm)
#define ASN1_TAG_EXPLICIT (0x100)
#define ASN1_TAG_OPT (0x200)
#define ASN1_NOT_TAGGED (0x400)
// -- Elements -------------------------------------------------------------
#define CallASN1(ret, p, end, todo) do { \
ret = todo; \
if (ret < 0) { \
print_msg(PRT_DEBUG_DECODE, " DEBUG> err 2 %s:%d\n", __FUNCTION__, __LINE__); \
return -1; \
} \
p += ret; \
} while (0)
// asn1_generic --
#define INIT \
int tag, len; \
int ret; \
u_char *beg; \
\
print_msg(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; \
}
ELEMENT_1(ParseInteger, int, );
ELEMENT_1(ParseOctetString, char, );
ELEMENT(ParseNull);
ELEMENT_1(ParseBoolean, int, );
ELEMENT_1(ParseEnum, int, );
ELEMENT_1(ParseNumericString, char, );
ELEMENT_1(ParseIA5String, char, );
#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(chanp, p, end, arg1)); \
} else { \
if (!((the_tag) & ASN1_TAG_OPT)) { \
print_msg(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(chanp, p, end, arg1)); \
} else { \
if (!(the_tag) & ASN1_TAG_OPT) { \
print_msg(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(chanp, p, end, arg1)); \
} else { \
if (!(the_tag) & ASN1_TAG_OPT) { \
print_msg(PRT_DEBUG_DECODE, " DEBUG> err 3 %s:%d\n", __FUNCTION__, __LINE__); \
return -1; \
} \
} \
} \
} \
} else { \
if (!(the_tag) & ASN1_TAG_OPT) { \
print_msg(PRT_DEBUG_DECODE, " DEBUG> err 4 %s:%d\n", __FUNCTION__, __LINE__); \
return -1; \
} \
} \
} while (0)
// asn1_comp.c -- EN 300 196-1, Table D.1
#define XSEQUENCE_OPT_1(todo, act_tag, the_tag, arg1) \
XSEQUENCE_1(todo, act_tag, (the_tag | ASN1_TAG_OPT), arg1)
ELEMENT_1(ParseComponent, Aoc, );
#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)
// asn1_aoc.c -- EN 300 182-1, Table 2
#define XCHOICE_1(todo, act_tag, the_tag, arg1) \
if (act_tag == ASN1_NOT_TAGGED) { \
return todo(chanp, beg, end, arg1); \
} \
if (the_tag == ASN1_NOT_TAGGED) { \
if (act_tag == tag) { \
return todo(chanp, beg, end, arg1); \
} \
} else { \
if ((the_tag | (0x80 | (act_tag & 0x20))) == tag) { \
return todo(chanp, beg, end, arg1); \
} \
}
ELEMENT_1(ParseARGAOCDCurrency, Aoc, );
ELEMENT_1(ParseARGAOCDChargingUnit, Aoc, );
ELEMENT_1(ParseARGAOCECurrency, Aoc, );
ELEMENT_1(ParseARGAOCEChargingUnit, Aoc, );
ELEMENT_1(ParseChargingAssociation, char, );
#define XCHOICE(todo, act_tag, the_tag) XCHOICE_1(todo, act_tag, the_tag, -1)
// aoc_address.c -- EN 300 196-1, Table D.3
#define XCHOICE_DEFAULT do {\
print_msg(PRT_DEBUG_DECODE, " DEBUG> err 5 %s:%d\n", __FUNCTION__, __LINE__); \
return -1; \
} while (0)
ELEMENT_1(ParsePresentedAddressScreened, char, );
ELEMENT_1(ParsePresentedAddressUnscreened, char, );
ELEMENT_1(ParsePresentedNumberScreened, char, );
ELEMENT_1(ParsePresentedNumberUnscreened, char, );
ELEMENT_1(ParseAddress, char, );
ELEMENT_1(ParsePartyNumber, char, );
ELEMENT_1(ParsePartySubaddress, char, );
// aoc_basic_service.c -- EN 300 196-1, Table D.6
#define NBasicService 43
#ifdef _ASN1_BASIC_SERVICE_C
#define _EXTERN
#else
#define _EXTERN extern
#endif
_EXTERN char* BasicService[NBasicService];
#undef _EXTERN
ELEMENT_1(ParseBasicService, int, );
// aoc_diversion.c -- EN 300 207-1, Table 3
ELEMENT_1(ParseARGActivationDiversion, char, );
ELEMENT_1(ParseARGDeactivationDiversion, char, );
ELEMENT_1(ParseARGActivationStatusNotificationDiv, char, );
ELEMENT_1(ParseARGDeactivationStatusNotificationDiv, char, );
ELEMENT_1(ParseARGInterrogationDiversion, char, );
ELEMENT_1(ParseARGDiversionInformation, char, );
ELEMENT_1(ParseRESInterrogationDiversion, char, );
ELEMENT_1(ParseRESInterrogateServedUserNumbers, char, );
// -------------------------------------------------------------------------------
// -- Makros
#define SEQ_NOT_TAGGED(a) \
if (elnr >= el.length) return 0; \
if (!a(el.content.elements[elnr++], ASN1_NOT_TAGGED)) { \
print_msg(PRT_DEBUG_DECODE, " DEBUG> SEQ_NOT_TAGGED: got FALSE\n"); \
return 0; \
}
#define SEQ_TAGGED(a, tag) \
if (elnr >= el.length) return 0; \
if (!a(el.content.elements[elnr++], tag)) { \
print_msg(PRT_DEBUG_DECODE, " DEBUG> SEQ_TAGGED: got FALSE\n"); \
return 0; \
}
#define SEQ_NOT_TAGGED_1(a, b) \
if (elnr >= el.length) return 0; \
if (!a(el.content.elements[elnr++], ASN1_NOT_TAGGED, b)) { \
print_msg(PRT_DEBUG_DECODE, " DEBUG> SEQ_NOT_TAGGED_1: got FALSE\n"); \
return 0; \
}
#define SEQ_EXP_TAGGED_1(a, b) \
if (elnr >= el.length) return 0; \
if (!a(el.content.elements[elnr++].content.elements[0], ASN1_NOT_TAGGED, b)) { \
print_msg(PRT_DEBUG_DECODE, " DEBUG> SEQ_EXP_TAGGED_1: got FALSE\n"); \
return 0; \
}
#define SEQ_TAGGED_1(a, tag, b) \
if (elnr >= el.length) return 0; \
if (!a(el.content.elements[elnr++], tag, b)) { \
print_msg(PRT_DEBUG_DECODE, " DEBUG> SEQ_TAGGED_1: got FALSE\n"); \
return 0; \
}
#define SEQOPT_NOT_TAGGED(a) \
if (elnr < el.length) { \
if (!a(el.content.elements[elnr++], ASN1_NOT_TAGGED)) { \
print_msg(PRT_DEBUG_DECODE, " DEBUG> SEQOPT_NOT_TAGGED: got FALSE\n"); \
return 0; \
} \
}
#define SEQOPT_TAGGED(a, tag) \
if (elnr < el.length) { \
if (!a(el.content.elements[elnr++], tag)) { \
print_msg(PRT_DEBUG_DECODE, " DEBUG> SEQOPT_TAGGED: got FALSE\n"); \
return 0; \
} \
}
#define SEQOPT_NOT_TAGGED_1(a, b) \
if (elnr < el.length) { \
if (!a(el.content.elements[elnr++], ASN1_NOT_TAGGED, b)) { \
print_msg(PRT_DEBUG_DECODE, " DEBUG> SEQOPT_NOT_TAGGED_1: got FALSE\n"); \
return 0; \
} \
}
#define SEQOPT_TAGGED_1(a, tag, b) \
if (elnr < el.length) { \
if (!a(el.content.elements[elnr++], tag, b)) { \
print_msg(PRT_DEBUG_DECODE, " DEBUG> SEQOPT_NOT_TAGGED_1: got FALSE\n"); \
return 0; \
} \
}
#define IMP_TAG(a) ((a) &~ 0xa0)
#define CASE_TAGGED(a, b) \
case a: if (!b(el, a)) return 0; \
break;
#define CASE_TAGGED_1(a, b, c) \
case a: if (!b(el, a, c)) return 0; \
break;
#define CASE_1(a, b, c) \
case a: if (!b(el, ASN1_NOT_TAGGED, c)) return 0; \
break;
#define MY_DEBUG(a) \
print_msg(PRT_DEBUG_DECODE, " DEBUG> %s\n", a);
#define CHECK_TAG(a) \
int elnr = 0; \
\
elnr = elnr; /* makes lint happy */ \
if (tag == ASN1_NOT_TAGGED) { \
if ((el.tag &~ 0x20) != (a)) { \
print_msg(PRT_DEBUG_DECODE, " DEBUG> native tag %2x not found, %2x instead\n", \
(a), el.tag); \
return 0; \
} \
} else { \
if ((el.tag &~ 0x20) != (0x80|(tag))) { \
print_msg(PRT_DEBUG_DECODE, " DEBUG> given tag %2x not found, %2x instead\n", \
(tag), el.tag); \
return 0; \
} \
}
#define CHECK_P do { \
if (p >= end) \
return -1; \
} while (0)
#endif

View File

@ -1,4 +1,4 @@
/* $Id: asn1_address.c,v 1.3 1999/12/31 13:30:01 akool Exp $
/* $Id: asn1_address.c,v 1.4 2000/01/20 07:30:09 kai Exp $
*
* ISDN accounting for isdn4linux. (ASN.1 parser)
*
@ -21,6 +21,14 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: asn1_address.c,v $
* Revision 1.4 2000/01/20 07:30:09 kai
* rewrote the ASN.1 parsing stuff. No known problems so far, apart from the
* following:
*
* I don't use buildnumber() anymore to translate the numbers to aliases, because
* it apparently did never work quite right. If someone knows how to handle
* buildnumber(), we can go ahead and fix this.
*
* Revision 1.3 1999/12/31 13:30:01 akool
* isdnlog-4.00 (Millenium-Edition)
* - Oracle support added by Jan Bolt (Jan.Bolt@t-online.de)
@ -41,355 +49,242 @@
*
*/
#include "asn1.h"
#include "asn1_generic.h"
#include "asn1_address.h"
ELEMENT_1(ParsePresentedAddressScreened, char, );
ELEMENT_1(ParsePresentedAddressUnscreened, char, );
ELEMENT_1(ParsePresentedNumberScreened, char, );
ELEMENT_1(ParsePresentedNumberUnscreened, char, );
ELEMENT_1(ParseAddressScreened, char, );
ELEMENT_1(ParseNumberScreened, char, );
ELEMENT_1(ParseAddress, char, );
ELEMENT_1(ParsePartyNumber, char, );
ELEMENT_1(ParsePublicPartyNumber, char, );
ELEMENT_1(ParsePrivatePartyNumber, char, );
ELEMENT_1(ParseNumberDigits, char, );
ELEMENT_1(ParsePublicTypeOfNumber, int, );
ELEMENT_1(ParsePrivateTypeOfNumber, int, );
ELEMENT_1(ParsePartySubaddress, char, );
ELEMENT_1(ParseUserSpecifiedSubaddress, char, );
ELEMENT_1(ParseNSAPSubaddress, char, );
ELEMENT_1(ParseSubaddressInformation, char, );
ELEMENT_1(ParseScreeningIndicator, int, );
char* PublicTypeOfNumber[] = {
"unknown",
"internationalNumber",
"nationalNumber",
"networkSpecificNumber",
"subscriberNumber",
"--",
"abbreviatedNumber",
};
const int NPublicTypeOfNumber = 7;
char* PrivateTypeOfNumber[] = {
"unknown",
"level2RegionalNumber",
"level1RegionalNumber",
"pTNSpecificNumber",
"localNumber",
"--",
"abbreviatedNumber",
};
const int NPrivateTypeOfNumber = 7;
char* ScreeningIndicator[] = {
"userProvidedNotScreened",
"userProvidedVerifiedAndPassed",
"userProvidedVerifiedAndFailed",
"networkProvided",
};
const int NScreeningIndicator = 4;
void buildnumber(char *num, int oc3, int oc3a, char *result, int version,
int *provider, int *sondernummer, int *intern, int *local,
int dir, int who);
ELEMENT_1(ParsePresentedAddressScreened, char, num)
// ======================================================================
// Address Types EN 300 196-1 D.3
int ParsePresentationRestricted(struct Aoc *chanp, u_char *p, u_char *end, char *str)
{
char tmp[255];
int ret;
MY_DEBUG("ParsePresentedAddressScreened");
switch (IMP_TAG(el.tag)) {
CASE_TAGGED_1(0, ParseAddressScreened, tmp);
CASE_TAGGED_1(3, ParseAddressScreened, tmp);
}
switch (IMP_TAG(el.tag)) {
case 0 : sprintf(num, "presentationAllowedAddress: %s", tmp); break;
case 1 : strcpy(num, "presentationRestricted"); break;
case 2 : strcpy(num, "numberNotAvailableDueToInterworking"); break;
case 3 : sprintf(num, "presentationRestrictedAddress: %s", tmp); break;
default : return 0;
}
print_msg(PRT_DEBUG_DECODE, " DEBUG> %s\n", num);
return 1;
ret = ParseNull(chanp, p, end, -1);
if (ret < 0)
return ret;
strcpy(str, "(presentation restricted)");
return ret;
}
ELEMENT_1(ParsePresentedAddressUnscreened, char, num)
int ParseNotAvailInterworking(struct Aoc *chanp, u_char *p, u_char *end, char *str)
{
char tmp[255];
int ret;
MY_DEBUG("ParsePresentedAddressUnscreened");
switch (IMP_TAG(el.tag)) {
CASE_TAGGED_1(0, ParseAddress, tmp);
CASE_TAGGED_1(3, ParseAddress, tmp);
}
switch (IMP_TAG(el.tag)) {
case 0 : sprintf(num, "presentationAllowedAddress: %s", tmp); break;
case 1 : strcpy(num, "presentationRestricted"); break;
case 2 : strcpy(num, "numberNotAvailableDueToInterworking"); break;
case 3 : sprintf(num, "presentationRestrictedAddress: %s", tmp); break;
default : return 0;
}
print_msg(PRT_DEBUG_DECODE, " DEBUG> %s\n", num);
return 1;
ret = ParseNull(chanp, p, end, -1);
if (ret < 0)
return ret;
strcpy(str, "(not available)");
return ret;
}
ELEMENT_1(ParsePresentedNumberScreened, char, num)
int ParsePresentedAddressScreened(struct Aoc *chanp, u_char *p, u_char *end, char *str)
{
char tmp[255];
INIT;
MY_DEBUG("ParsePresentedNumberScreened");
switch (IMP_TAG(el.tag)) {
CASE_TAGGED_1(0, ParseNumberScreened, tmp);
CASE_TAGGED_1(3, ParseNumberScreened, tmp);
}
switch (IMP_TAG(el.tag)) {
case 0 : sprintf(num, "presentationAllowedNumber: %s", tmp); break;
case 1 : strcpy(num, "presentationRestricted"); break;
case 2 : strcpy(num, "numberNotAvailableDueToInterworking"); break;
case 3 : sprintf(num, "presentationRestrictedNumber: %s", tmp); break;
default : return 0;
}
print_msg(PRT_DEBUG_DECODE, " DEBUG> %s\n", num);
return 1;
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;
}
ELEMENT_1(ParsePresentedNumberUnscreened, char, num)
int ParsePresentedNumberScreened(struct Aoc *chanp, u_char *p, u_char *end, char *str)
{
char tmp[255];
INIT;
MY_DEBUG("ParsePresentedNumberUnscreened");
switch (IMP_TAG(el.tag)) {
CASE_TAGGED_1(0, ParsePartyNumber, tmp);
CASE_TAGGED_1(3, ParsePartyNumber, tmp);
}
switch (IMP_TAG(el.tag)) {
case 0 : sprintf(num, "presentationAllowedNumber: %s", tmp); break;
case 1 : strcpy(num, "presentationRestricted"); break;
case 2 : strcpy(num, "numberNotAvailableDueToInterworking"); break;
case 3 : sprintf(num, "presentationRestrictedNumber: %s", tmp); break;
default : return 0;
}
print_msg(PRT_DEBUG_DECODE, " DEBUG> %s\n", num);
return 1;
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;
}
ELEMENT_1(ParseAddressScreened, char, addr)
int ParsePresentedNumberUnscreened(struct Aoc *chanp, u_char *p, u_char *end, char *str)
{
char num[BUF_SIZE];
char sa[BUF_SIZE];
int screeningIndicator;
INIT;
CHECK_TAG(ASN1_TAG_SEQUENCE);
MY_DEBUG("ParseAddressScreened");
strcpy(sa, "");
SEQ_NOT_TAGGED_1(ParsePartyNumber, num);
SEQ_NOT_TAGGED_1(ParseScreeningIndicator, &screeningIndicator);
SEQOPT_NOT_TAGGED_1(ParsePartySubaddress, sa);
if (strcmp(sa, "") != 0)
sprintf(addr, "%s SUB %s", num, sa);
else
strcpy(addr, num);
return 1;
XCHOICE_1(ParsePartyNumber, ASN1_TAG_SEQUENCE, 0, str); // 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, str); // FIXME EXP
XCHOICE_DEFAULT;
}
ELEMENT_1(ParseNumberScreened, char, addr)
int ParseNumberScreened(struct Aoc *chanp, u_char *p, u_char *end, char *str)
{
int screeningIndicator;
char partyNumber[30];
char screeningIndicator[30];
INIT;
CHECK_TAG(ASN1_TAG_SEQUENCE);
MY_DEBUG("ParseNumberScreened");
XSEQUENCE_1(ParsePartyNumber, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, partyNumber);
XSEQUENCE_1(ParseScreeningIndicator, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, screeningIndicator);
SEQ_NOT_TAGGED_1(ParsePartyNumber, addr);
SEQ_NOT_TAGGED_1(ParseScreeningIndicator, &screeningIndicator);
str += sprintf(str, "%s", partyNumber);
return 1;
return p - beg;
}
ELEMENT_1(ParseAddress, char, addr)
int ParseAddressScreened(struct Aoc *chanp, u_char *p, u_char *end, char *str)
{
char num[BUF_SIZE];
char sa[BUF_SIZE];
char partyNumber[30];
char partySubaddress[30] = "";
char screeningIndicator[30];
INIT;
CHECK_TAG(ASN1_TAG_SEQUENCE);
MY_DEBUG("ParseAddress");
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);
strcpy(sa, "");
SEQ_NOT_TAGGED_1(ParsePartyNumber, num);
SEQOPT_NOT_TAGGED_1(ParsePartySubaddress, sa);
str += sprintf(str, "%s", partyNumber);
if (strlen(partySubaddress))
str += sprintf(str, ".%s", partySubaddress);
if (strcmp(sa, "") != 0)
sprintf(addr, "%s SUB %s", num, sa);
else
strcpy(addr, num);
return 1;
return p - beg;
}
ELEMENT_1(ParsePartyNumber, char, num)
int ParseAddress(struct Aoc *chanp, u_char *p, u_char *end, char *str)
{
int a1, a2, a3, a4;
char partyNumber[30];
char partySubaddress[30] = "";
INIT;
MY_DEBUG("ParsePartyNumber");
XSEQUENCE_1(ParsePartyNumber, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, partyNumber);
XSEQUENCE_OPT_1(ParsePartySubaddress, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, partySubaddress);
switch (IMP_TAG(el.tag)) {
CASE_TAGGED_1(0, ParseNumberDigits, num); // unknownPartyNumber
CASE_TAGGED_1(1, ParsePublicPartyNumber, num); // publicPartyNumber
CASE_TAGGED_1(3, ParseNumberDigits, num); // dataPartyNumber
CASE_TAGGED_1(4, ParseNumberDigits, num); // telexPartyNumber
CASE_TAGGED_1(5, ParsePrivatePartyNumber, num); // privatePartyNumber
CASE_TAGGED_1(8, ParseNumberDigits, num); // nationalStandardPartyNumber
default:
return 0;
}
if (el.tag == 0) {
buildnumber(num, 0, 0, call[6].num[CLIP],
VERSION_EDSS1, &a1, &a2, &a3, &a4, 0, 999);
strcpy(num, vnum(6, CLIP));
}
return 1;
str += sprintf(str, partyNumber);
if (strlen(partySubaddress))
str += sprintf(str, ".%s", partySubaddress);
return p - beg;
}
ELEMENT_1(ParsePublicPartyNumber, char, num)
int ParsePartyNumber(struct Aoc *chanp, u_char *p, u_char *end, char *str)
{
int pton;
char digits[BUF_SIZE];
int a1, a2, a3, a4;
INIT;
CHECK_TAG(ASN1_TAG_SEQUENCE);
MY_DEBUG("ParsePublicPartyNumber");
SEQ_NOT_TAGGED_1(ParsePublicTypeOfNumber, &pton);
SEQ_NOT_TAGGED_1(ParseNumberDigits, digits);
buildnumber(digits, pton << 4, 0, call[6].num[CLIP],
VERSION_EDSS1, &a1, &a2, &a3, &a4, 0, 999);
strcpy(num, vnum(6, CLIP));
return 1;
XCHOICE_1(ParseNumberDigits, ASN1_TAG_NUMERIC_STRING, 0, str); // unknownPartyNumber
XCHOICE_1(ParsePublicPartyNumber, ASN1_TAG_SEQUENCE, 1, str);
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
XCHOICE_DEFAULT;
}
ELEMENT_1(ParsePrivatePartyNumber, char, num)
int ParsePublicPartyNumber(struct Aoc *chanp, u_char *p, u_char *end, char *str)
{
int pton;
char digits[BUF_SIZE];
int publicTypeOfNumber;
char numberDigits[20];
INIT;
XSEQUENCE_1(ParsePublicTypeOfNumber, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, &publicTypeOfNumber);
XSEQUENCE_1(ParseNumberDigits, ASN1_TAG_NUMERIC_STRING, ASN1_NOT_TAGGED, numberDigits);
switch (publicTypeOfNumber) {
case 0: break; // unknown
case 1: str += sprintf(str, countryprefix); break;
case 2: str += sprintf(str, areaprefix); break;
case 3: str += sprintf(str, "(network)"); break;
case 4: str += sprintf(str, "(MSN)"); break;
case 6: str += sprintf(str, "(abbrev)"); break;
}
str += sprintf(str, numberDigits);
CHECK_TAG(ASN1_TAG_SEQUENCE);
MY_DEBUG("ParsePrivatePartyNumber");
SEQ_NOT_TAGGED_1(ParsePrivateTypeOfNumber, &pton);
SEQ_NOT_TAGGED_1(ParseNumberDigits, digits);
sprintf(num, "%s %s", PrivateTypeOfNumber[pton], digits);
return 1;
return p - beg;
}
ELEMENT_1(ParseNumberDigits, char, s)
int ParsePrivatePartyNumber(struct Aoc *chanp, u_char *p, u_char *end, char *str)
{
MY_DEBUG("ParseNumberDigits");
int privateTypeOfNumber;
char numberDigits[20];
INIT;
return ParseNumericString(el, tag, s);
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;
}
ELEMENT_1(ParsePublicTypeOfNumber, int, publicTypeOfNumber)
int ParsePublicTypeOfNumber(struct Aoc *chanp, u_char *p, u_char *end, int *publicTypeOfNumber)
{
MY_DEBUG("ParsePublicTypeOfNumber");
if (!ParseEnum(el, tag, publicTypeOfNumber)) return 0;
if ((*publicTypeOfNumber < 0) || (*publicTypeOfNumber > NPublicTypeOfNumber))
return 0;
print_msg(PRT_DEBUG_DECODE, " DEBUG> publicTypeOfNumber = %s\n",
PublicTypeOfNumber[*publicTypeOfNumber]);
return 1;
return ParseEnum(chanp, p, end, publicTypeOfNumber);
}
ELEMENT_1(ParsePrivateTypeOfNumber, int, privateTypeOfNumber)
int ParsePrivateTypeOfNumber(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
{
MY_DEBUG("ParsePrivateTypeOfNumber");
int typeOfNumber;
if (!ParseEnum(el, tag, privateTypeOfNumber)) return 0;
if ((*privateTypeOfNumber < 0) || (*privateTypeOfNumber > NPrivateTypeOfNumber))
return 0;
print_msg(PRT_DEBUG_DECODE, " DEBUG> publicTypeOfNumber = %s\n",
PrivateTypeOfNumber[*privateTypeOfNumber]);
return 1;
return ParseEnum(chanp, p, end, &typeOfNumber);
}
ELEMENT_1(ParsePartySubaddress, char, sa)
int ParsePartySubaddress(struct Aoc *chanp, u_char *p, u_char *end, char *str)
{
MY_DEBUG("ParsePartySubaddress");
INIT;
switch (el.tag &~ 0x20) {
CASE_1(ASN1_TAG_SEQUENCE, ParseUserSpecifiedSubaddress, sa);
CASE_1(ASN1_TAG_OCTET_STRING, ParseNSAPSubaddress, sa);
default:
return 0;
}
return 1;
XCHOICE_1(ParseUserSpecifiedSubaddress, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, str);
XCHOICE_1(ParseNSAPSubaddress, ASN1_TAG_OCTET_STRING, ASN1_NOT_TAGGED, str);
XCHOICE_DEFAULT;
}
ELEMENT_1(ParseUserSpecifiedSubaddress, char, sa)
int ParseUserSpecifiedSubaddress(struct Aoc *chanp, u_char *p, u_char *end, char *str)
{
int oddCountIndicator = -2;
int oddCountIndicator;
INIT;
CHECK_TAG(ASN1_TAG_SEQUENCE);
MY_DEBUG("ParsePublicPartyNumber");
SEQ_NOT_TAGGED_1(ParseSubaddressInformation, sa);
SEQOPT_NOT_TAGGED_1(ParseBoolean, &oddCountIndicator);
if (oddCountIndicator != -2) {
sprintf(sa, "%s %s", sa, oddCountIndicator?"odd":"even");
}
return 1;
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;
}
ELEMENT_1(ParseNSAPSubaddress, char, sa)
int ParseNSAPSubaddress(struct Aoc *chanp, u_char *p, u_char *end, char *str)
{
MY_DEBUG("ParseNSAPSubaddress");
return ParseOctetString(el, tag, sa);
return ParseOctetString(chanp, p, end, str);
}
ELEMENT_1(ParseSubaddressInformation, char, sa)
int ParseSubaddressInformation(struct Aoc *chanp, u_char *p, u_char *end, char *str)
{
MY_DEBUG("ParseSubaddressInformation");
return ParseOctetString(el, tag, sa);
return ParseOctetString(chanp, p, end, str);
}
ELEMENT_1(ParseScreeningIndicator, int, screeningIndicator)
int ParseScreeningIndicator(struct Aoc *chanp, u_char *p, u_char *end, char *str)
{
MY_DEBUG("ParseScreeningIndicator");
int ret;
int screeningIndicator;
if (!ParseEnum(el, tag, screeningIndicator)) return 0;
ret = ParseEnum(chanp, 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;
}
if ((*screeningIndicator < 0) || (*screeningIndicator > NScreeningIndicator))
return 0;
print_msg(PRT_DEBUG_DECODE, " DEBUG> screeningIndicator = %s\n",
ScreeningIndicator[*screeningIndicator]);
return 1;
return ret;
}
int ParseNumberDigits(struct Aoc *chanp, u_char *p, u_char *end, char *str)
{
return ParseNumericString(chanp, p, end, str);
}

View File

@ -0,0 +1,56 @@
/* $Id: asn1_address.h,v 1.1 2000/01/20 07:30:09 kai Exp $
*
* ISDN accounting for isdn4linux. (ASN.1 parser)
*
* Copyright 1995 .. 2000 by Andreas Kool (akool@isdn4linux.de)
*
* ASN.1 parser written by Kai Germaschewski <kai@thphy.uni-duesseldorf.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: asn1_address.h,v $
* Revision 1.1 2000/01/20 07:30:09 kai
* rewrote the ASN.1 parsing stuff. No known problems so far, apart from the
* following:
*
* I don't use buildnumber() anymore to translate the numbers to aliases, because
* it apparently did never work quite right. If someone knows how to handle
* buildnumber(), we can go ahead and fix this.
*
*
*
*/
// ======================================================================
// Address Types EN 300 196-1 D.3
int ParsePresentedAddressScreened(struct Aoc *chanp, u_char *p, u_char *end, char *str);
int ParsePresentedNumberScreened(struct Aoc *chanp, u_char *p, u_char *end, char *str);
int ParsePresentedNumberUnscreened(struct Aoc *chanp, u_char *p, u_char *end, char *str);
int ParseAddressScreened(struct Aoc *chanp, u_char *p, u_char *end, char *str);
int ParseNumberScreened(struct Aoc *chanp, u_char *p, u_char *end, char *str);
int ParseAddress(struct Aoc *chanp, u_char *p, u_char *end, char *str);
int ParsePartyNumber(struct Aoc *chanp, u_char *p, u_char *end, char *str);
int ParsePublicPartyNumber(struct Aoc *chanp, u_char *p, u_char *end, char *str);
int ParsePrivatePartyNumber(struct Aoc *chanp, u_char *p, u_char *end, char *str);
int ParsePublicTypeOfNumber(struct Aoc *chanp, u_char *p, u_char *end, int *publicTypeOfNumber);
int ParsePrivateTypeOfNumber(struct Aoc *chanp, u_char *p, u_char *end, int dummy);
int ParsePartySubaddress(struct Aoc *chanp, u_char *p, u_char *end, char *str);
int ParseUserSpecifiedSubaddress(struct Aoc *chanp, u_char *p, u_char *end, char *str);
int ParseNSAPSubaddress(struct Aoc *chanp, u_char *p, u_char *end, char *str);
int ParseSubaddressInformation(struct Aoc *chanp, u_char *p, u_char *end, char *str);
int ParseScreeningIndicator(struct Aoc *chanp, u_char *p, u_char *end, char *str);
int ParseNumberDigits(struct Aoc *chanp, u_char *p, u_char *end, char *str);

View File

@ -1,4 +1,4 @@
/* $Id: asn1_aoc.c,v 1.3 1999/12/31 13:30:01 akool Exp $
/* $Id: asn1_aoc.c,v 1.4 2000/01/20 07:30:09 kai Exp $
*
* ISDN accounting for isdn4linux. (ASN.1 parser)
*
@ -21,6 +21,14 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: asn1_aoc.c,v $
* Revision 1.4 2000/01/20 07:30:09 kai
* rewrote the ASN.1 parsing stuff. No known problems so far, apart from the
* following:
*
* I don't use buildnumber() anymore to translate the numbers to aliases, because
* it apparently did never work quite right. If someone knows how to handle
* buildnumber(), we can go ahead and fix this.
*
* Revision 1.3 1999/12/31 13:30:01 akool
* isdnlog-4.00 (Millenium-Edition)
* - Oracle support added by Jan Bolt (Jan.Bolt@t-online.de)
@ -41,562 +49,342 @@
*
*/
#include "asn1.h"
#include "asn1_generic.h"
#include "asn1_address.h"
#include "asn1_aoc.h"
ELEMENT_1(ParseARGAOCDCurrency, Aoc, );
ELEMENT_1(ParseARGAOCDChargingUnit, Aoc, );
ELEMENT_1(ParseARGAOCECurrency, Aoc, );
ELEMENT_1(ParseARGAOCEChargingUnit, Aoc, );
// ======================================================================
// AOC EN 300 182-1 V1.3.3
ELEMENT_1(ParseAOCDCurrencyInfo, Aoc, );
ELEMENT_1(ParseAOCDSpecificCurrency, Aoc, );
ELEMENT_1(ParseAOCDChargingUnitInfo, Aoc, );
ELEMENT_1(ParseAOCDSpecificChargingUnits, Aoc, );
ELEMENT_1(ParseRecordedCurrency, Aoc, );
ELEMENT_1(ParseRecordedUnitsList, Aoc, );
ELEMENT_1(ParseTypeOfChargingInfo, int, );
ELEMENT_1(ParseRecordedUnits, Aoc, );
ELEMENT_1(ParseRecordedUnitsChoice, Aoc, );
ELEMENT_1(ParseAOCDBillingId, int, );
ELEMENT_1(ParseAOCECurrencyInfo, Aoc, );
ELEMENT_1(ParseAOCECurrencyInfoChoice, Aoc, );
ELEMENT_1(ParseAOCESpecificCurrency, Aoc, );
ELEMENT_1(ParseAOCEChargingUnitInfo, Aoc, );
ELEMENT_1(ParseAOCEChargingUnitInfoChoice, Aoc, );
ELEMENT_1(ParseAOCESpecificChargingUnits, Aoc, );
ELEMENT_1(ParseAOCEBillingId, int, );
ELEMENT_1(ParseCurrency, char, msg);
ELEMENT_1(ParseAmount, Aoc, aoc);
ELEMENT_1(ParseCurrencyAmount, int, );
ELEMENT_1(ParseMultiplier, int, );
ELEMENT_1(ParseTypeOfUnit, int, );
ELEMENT_1(ParseNumberOfUnits, int, );
ELEMENT_1(ParseChargingAssociation, char, );
ELEMENT_1(ParseChargeIdentifier, int, );
// AOCDCurrency
char* XTypeOfChargingInfo[] = {
"subTotal",
"total",
};
const int NTypeOfChargingInfo = 2;
char* AOCDBillingId[] = {
"normalCharging",
"reverseCharging",
"creditCardCharging",
};
const int NAOCDBillingId = 3;
char* AOCEBillingId[] = {
"normalCharging",
"reverseCharging",
"creditCardCharging",
"callForwardingUnconditional",
"callForwardingBusy",
"callForwardingNoReply",
"callDeflection",
"callTransfer",
};
const int NAOCEBillingId = 8;
float XMultiplier[] = {
0.001,
0.01,
0.1,
1,
10,
100,
1000,
};
const int NMultiplier = 7;
// ---------------------------------------
ELEMENT_1(ParseARGAOCDCurrency, Aoc, aoc)
int
ParseAOCDCurrency(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
{
char tmp[255];
INIT;
CHECK_TAG(ASN1_TAG_SEQUENCE);
MY_DEBUG("ParseARGAOCDCurrency");
aoc->type = 33; // AOCDCurrency
if (ParseAOCDCurrencyInfo(el, ASN1_NOT_TAGGED, aoc)) {
;
} else if (ParseNull(el, ASN1_NOT_TAGGED)) {
aoc->amount = -1; // chargeNotAvailable
strcpy(aoc->msg, "chargeNotAvailable");
strcpy(aoc->currency, "");
} else {
return 0;
}
sprintf(tmp, "AOC-D: %f %s %s\n",
aoc->amount*aoc->multiplier, aoc->currency, aoc->msg);
strcpy(aoc->msg, tmp);
print_msg(PRT_DEBUG_DECODE, " DEBUG> %s\n", aoc->msg);
return 1;
XCHOICE(ParseNull, ASN1_TAG_NULL, ASN1_NOT_TAGGED); // chargeNotAvail
XCHOICE(ParseAOCDCurrencyInfo, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED);
XCHOICE_DEFAULT;
}
ELEMENT_1(ParseARGAOCDChargingUnit, Aoc, aoc)
// AOCDChargingUnit
int
ParseAOCDChargingUnit(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
{
char tmp[255];
INIT;
MY_DEBUG("ParseARGAOCDChargingUnit");
aoc->type = 34; // AOCDChargingUnit
if (ParseAOCDChargingUnitInfo(el, ASN1_NOT_TAGGED, aoc)) {
;
} else if (ParseNull(el, ASN1_NOT_TAGGED)) {
aoc->amount = 1; // chargeNotAvailable
strcpy(aoc->msg, "chargeNotAvailable");
} else {
return 0;
}
sprintf(tmp, "AOC-D: %d EH, %s", aoc->amount, aoc->msg);
strcpy(aoc->msg, tmp);
print_msg(PRT_DEBUG_DECODE, " DEBUG> %s\n", aoc->msg);
return 1;
XCHOICE(ParseNull, ASN1_TAG_NULL, ASN1_NOT_TAGGED); // chargeNotAvail
XCHOICE(ParseAOCDChargingUnitInfo, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED);
XCHOICE_DEFAULT;
}
ELEMENT_1(ParseARGAOCECurrency, Aoc, aoc)
// AOCECurrency
int
ParseAOCECurrency(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
{
char tmp[255];
INIT;
CHECK_TAG(ASN1_TAG_SEQUENCE);
MY_DEBUG("ParseARGAOCECurrency");
aoc->type = 35; // AOCECurrency
if (ParseAOCECurrencyInfo(el, ASN1_NOT_TAGGED, aoc)) {
;
} else if (ParseNull(el, ASN1_NOT_TAGGED)) {
aoc->amount = -1; // chargeNotAvailable
strcpy(aoc->msg, "chargeNotAvailable");
strcpy(aoc->currency, "");
} else {
return 0;
}
sprintf(tmp, "AOC-D: %f %s %s\n",
aoc->amount*aoc->multiplier, aoc->currency, aoc->msg);
strcpy(aoc->msg, tmp);
print_msg(PRT_DEBUG_DECODE, " DEBUG> %s\n", aoc->msg);
return 1;
XCHOICE(ParseNull, ASN1_TAG_NULL, ASN1_NOT_TAGGED); // chargeNotAvail
XCHOICE(ParseAOCECurrencyInfo, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED);
XCHOICE_DEFAULT;
}
ELEMENT_1(ParseARGAOCEChargingUnit, Aoc, aoc)
// AOCEChargingUnit
int
ParseAOCEChargingUnit(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
{
char tmp[255];
INIT;
MY_DEBUG("ParseARGAOCEChargingUnit");
aoc->type = 36; // AOCEChargingUnit
if (ParseAOCEChargingUnitInfo(el, ASN1_NOT_TAGGED, aoc)) {
;
} else if (ParseNull(el, ASN1_NOT_TAGGED)) {
aoc->amount = -1; // chargeNotAvailable
strcpy(aoc->msg, "chargeNotAvailable");
} else {
return 0;
}
sprintf(tmp, "AOC-E: %d EH, %s", aoc->amount, aoc->msg);
strcpy(aoc->msg, tmp);
print_msg(PRT_DEBUG_DECODE, " DEBUG> %s\n", aoc->msg);
return 1;
XCHOICE(ParseNull, ASN1_TAG_NULL, ASN1_NOT_TAGGED); // chargeNotAvail
XCHOICE(ParseAOCEChargingUnitInfo, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED);
XCHOICE_DEFAULT;
}
ELEMENT_1(ParseAOCDCurrencyInfo, Aoc, aoc)
// AOCDCurrencyInfo
int
ParseAOCDSpecificCurrency(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
{
MY_DEBUG("ParseAOCDCurrencyInfo");
int typeOfChargingInfo;
int billingId;
INIT;
if (ParseAOCDSpecificCurrency(el, tag, aoc)) {
;
} else if (ParseNull(el, 1)) {
aoc->amount = 0; // freeOfCharge
strcpy(aoc->msg, "freeOfCharge");
} else {
return 0;
}
XSEQUENCE(ParseRecordedCurrency, ASN1_TAG_SEQUENCE, 1);
XSEQUENCE_1(ParseTypeOfChargingInfo, ASN1_TAG_ENUM, 2, &typeOfChargingInfo);
XSEQUENCE_OPT_1(ParseAOCDBillingId, ASN1_TAG_ENUM, 3, &billingId);
return 1;
return p - beg;
}
ELEMENT_1(ParseAOCDSpecificCurrency, Aoc, aoc)
int
ParseAOCDCurrencyInfo(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
{
int billingId = -1;
INIT;
CHECK_TAG(ASN1_TAG_SEQUENCE);
MY_DEBUG("ParseAOCDSpecificCurrency");
SEQ_TAGGED_1(ParseRecordedCurrency, 1, aoc);
SEQ_TAGGED_1(ParseTypeOfChargingInfo, 2, &aoc->type_of_charging_info);
SEQOPT_TAGGED_1(ParseAOCDBillingId, 3, &billingId);
sprintf(aoc->msg, "typeOfChargingInfo = %s, billingId = %s",
XTypeOfChargingInfo[aoc->type_of_charging_info],
(billingId==-1)?"-":AOCDBillingId[billingId]);
return 1;
XCHOICE(ParseAOCDSpecificCurrency, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED);
XCHOICE(ParseNull, ASN1_TAG_NULL, 1); // freeOfCharge
XCHOICE_DEFAULT;
}
ELEMENT_1(ParseAOCDChargingUnitInfo, Aoc, aoc)
// AOCDChargingUnitInfo
int
ParseAOCDSpecificChargingUnits(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
{
MY_DEBUG("ParseAOCDChargingUnitInfo");
int recordedUnits;
int typeOfChargingInfo;
int billingId;
INIT;
if (ParseAOCDSpecificChargingUnits(el, tag, aoc)) {
;
} else if (ParseNull(el, 1)) {
aoc->amount = 0; // freeOfCharge
strcpy(aoc->msg, "freeOfCharge");
} else {
return 0;
}
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);
return 1;
chanp->type_of_charging_info = typeOfChargingInfo;
chanp->amount = recordedUnits;
return p - beg;
}
ELEMENT_1(ParseAOCDSpecificChargingUnits, Aoc, aoc)
int
ParseAOCDChargingUnitInfo(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
{
int billingId = -1;
INIT;
CHECK_TAG(ASN1_TAG_SEQUENCE);
MY_DEBUG("ParseAOCDSpecificChargingUnits");
SEQ_TAGGED_1(ParseRecordedUnitsList, 1, aoc);
SEQ_TAGGED_1(ParseTypeOfChargingInfo, 2, &aoc->type_of_charging_info);
SEQOPT_TAGGED_1(ParseAOCDBillingId, 3, &billingId);
sprintf(aoc->msg, "typeOfChargingInfo = %s, billingId = %s",
XTypeOfChargingInfo[aoc->type_of_charging_info],
(billingId==-1)?"-":AOCDBillingId[billingId]);
return 1;
XCHOICE(ParseAOCDSpecificChargingUnits, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED);
XCHOICE(ParseNull, ASN1_TAG_NULL, 1); // freeOfCharge
XCHOICE_DEFAULT;
}
ELEMENT_1(ParseRecordedCurrency, Aoc, aoc)
// RecordedCurrency
int
ParseRecordedCurrency(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
{
CHECK_TAG(ASN1_TAG_SEQUENCE);
MY_DEBUG("ParseRecordedCurrency");
INIT;
SEQ_TAGGED_1(ParseCurrency, 1, aoc->currency);
SEQ_TAGGED_1(ParseAmount, 2, aoc);
XSEQUENCE_1(ParseCurrency, ASN1_TAG_IA5_STRING, 1, chanp->currency);
XSEQUENCE(ParseAmount, ASN1_TAG_SEQUENCE, 2);
return 1;
return p - beg;
}
ELEMENT_1(ParseRecordedUnitsList, Aoc, aoc)
// RecordedUnitsList
int
ParseRecordedUnitsList(struct Aoc *chanp, u_char *p, u_char *end, int *recordedUnits)
{
CHECK_TAG(ASN1_TAG_SEQUENCE);
MY_DEBUG("ParseRecordedUnitsList");
int i;
INIT;
aoc->amount = 0;
while (elnr < el.length) {
SEQ_NOT_TAGGED_1(ParseRecordedUnits, aoc);
}
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 1;
return p - beg;
}
ELEMENT_1(ParseTypeOfChargingInfo, int, typeOfChargingInfo)
// TypeOfChargingInfo
int
ParseTypeOfChargingInfo(struct Aoc *chanp, u_char *p, u_char *end, int *typeOfChargingInfo)
{
MY_DEBUG("ParseTypeOfChargingInfo");
if (!ParseEnum(el, tag, typeOfChargingInfo)) return 0;
if ((*typeOfChargingInfo < 0) || (*typeOfChargingInfo > NTypeOfChargingInfo))
return 0;
print_msg(PRT_DEBUG_DECODE, " DEBUG> typeOfChargingInfo = %s\n",
XTypeOfChargingInfo[*typeOfChargingInfo]);
return 1;
return ParseEnum(chanp, p, end, typeOfChargingInfo);
}
ELEMENT_1(ParseRecordedUnits, Aoc, aoc)
// RecordedUnits
int
ParseRecordedUnitsChoice(struct Aoc *chanp, u_char *p, u_char *end, int *recordedUnits)
{
int typeOfUnit = -1;
INIT;
CHECK_TAG(ASN1_TAG_SEQUENCE);
MY_DEBUG("ParseRecordedUnits");
SEQ_NOT_TAGGED_1(ParseRecordedUnitsChoice, aoc);
SEQOPT_NOT_TAGGED_1(ParseTypeOfUnit, &typeOfUnit);
if (typeOfUnit != -1) {
sprintf(aoc->msg, "typeOfUnit = %d", typeOfUnit);
}
return 1;
XCHOICE_1(ParseNumberOfUnits, ASN1_TAG_INTEGER, ASN1_NOT_TAGGED, recordedUnits);
XCHOICE(ParseNull, ASN1_TAG_NULL, ASN1_NOT_TAGGED); // not available
XCHOICE_DEFAULT;
}
ELEMENT_1(ParseRecordedUnitsChoice, Aoc, aoc)
int
ParseRecordedUnits(struct Aoc *chanp, u_char *p, u_char *end, int *recordedUnits)
{
int eh;
int typeOfUnit;
INIT;
MY_DEBUG("ParseRecordedUnitsChoice");
XSEQUENCE_1(ParseRecordedUnitsChoice, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, recordedUnits);
XSEQUENCE_OPT_1(ParseTypeOfUnit, ASN1_TAG_INTEGER, ASN1_NOT_TAGGED, &typeOfUnit);
if (ParseNumberOfUnits(el, ASN1_NOT_TAGGED, &eh)) {
aoc->amount += eh;
} else if (ParseNull(el, ASN1_NOT_TAGGED)) {
aoc->amount = -1; // notAvailable
} else {
return 0;
}
return 1;
return p - beg;
}
ELEMENT_1(ParseAOCDBillingId, int, billingId)
// AOCDBillingId
int
ParseAOCDBillingId(struct Aoc *chanp, u_char *p, u_char *end, int *billingId)
{
MY_DEBUG("ParseAOCDBillingId");
if (!ParseEnum(el, tag, billingId)) return 0;
if ((*billingId < 0) || (*billingId > NAOCDBillingId))
return 0;
print_msg(PRT_DEBUG_DECODE, " DEBUG> AOCDBillingId = %s\n",
AOCDBillingId[*billingId]);
return 1;
return ParseEnum(chanp, p, end, billingId);
}
ELEMENT_1(ParseAOCECurrencyInfo, Aoc, aoc)
// AOCECurrencyInfo
int
ParseAOCESpecificCurrency(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
{
char msg[21] = "";
int billingId;
INIT;
CHECK_TAG(ASN1_TAG_SEQUENCE);
MY_DEBUG("ParseARGAOCECurrencyInfo");
XSEQUENCE(ParseRecordedCurrency, ASN1_TAG_SEQUENCE, 1);
XSEQUENCE_OPT_1(ParseAOCEBillingId, ASN1_TAG_ENUM, 2, &billingId);
SEQ_NOT_TAGGED_1(ParseAOCECurrencyInfoChoice, aoc);
SEQOPT_NOT_TAGGED_1(ParseChargingAssociation, msg);
if (strcmp(msg, "") != 0) {
strcat(aoc->msg, " chargingAssociation: ");
strcat(aoc->msg, msg);
}
return 1;
return p - beg;
}
ELEMENT_1(ParseAOCECurrencyInfoChoice, Aoc, aoc)
int
ParseAOCECurrencyInfoChoice(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
{
MY_DEBUG("ParseAOCECurrencyInfoChoice");
INIT;
if (ParseAOCESpecificCurrency(el, tag, aoc)) {
;
} else if (ParseNull(el, 1)) {
aoc->amount = 0; // freeOfCharge
strcpy(aoc->msg, "freeOfCharge");
} else {
return 0;
}
return 1;
XCHOICE(ParseAOCESpecificCurrency, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED);
XCHOICE(ParseNull, ASN1_TAG_NULL, 1); // freeOfCharge
XCHOICE_DEFAULT;
}
ELEMENT_1(ParseAOCESpecificCurrency, Aoc, aoc)
int
ParseAOCECurrencyInfo(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
{
int billingId = -1;
INIT;
CHECK_TAG(ASN1_TAG_SEQUENCE);
MY_DEBUG("ParseAOCESpecificCurrency");
SEQ_TAGGED_1(ParseRecordedCurrency, 1, aoc);
SEQOPT_TAGGED_1(ParseAOCEBillingId, 2, &billingId);
if (billingId != -1) {
strcpy(aoc->msg, "billingId = ");
strcat(aoc->msg, AOCEBillingId[billingId]);
} else {
strcpy(aoc->msg, "");
}
return 1;
XSEQUENCE(ParseAOCECurrencyInfoChoice, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED);
XSEQUENCE_OPT(ParseChargingAssociation, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED);
XCHOICE_DEFAULT;
}
ELEMENT_1(ParseAOCEChargingUnitInfo, Aoc, aoc)
// AOCEChargingUnitInfo
int
ParseAOCESpecificChargingUnits(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
{
char msg[21] = "";
int recordedUnits;
int billingId;
INIT;
CHECK_TAG(ASN1_TAG_SEQUENCE);
MY_DEBUG("ParseAOCEChargingUnitInfo");
XSEQUENCE_1(ParseRecordedUnitsList, ASN1_TAG_SEQUENCE, 1, &recordedUnits);
XSEQUENCE_OPT_1(ParseAOCEBillingId, ASN1_TAG_ENUM, 2, &billingId);
SEQ_NOT_TAGGED_1(ParseAOCEChargingUnitInfoChoice, aoc);
SEQOPT_NOT_TAGGED_1(ParseChargingAssociation, msg);
chanp->amount = recordedUnits;
if (strcmp(msg, "") != 0) {
strcat(aoc->msg, " ChargingAssociation = ");
strcat(aoc->msg, msg);
}
return 1;
return p - beg;
}
ELEMENT_1(ParseAOCEChargingUnitInfoChoice, Aoc, aoc)
int
ParseAOCEChargingUnitInfoChoice(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
{
MY_DEBUG("ParseAOCEChargingUnitInfoChoice");
INIT;
if (ParseAOCESpecificChargingUnits(el, tag, aoc)) {
;
} else if (ParseNull(el, 1)) {
aoc->amount = 0; // freeOfCharge
strcpy(aoc->msg, "freeOfCharge");
} else {
return 0;
}
return 1;
XCHOICE(ParseAOCESpecificChargingUnits, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED);
XCHOICE(ParseNull, ASN1_TAG_NULL, 1); // freeOfCharge
XCHOICE_DEFAULT;
}
ELEMENT_1(ParseAOCESpecificChargingUnits, Aoc, aoc)
int
ParseAOCEChargingUnitInfo(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
{
int billingId = -1;
INIT;
CHECK_TAG(ASN1_TAG_SEQUENCE);
MY_DEBUG("ParseAOCESpecificChargingUnits");
XSEQUENCE(ParseAOCEChargingUnitInfoChoice, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED);
XSEQUENCE_OPT(ParseChargingAssociation, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED);
SEQ_TAGGED_1(ParseRecordedUnitsList, 1, aoc);
SEQOPT_TAGGED_1(ParseAOCEBillingId, 2, &billingId);
if (billingId != -1) {
strcpy(aoc->msg, "billingId = ");
strcat(aoc->msg, AOCEBillingId[billingId]);
} else {
strcpy(aoc->msg, "");
}
return 1;
return p - beg;
}
// AOCEBillingId
ELEMENT_1(ParseAOCEBillingId, int, billingId)
int
ParseAOCEBillingId(struct Aoc *chanp, u_char *p, u_char *end, int *billingId)
{
MY_DEBUG("ParseAOCEBillingId");
if (!ParseEnum(el, tag, billingId)) return 0;
if ((*billingId < 0) || (*billingId > NAOCEBillingId))
return 0;
print_msg(PRT_DEBUG_DECODE, " DEBUG> billingId = %s\n",
AOCEBillingId[*billingId]);
return 1;
return ParseEnum(chanp, p, end, billingId);
}
ELEMENT_1(ParseCurrency, char, msg)
// Currency
int
ParseCurrency(struct Aoc *chanp, u_char *p, u_char *end, char *currency)
{
MY_DEBUG("ParseCurrency");
if (!ParseIA5String(el, tag, msg)) return 0;
print_msg(PRT_DEBUG_DECODE, " DEBUG> Currency = %s\n",
msg);
return 1;
return ParseIA5String(chanp, p, end, currency);
}
ELEMENT_1(ParseAmount, Aoc, aoc)
// Amount
int
ParseAmount(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
{
int multiplier;
int multiplier;
INIT;
CHECK_TAG(ASN1_TAG_SEQUENCE);
XSEQUENCE_1(ParseCurrencyAmount, ASN1_TAG_INTEGER, 1, &chanp->amount);
XSEQUENCE_1(ParseMultiplier, ASN1_TAG_INTEGER, 2, &multiplier);
MY_DEBUG("ParseAmount");
chanp->multiplier = pow(10, multiplier-3);
SEQ_TAGGED_1(ParseCurrencyAmount, 1, &aoc->amount);
SEQ_TAGGED_1(ParseMultiplier, 2, &multiplier);
aoc->multiplier = XMultiplier[multiplier];
print_msg(PRT_DEBUG_DECODE, " DEBUG> Amount = %d * %f\n",
aoc->amount, aoc->multiplier);
return 1;
return p - beg;
}
ELEMENT_1(ParseCurrencyAmount, int, amount)
// CurrencyAmount
int
ParseCurrencyAmount(struct Aoc *chanp, u_char *p, u_char *end, int *currencyAmount)
{
MY_DEBUG("ParseCurrencyAmount");
if (!ParseInteger(el, tag, amount)) return 0;
print_msg(PRT_DEBUG_DECODE, " DEBUG> CurrencyAmount = %d\n",
*amount);
return 1;
return ParseInteger(chanp, p, end, currencyAmount);
}
ELEMENT_1(ParseMultiplier, int, multiplier)
// Multiplier
int
ParseMultiplier(struct Aoc *chanp, u_char *p, u_char *end, int *multiplier)
{
MY_DEBUG("ParseMultiplier");
if (!ParseEnum(el, tag, multiplier)) return 0;
if ((*multiplier < 0) || (*multiplier > NMultiplier))
return 0;
print_msg(PRT_DEBUG_DECODE, " DEBUG> Multiplier = %f\n",
XMultiplier[*multiplier]);
return 1;
return ParseEnum(chanp, p, end, multiplier);
}
ELEMENT_1(ParseTypeOfUnit, int, typeOfUnit)
// TypeOfUnit
int
ParseTypeOfUnit(struct Aoc *chanp, u_char *p, u_char *end, int *typeOfUnit)
{
MY_DEBUG("ParseTypeOfUnit");
if (!ParseInteger(el, tag, typeOfUnit)) return 0;
print_msg(PRT_DEBUG_DECODE, " DEBUG> typeOfUnit = %d\n",
*typeOfUnit);
return 1;
return ParseInteger(chanp, p, end, typeOfUnit);
}
ELEMENT_1(ParseNumberOfUnits, int, numberOfUnits)
// NumberOfUnits
int
ParseNumberOfUnits(struct Aoc *chanp, u_char *p, u_char *end, int *numberOfUnits)
{
MY_DEBUG("ParseNumberOfUnits");
if (!ParseInteger(el, tag, numberOfUnits)) return 0;
print_msg(PRT_DEBUG_DECODE, " DEBUG> numberOfUnits = %d\n",
*numberOfUnits);
return 1;
return ParseInteger(chanp, p, end, numberOfUnits);
}
ELEMENT_1(ParseChargingAssociation, char, s)
// Charging Association
int
ParseChargingAssociation(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
{
int chargeIdentifier;
char partyNumber[30];
INIT;
MY_DEBUG("ParseChargingAssociation");
if ((el.tag &~ 0xa0) == 0) {
if (!ParsePartyNumber(el.content.elements[0], ASN1_NOT_TAGGED, s))
return 0;
} else {
if (!ParseChargeIdentifier(el, ASN1_NOT_TAGGED, &chargeIdentifier)) {
return 0;
} else {
sprintf(s, "%d", chargeIdentifier);
}
}
return 1;
XCHOICE_1(ParsePartyNumber, ASN1_TAG_SEQUENCE, 0, partyNumber);
XCHOICE(ParseChargeIdentifier, ASN1_TAG_INTEGER, ASN1_NOT_TAGGED);
XCHOICE_DEFAULT;
}
ELEMENT_1(ParseChargeIdentifier, int, chargeIdentifier)
// ChargeIdentifier
int
ParseChargeIdentifier(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
{
MY_DEBUG("ParseChargeIdentifier");
int chargeIdentifier;
if (!ParseInteger(el, tag, chargeIdentifier)) return 0;
print_msg(PRT_DEBUG_DECODE, " DEBUG> chargeIdentifier = %d\n",
*chargeIdentifier);
return 1;
return ParseInteger(chanp, p, end, &chargeIdentifier);
}

View File

@ -0,0 +1,61 @@
/* $Id: asn1_aoc.h,v 1.1 2000/01/20 07:30:09 kai Exp $
*
* ISDN accounting for isdn4linux. (ASN.1 parser)
*
* Copyright 1995 .. 2000 by Andreas Kool (akool@isdn4linux.de)
*
* ASN.1 parser written by Kai Germaschewski <kai@thphy.uni-duesseldorf.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: asn1_aoc.h,v $
* Revision 1.1 2000/01/20 07:30:09 kai
* rewrote the ASN.1 parsing stuff. No known problems so far, apart from the
* following:
*
* I don't use buildnumber() anymore to translate the numbers to aliases, because
* it apparently did never work quite right. If someone knows how to handle
* buildnumber(), we can go ahead and fix this.
*
*
*
*/
// ======================================================================
// AOC EN 300 182-1 V1.3.3
int ParseAOCDCurrency(struct Aoc *chanp, u_char *p, u_char *end, int dummy);
int ParseAOCDChargingUnit(struct Aoc *chanp,u_char *p, u_char *end, int dummy);
int ParseAOCECurrency(struct Aoc *chanp, u_char *p, u_char *end, int dummy);
int ParseAOCEChargingUnit(struct Aoc *chanp,u_char *p, u_char *end, int dummy);
int ParseAOCDCurrencyInfo(struct Aoc *chanp,u_char *p, u_char *end, int dummy);
int ParseAOCDChargingUnitInfo(struct Aoc *chanp,u_char *p, u_char *end, int dummy);
int ParseRecordedCurrency(struct Aoc *chanp,u_char *p, u_char *end, int dummy);
int ParseRecordedUnitsList(struct Aoc *chanp,u_char *p, u_char *end, int *recordedUnits);
int ParseTypeOfChargingInfo(struct Aoc *chanp,u_char *p, u_char *end, int *typeOfChargingInfo);
int ParseRecordedUnits(struct Aoc *chanp,u_char *p, u_char *end, int *recordedUnits);
int ParseAOCDBillingId(struct Aoc *chanp, u_char *p, u_char *end, int *billingId);
int ParseAOCECurrencyInfo(struct Aoc *chanp, u_char *p, u_char *end, int dummy);
int ParseAOCEChargingUnitInfo(struct Aoc *chanp,u_char *p, u_char *end, int dummy);
int ParseAOCEBillingId(struct Aoc *chanp,u_char *p, u_char *end, int *billingId);
int ParseCurrency(struct Aoc *chanp,u_char *p, u_char *end, char *currency);
int ParseAmount(struct Aoc *chanp,u_char *p, u_char *end, int dummy);
int ParseCurrencyAmount(struct Aoc *chanp,u_char *p, u_char *end, int *currencyAmount);
int ParseMultiplier(struct Aoc *chanp,u_char *p, u_char *end, int *multiplier);
int ParseTypeOfUnit(struct Aoc *chanp,u_char *p, u_char *end, int *typeOfUnit);
int ParseNumberOfUnits(struct Aoc *chanp,u_char *p, u_char *end, int *numberOfUnits);
int ParseChargingAssociation(struct Aoc *chanp,u_char *p, u_char *end, int dummy);
int ParseChargeIdentifier(struct Aoc *chanp,u_char *p, u_char *end, int dummy);

View File

@ -1,4 +1,4 @@
/* $Id: asn1_basic_service.c,v 1.4 1999/12/31 13:30:01 akool Exp $
/* $Id: asn1_basic_service.c,v 1.5 2000/01/20 07:30:09 kai Exp $
*
* ISDN accounting for isdn4linux. (ASN.1 parser)
*
@ -21,6 +21,14 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: asn1_basic_service.c,v $
* Revision 1.5 2000/01/20 07:30:09 kai
* rewrote the ASN.1 parsing stuff. No known problems so far, apart from the
* following:
*
* I don't use buildnumber() anymore to translate the numbers to aliases, because
* it apparently did never work quite right. If someone knows how to handle
* buildnumber(), we can go ahead and fix this.
*
* Revision 1.4 1999/12/31 13:30:01 akool
* isdnlog-4.00 (Millenium-Edition)
* - Oracle support added by Jan Bolt (Jan.Bolt@t-online.de)
@ -47,47 +55,43 @@
*
*/
#define _ASN1_BASIC_SERVICE_C
#include "asn1.h"
#include "asn1_generic.h"
#include "asn1_basic_service.h"
/* char* BasicService[NBasicService]; -lt- is in asn1.h */
ELEMENT_1(ParseBasicService, int, );
// ======================================================================
// Basic Service Elements EN 300 196-1 D.6
// --
char* BasicService[NBasicService] = {
"allServices",
"speech",
"unrestrictedDigitalInformation",
"audio3100Hz",
"unrestrictedDigitalInformationWithTonesAndAnnouncements",
"multirate", // 5
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", // 15
"?", "?", "?", "?", "?", "?", "?", "?",
"?", "?", "?", "?", "?", "?", "?", "?", // 31
"telephony", // 32
"teletex",
"telefaxGroup4Class1",
"videotexSyntaxBased",
"videotelephony",
"telefaxGroup2-3",
"telephony7kHz",
"euroFileTransfer",
"fileTransferAndAccessManagement",
"videoconference",
"audioGraphicConference", // 42
};
ELEMENT_1(ParseBasicService, int, basicService)
int ParseBasicService(struct Aoc *chanp, u_char *p, u_char *end, char *str)
{
MY_DEBUG("ParseBasicService");
int basicService;
int ret;
if (!ParseEnum(el, tag, basicService)) return 0;
ret = ParseEnum(chanp, p, end, &basicService);
if (ret < 0)
return ret;
if ((*basicService < 0) || (*basicService > NBasicService))
return 0;
switch (basicService) {
case 0: sprintf(str, "all services"); break;
case 1: sprintf(str, "speech"); break;
case 2: sprintf(str, "unrestricted digital"); break;
case 3: sprintf(str, "audio 3.1 kHz"); break;
case 4: sprintf(str, "unrestricted digital+"); break;
case 5: sprintf(str, "multirate"); break;
case 32: sprintf(str, "telephony 3.1 kHz"); break;
case 33: sprintf(str, "teletex"); break;
case 34: sprintf(str, "telefax G4"); break;
case 35: sprintf(str, "videotex"); break;
case 36: sprintf(str, "video telephony"); break;
case 37: sprintf(str, "telefax G2/G3"); break;
case 38: sprintf(str, "telephony 7 kHz"); break;
case 39: sprintf(str, "eurofile"); break;
case 40: sprintf(str, "file transfer"); break;
case 41: sprintf(str, "video conference"); break;
case 42: sprintf(str, "audio graphic conference"); break;
default: sprintf(str, "(%d)", basicService); break;
}
print_msg(PRT_DEBUG_DECODE, " DEBUG> basicService = %s\n",
BasicService[*basicService]);
return 1;
return ret;
}

View File

@ -0,0 +1,40 @@
/* $Id: asn1_basic_service.h,v 1.1 2000/01/20 07:30:09 kai Exp $
*
* ISDN accounting for isdn4linux. (ASN.1 parser)
*
* Copyright 1995 .. 2000 by Andreas Kool (akool@isdn4linux.de)
*
* ASN.1 parser written by Kai Germaschewski <kai@thphy.uni-duesseldorf.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: asn1_basic_service.h,v $
* Revision 1.1 2000/01/20 07:30:09 kai
* rewrote the ASN.1 parsing stuff. No known problems so far, apart from the
* following:
*
* I don't use buildnumber() anymore to translate the numbers to aliases, because
* it apparently did never work quite right. If someone knows how to handle
* buildnumber(), we can go ahead and fix this.
*
*
*
*/
// ======================================================================
// Basic Service Elements EN 300 196-1 D.6
int ParseBasicService(struct Aoc *chanp, u_char *p, u_char *end, char *str);

View File

@ -1,4 +1,4 @@
/* $Id: asn1_comp.c,v 1.3 1999/12/31 13:30:01 akool Exp $
/* $Id: asn1_comp.c,v 1.4 2000/01/20 07:30:09 kai Exp $
*
* ISDN accounting for isdn4linux. (ASN.1 parser)
*
@ -21,6 +21,14 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: asn1_comp.c,v $
* Revision 1.4 2000/01/20 07:30:09 kai
* rewrote the ASN.1 parsing stuff. No known problems so far, apart from the
* following:
*
* I don't use buildnumber() anymore to translate the numbers to aliases, because
* it apparently did never work quite right. If someone knows how to handle
* buildnumber(), we can go ahead and fix this.
*
* Revision 1.3 1999/12/31 13:30:01 akool
* isdnlog-4.00 (Millenium-Edition)
* - Oracle support added by Jan Bolt (Jan.Bolt@t-online.de)
@ -41,279 +49,145 @@
*
*/
#include "asn1.h"
#include "asn1_generic.h"
#include "asn1_diversion.h"
#include "asn1_aoc.h"
#include "asn1_comp.h"
ELEMENT_1(ParseComponent, Aoc, );
// ======================================================================
// Component EN 300 196-1 D.1
ELEMENT_1(ParseInvokeComponent, Aoc, );
ELEMENT_1(ParseReturnResultComponent, Aoc, );
ELEMENT_1(ParseReturnResultComponentSequence, char, msg);
ELEMENT_1(ParseReturnErrorComponent, Aoc, );
ELEMENT_1(ParseInvokeID, int, );
ELEMENT_1(ParseOperationValue, int, );
ELEMENT_1(ParseErrorValue, int, );
char* OperationValue[] = {
"?",
"uUsa", // 1
"cUGCall",
"mCIDRequest",
"beginTPY",
"endTPY", // 5
"eCTRequest",
"activationDiversion",
"deactivationDiversion",
"activationStatusNotificationDiv",
"deactivationStatusNotificationDiv", // 10
"interrogationDiversion",
"diversionInformation",
"callDeflection",
"callRerouting",
"divertingLegInformation2", // 15
"invokeStatus",
"interrogateServedUserNumbers",
"divertingLegInformation1",
"divertingLegInformation3",
"explicitReservationCreationControl", // 20
"explicitReservationManagement",
"explicitReservationCancel",
"?",
"mLPP lfb Query",
"mLPP Call Request", // 25
"mLPP Call preemption",
"?",
"?",
"?",
"chargingRequest", // 30
"aOCSCurrency",
"aOCSSpecialArrangement",
"aOCDCurrency",
"aOCDChargingUnit",
"aOCECurrency", // 35
"aOCEChargingUnit",
"identificationOfChange",
"?",
"?",
"beginConf", // 40
"addConf",
"splitConf",
"dropConf",
"IsolateConf",
"reattachConf", // 45
"partyDISC",
"floatConf",
"endConf",
"identifyConferee",
"?", // 50
"?",
"?",
"?",
"?",
"?", // 55
"?",
"?",
"?",
"?",
"requestREV", // 60
};
const int NOperationValue = 61;
char* ErrorValue[] = {
"notSubscribed",
"1", // 1
"2",
"notAvailable",
"notImplemented",
"5", // 5
"invalidServedUserNr",
"invalidCallState",
"basicServiceNotProvided",
"notIncomingCall",
"supplementaryServiceInteractionNotAllowed", // 10
"resourceUnavailable",
"invalidDivertedToNr",
"13",
"specialServiceNr",
"diversionToServedUserNr", // 15
"16",
"17",
"18",
"19",
"20", // 20
"21",
"22",
"incomingCallAccepted",
"numberOfDiversionsExceeded",
"25", // 25
"noChargingInfoAvailable",
"27",
"28",
"29",
"30", // 30
"31",
"32",
"33",
"34",
"35", // 35
"36",
"37",
"38",
"39",
"40", // 40
"41",
"42",
"43",
"44",
"45", // 45
"notActivated",
"47",
"requestAlreadyAccepted",
};
const int NErrorValue = 49;
// ---------------------------------------
ELEMENT_1(ParseComponent, Aoc, aoc)
int
ParseInvokeId(struct Aoc *chanp, u_char *p, u_char *end, int *invokeId)
{
MY_DEBUG("ParseComponent");
strcpy(aoc->msg, "");
switch (IMP_TAG(el.tag)) {
CASE_TAGGED_1(1, ParseInvokeComponent, aoc);
CASE_TAGGED_1(2, ParseReturnResultComponent, aoc);
CASE_TAGGED_1(3, ParseReturnErrorComponent, aoc);
default:
return 0;
}
#if 0 /* DEBUG */
if (strcmp(aoc->msg, "") != 0) {
print_msg(PRT_SHOWNUMBERS, "%s\n", aoc->msg);
}
#endif
return 1;
return ParseInteger(chanp, p, end, invokeId);
}
ELEMENT_1(ParseInvokeComponent, Aoc, aoc)
int
ParseErrorValue(struct Aoc *chanp, u_char *p, u_char *end, int *errorValue)
{
int invokeID, linkedID, operation;
CHECK_TAG(ASN1_TAG_SEQUENCE);
MY_DEBUG("ParseInvokeComponent");
SEQ_NOT_TAGGED_1(ParseInvokeID, &invokeID);
if ((el.content.elements[elnr].tag &~ 0xa0) == 0) {
SEQ_TAGGED_1(ParseInvokeID, 0, &linkedID);
}
SEQ_NOT_TAGGED_1(ParseOperationValue, &operation);
switch (operation) {
case 7 : SEQ_NOT_TAGGED_1(ParseARGActivationDiversion, aoc->msg); break;
case 8 : SEQ_NOT_TAGGED_1(ParseARGDeactivationDiversion, aoc->msg); break;
case 9 : SEQ_NOT_TAGGED_1(ParseARGActivationStatusNotificationDiv, aoc->msg); break;
case 10 : SEQ_NOT_TAGGED_1(ParseARGDeactivationStatusNotificationDiv, aoc->msg); break;
case 11 : SEQ_NOT_TAGGED_1(ParseARGInterrogationDiversion, aoc->msg); break;
case 12 : SEQ_NOT_TAGGED_1(ParseARGDiversionInformation, aoc->msg); break;
case 33 : SEQ_NOT_TAGGED_1(ParseARGAOCDCurrency, aoc); break;
case 34 : SEQ_NOT_TAGGED_1(ParseARGAOCDChargingUnit, aoc); break;
case 35 : SEQ_NOT_TAGGED_1(ParseARGAOCECurrency, aoc); break;
case 36 : SEQ_NOT_TAGGED_1(ParseARGAOCEChargingUnit, aoc); break;
}
return 1;
return ParseInteger(chanp, p, end, errorValue);
}
ELEMENT_1(ParseInvokeID, int, invokeID)
int
ParseOperationValue(struct Aoc *chanp, u_char *p, u_char *end, int *operationValue)
{
MY_DEBUG("ParseInvokeID");
if (!ParseInteger(el, tag, invokeID)) return 0;
print_msg(PRT_DEBUG_DECODE, " DEBUG> invokeID = %d\n",
*invokeID);
return 1;
return ParseInteger(chanp, p, end, operationValue);
}
ELEMENT_1(ParseReturnResultComponent, Aoc, aoc)
int
ParseInvokeComponent(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
{
int invokeID;
int invokeId, operationValue;
INIT;
CHECK_TAG(ASN1_TAG_SEQUENCE);
MY_DEBUG("ParseReturnResultComponent");
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);
switch (operationValue) {
case 7: XSEQUENCE(ParseARGActivationDiversion, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED); break;
case 8: XSEQUENCE(ParseARGDeactivationDiversion, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED); break;
case 9: XSEQUENCE(ParseARGActivationStatusNotificationDiv, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED); break;
case 10: XSEQUENCE(ParseARGDeactivationStatusNotificationDiv, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED); break;
case 11: XSEQUENCE(ParseARGInterrogationDiversion, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED); break;
case 12: XSEQUENCE(ParseARGDiversionInformation, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED); break;
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;
default:
return -1;
}
SEQ_NOT_TAGGED_1(ParseInvokeID, &invokeID);
SEQOPT_NOT_TAGGED_1(ParseReturnResultComponentSequence, aoc->msg);
switch (operationValue) {
case 33:
case 34:
case 35:
case 36:
chanp->type = operationValue;
break;
}
return 1;
return p - beg;
}
ELEMENT_1(ParseReturnResultComponentSequence, char, msg)
int
ParseReturnResultComponentSequence(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
{
int operationValue;
int operationValue;
INIT;
CHECK_TAG(ASN1_TAG_SEQUENCE);
MY_DEBUG("ParseReturnResultComponentSequence");
SEQ_NOT_TAGGED_1(ParseOperationValue, &operationValue);
switch (operationValue) {
case 11 : SEQ_NOT_TAGGED_1(ParseRESInterrogationDiversion, msg); break;
case 17 : SEQ_NOT_TAGGED_1(ParseRESInterrogateServedUserNumbers, msg); break;
}
return 1;
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;
}
ELEMENT_1(ParseReturnErrorComponent, Aoc, aoc)
int
ParseReturnResultComponent(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
{
int invokeID, errorValue;
int invokeId;
INIT;
CHECK_TAG(ASN1_TAG_SEQUENCE);
MY_DEBUG("ParseReturnErrorComponent");
XSEQUENCE_1(ParseInvokeId, ASN1_TAG_INTEGER, ASN1_NOT_TAGGED, &invokeId);
XSEQUENCE_OPT(ParseReturnResultComponentSequence, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED);
SEQ_NOT_TAGGED_1(ParseInvokeID, &invokeID);
SEQ_NOT_TAGGED_1(ParseErrorValue, &errorValue);
sprintf(aoc->msg, "ERROR: %s", ErrorValue[errorValue]);
switch (errorValue) {
}
return 1;
return p - beg;
}
ELEMENT_1(ParseOperationValue, int, operationValue)
int
ParseReturnErrorComponent(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
{
MY_DEBUG("ParseOperationValue");
int invokeId;
int errorValue;
char error[80];
INIT;
if (!ParseInteger(el, tag, operationValue)) return 0;
XSEQUENCE_1(ParseInvokeId, ASN1_TAG_INTEGER, ASN1_NOT_TAGGED, &invokeId);
XSEQUENCE_1(ParseErrorValue, ASN1_TAG_INTEGER, ASN1_NOT_TAGGED, &errorValue);
if ((*operationValue < 0) || (*operationValue > NOperationValue))
return 0;
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_msg(PRT_SHOWNUMBERS, "ReturnError: %s\n", error);
print_msg(PRT_DEBUG_DECODE, " DEBUG> operationValue = %s\n",
OperationValue[*operationValue]);
return 1;
return p - beg;
}
ELEMENT_1(ParseErrorValue, int, errorValue)
int
ParseComponent(struct Aoc *chanp, u_char *p, u_char *end)
{
MY_DEBUG("ParseErrorValue");
INIT;
if (!ParseInteger(el, tag, errorValue)) return 0;
if ((*errorValue < 0) || (*errorValue > NErrorValue))
return 0;
print_msg(PRT_DEBUG_DECODE, " DEBUG> errorValue = %s\n",
ErrorValue[*errorValue]);
return 1;
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_DEFAULT;
}

View File

@ -0,0 +1,41 @@
/* $Id: asn1_comp.h,v 1.1 2000/01/20 07:30:09 kai Exp $
*
* ISDN accounting for isdn4linux. (ASN.1 parser)
*
* Copyright 1995 .. 2000 by Andreas Kool (akool@isdn4linux.de)
*
* ASN.1 parser written by Kai Germaschewski <kai@thphy.uni-duesseldorf.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: asn1_comp.h,v $
* Revision 1.1 2000/01/20 07:30:09 kai
* rewrote the ASN.1 parsing stuff. No known problems so far, apart from the
* following:
*
* I don't use buildnumber() anymore to translate the numbers to aliases, because
* it apparently did never work quite right. If someone knows how to handle
* buildnumber(), we can go ahead and fix this.
*
*
*
*/
int ParseInvokeId(struct Aoc *chanp,u_char *p, u_char *end, int *invokeId);
int ParseOperationValue(struct Aoc *chanp,u_char *p, u_char *end, int *operationValue);
int ParseInvokeComponent(struct Aoc *chanp,u_char *p, u_char *end, int dummy);
int ParseReturnResultComponent(struct Aoc *chanp,u_char *p, u_char *end, int dummy);
int ParseComponent(struct Aoc *chanp, u_char *p, u_char *end);

View File

@ -1,4 +1,4 @@
/* $Id: asn1_diversion.c,v 1.4 1999/12/31 13:30:01 akool Exp $
/* $Id: asn1_diversion.c,v 1.5 2000/01/20 07:30:09 kai Exp $
*
* ISDN accounting for isdn4linux. (ASN.1 parser)
*
@ -21,6 +21,14 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: asn1_diversion.c,v $
* Revision 1.5 2000/01/20 07:30:09 kai
* rewrote the ASN.1 parsing stuff. No known problems so far, apart from the
* following:
*
* I don't use buildnumber() anymore to translate the numbers to aliases, because
* it apparently did never work quite right. If someone knows how to handle
* buildnumber(), we can go ahead and fix this.
*
* Revision 1.4 1999/12/31 13:30:01 akool
* isdnlog-4.00 (Millenium-Edition)
* - Oracle support added by Jan Bolt (Jan.Bolt@t-online.de)
@ -49,320 +57,278 @@
*
*/
#include "asn1.h"
#include "asn1_generic.h"
#include "asn1_address.h"
#include "asn1_basic_service.h"
#include "asn1_diversion.h"
ELEMENT_1(ParseARGActivationDiversion, char, );
ELEMENT_1(ParseARGDeactivationDiversion, char, );
ELEMENT_1(ParseARGActivationStatusNotificationDiv, char, );
ELEMENT_1(ParseARGDeactivationStatusNotificationDiv, char, );
ELEMENT_1(ParseARGInterrogationDiversion, char, );
ELEMENT_1(ParseARGDiversionInformation, char, );
ELEMENT_1(ParseRESInterrogationDiversion, char, );
ELEMENT_1(ParseRESInterrogateServedUserNumbers, char, );
// ======================================================================
// Diversion Supplementary Services ETS 300 207-1 Table 3
ELEMENT_1(ParseIntResultList, char, );
ELEMENT_1(ParseIntResult, char, );
ELEMENT_1(ParseServedUserNr, char, );
ELEMENT_1(ParseProcedure, int, );
ELEMENT_1(ParseDiversionReason, int, );
ELEMENT_1(ParseBasicService, int, );
char* Procedure[] = {
"CFU",
"CFB",
"CFNR",
};
const int NProcedure = 3;
char* DiversionReason[] = {
"unknown",
"CFU",
"CFB",
"CFNR",
"CD Alerting",
"CD Immediate",
};
const int NDiversionReason = 6;
ELEMENT_1(ParseARGActivationDiversion, char, s)
int
ParseARGActivationDiversion(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
{
int procedure, basicService;
char forwardedToAddress[BUF_SIZE], servedUserNr[BUF_SIZE];
auto char vsrc[BUFSIZ], vdst[BUFSIZ];
auto int a1, a2, a3, a4;
char procedure[10];
char basicService[30];
char servedUserNr[30];
char address[60];
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);
CHECK_TAG(ASN1_TAG_SEQUENCE)
MY_DEBUG("ParseARGActivationDiversion");
SEQ_NOT_TAGGED_1(ParseProcedure, &procedure);
SEQ_NOT_TAGGED_1(ParseBasicService, &basicService);
SEQ_NOT_TAGGED_1(ParseAddress, forwardedToAddress);
SEQ_NOT_TAGGED_1(ParseServedUserNr, servedUserNr);
buildnumber(servedUserNr, 0, 0, call[6].num[CLIP], VERSION_EDSS1, &a1, &a2, &a3, &a4, 0, 999);
strcpy(vsrc, vnum(6, CLIP));
buildnumber(forwardedToAddress, 0, 0, call[6].num[CLIP], VERSION_EDSS1, &a1, &a2, &a3, &a4, 0, 999);
strcpy(vdst, vnum(6, CLIP));
sprintf(s, "activate %s %s/%s -> %s",
Procedure[procedure], vsrc, BasicService[basicService], vdst);
return 1;
print_msg(PRT_SHOWNUMBERS, "Activation Diversion %s (%s), %s -> %s\n",
procedure, basicService, servedUserNr, address);
return p - beg;
}
ELEMENT_1(ParseARGDeactivationDiversion, char, s)
int
ParseARGDeactivationDiversion(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
{
int procedure, basicService;
char servedUserNr[BUF_SIZE];
auto char vsrc[BUFSIZ];
auto int a1, a2, a3, a4;
char procedure[10];
char basicService[30];
char servedUserNr[30];
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);
CHECK_TAG(ASN1_TAG_SEQUENCE)
MY_DEBUG("ParseARGDeactivationDiversion");
SEQ_NOT_TAGGED_1(ParseProcedure, &procedure);
SEQ_NOT_TAGGED_1(ParseBasicService, &basicService);
SEQ_NOT_TAGGED_1(ParseServedUserNr, servedUserNr);
buildnumber(servedUserNr, 0, 0, call[6].num[CLIP], VERSION_EDSS1, &a1, &a2, &a3, &a4, 0, 999);
strcpy(vsrc, vnum(6, CLIP));
sprintf(s, "deactivate %s %s/%s",
Procedure[procedure], vsrc, BasicService[basicService]);
return 1;
print_msg(PRT_SHOWNUMBERS, "Deactivation Diversion %s (%s), %s\n",
procedure, basicService, servedUserNr);
return p - beg;
}
ELEMENT_1(ParseARGActivationStatusNotificationDiv, char, s)
int
ParseARGActivationStatusNotificationDiv(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
{
int procedure, basicService;
char forwardedToAddress[BUF_SIZE], servedUserNr[BUF_SIZE];
char procedure[10];
char basicService[30];
char servedUserNr[30];
char address[60];
INIT;
CHECK_TAG(ASN1_TAG_SEQUENCE)
MY_DEBUG("ParseARGActivationStatusNotificationDiv");
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);
SEQ_NOT_TAGGED_1(ParseProcedure, &procedure);
SEQ_NOT_TAGGED_1(ParseBasicService, &basicService);
SEQ_NOT_TAGGED_1(ParseAddress, forwardedToAddress);
SEQ_NOT_TAGGED_1(ParseServedUserNr, servedUserNr);
sprintf(s, "NOTIFICATION: activated %s %s/%s -> %s",
Procedure[procedure], servedUserNr, BasicService[basicService],
forwardedToAddress);
return 1;
print_msg(PRT_SHOWNUMBERS, "Notification: Activated Diversion %s (%s), %s -> %s\n",
procedure, basicService, servedUserNr, address);
return p - beg;
}
ELEMENT_1(ParseARGDeactivationStatusNotificationDiv, char, s)
int
ParseARGDeactivationStatusNotificationDiv(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
{
int procedure, basicService;
char servedUserNr[BUF_SIZE];
char procedure[10];
char basicService[30];
char servedUserNr[30];
INIT;
CHECK_TAG(ASN1_TAG_SEQUENCE)
MY_DEBUG("ParseARGDeactivationStatusNotificationDiv");
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);
SEQ_NOT_TAGGED_1(ParseProcedure, &procedure);
SEQ_NOT_TAGGED_1(ParseBasicService, &basicService);
SEQ_NOT_TAGGED_1(ParseServedUserNr, servedUserNr);
sprintf(s, "NOTIFICATION: deactivated %s %s/%s",
Procedure[procedure], servedUserNr, BasicService[basicService]);
return 1;
print_msg(PRT_SHOWNUMBERS, "Notification: Deactivated Diversion %s (%s), %s\n",
procedure, basicService, servedUserNr);
return p - beg;
}
ELEMENT_1(ParseARGInterrogationDiversion, char, s)
int
ParseARGInterrogationDiversion(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
{
int procedure, basicService;
char servedUserNr[BUF_SIZE];
char procedure[10];
char basicService[30];
char servedUserNr[30];
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);
CHECK_TAG(ASN1_TAG_SEQUENCE)
MY_DEBUG("ParseARGInterrogationDiversion");
SEQ_NOT_TAGGED_1(ParseProcedure, &procedure);
SEQ_NOT_TAGGED_1(ParseBasicService, &basicService); // todo DEFAULT
SEQ_NOT_TAGGED_1(ParseServedUserNr, servedUserNr);
sprintf(s, "InterrogationDiversion: %s(%s) %s",
Procedure[procedure], BasicService[basicService],
servedUserNr);
return 1;
print_msg(PRT_SHOWNUMBERS, "Interrogation Diversion %s (%s), %s\n",
procedure, basicService, servedUserNr);
return p - beg;
}
ELEMENT_1(ParseARGDiversionInformation, char, res)
int
ParseRESInterrogationDiversion(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
{
int diversionReason, basicService, lastDivertingReason;
char servedUserSubaddress[25], callingAddress[255], originalCalledNr[255],
lastDivertingNr[255]; // , userInfo[255];
print_msg(PRT_SHOWNUMBERS, "Interrogation Diversion Result\n");
CHECK_TAG(ASN1_TAG_SEQUENCE)
MY_DEBUG("ParseARGDiversionInformation");
SEQ_NOT_TAGGED_1(ParseDiversionReason, &diversionReason);
SEQ_NOT_TAGGED_1(ParseBasicService, &basicService);
if ((el.content.elements[elnr].tag & 0x80) == 0) {
SEQ_NOT_TAGGED_1(ParsePartySubaddress, servedUserSubaddress);
} else {
strcpy(servedUserSubaddress, "-");
}
if ((elnr < el.length) && (el.content.elements[elnr].tag &~ 0x20) == 0x80) {
SEQ_EXP_TAGGED_1(ParsePresentedAddressScreened, callingAddress);
} else {
strcpy(callingAddress, "-");
}
if ((elnr < el.length) && (el.content.elements[elnr].tag &~ 0x20) == 0x81) {
SEQ_EXP_TAGGED_1(ParsePresentedNumberUnscreened, originalCalledNr);
} else {
strcpy(originalCalledNr, "-");
}
if ((elnr < el.length) && (el.content.elements[elnr].tag &~ 0x20) == 0x82) {
SEQ_EXP_TAGGED_1(ParsePresentedNumberUnscreened, lastDivertingNr);
} else {
strcpy(lastDivertingNr, "-");
}
if ((elnr < el.length) && (el.content.elements[elnr].tag &~ 0x20) == 0x83) {
SEQ_EXP_TAGGED_1(ParseDiversionReason, &lastDivertingReason);
} else {
lastDivertingReason = -1;
}
// SEQOPT_NOT_TAGGED_1(ParseQ931InformationElement, userInfo);
sprintf(res, "DiversionInformation: %s (%s), servedUserSubaddress = %s, callingAddress = %s, originalCalledNr = %s, lastDivertingNr = %s, lastDivertingReason = %s",
DiversionReason[diversionReason], BasicService[basicService],
servedUserSubaddress, callingAddress, originalCalledNr,
lastDivertingNr,
(lastDivertingReason == -1)?"-":DiversionReason[lastDivertingReason]);
return 1;
return ParseIntResultList(chanp, p, end, dummy);
}
ELEMENT_1(ParseRESInterrogationDiversion, char, res)
int
ParseARGInterrogateServedUserNumbers(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
{
char s[BUF_SIZE];
MY_DEBUG("ParseRESInterrogationDiversion");
if (!ParseIntResultList(el, tag, s)) return 0;
sprintf(res, "InterrogationDiversion Result: %s", s);
return 1;
print_msg(PRT_SHOWNUMBERS, "Interrogate Served User Numbers\n");
return 0;
}
ELEMENT_1(ParseServedUserNumberList, char, res)
int
ParseRESInterrogateServedUserNumbers(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
{
int i;
char num[BUF_SIZE];
int ret;
char servedUserNumberList[200] = "";
CHECK_TAG(ASN1_TAG_SET);
MY_DEBUG("ParseServedUserNumberList");
ret = ParseServedUserNumberList(chanp, p, end, servedUserNumberList);
if (ret < 0)
return ret;
for (i = 0; i < el.length; i++) {
if (!ParsePartyNumber(el.content.elements[i], -1, num)) return 0;
if (i == 0) {
sprintf(res, "%s", num);
} else {
sprintf(res, "%s %s", res, num);
}
}
return 1;
print_msg(PRT_SHOWNUMBERS, "Interrogate Served User Numbers: %s\n",
servedUserNumberList);
return ret;
}
ELEMENT_1(ParseRESInterrogateServedUserNumbers, char, res)
int
ParseARGDiversionInformation(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
{
char s[BUF_SIZE];
char diversionReason[20];
char basicService[30];
char servedUserSubaddress[30] = "";
char callingAddress[80] = "-";
char originalCalledNr[80] = "-";
char lastDivertingNr[80] = "-";
char lastDivertingReason[20] = "-";
INIT;
MY_DEBUG("ParseRESInterrogateServedUserNumbers");
if (!ParseServedUserNumberList(el, tag, s)) return 0;
sprintf(res, "InterrogateServedUserNumbers Result: %s", s);
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);
return 1;
print_msg(PRT_SHOWNUMBERS, "Diversion Information %s(%s) %s\n"
" callingAddress %s originalCalled Nr %s\n"
" lastDivertingNr %s lastDiverting Reason %s\n",
diversionReason, basicService, servedUserSubaddress, callingAddress,
originalCalledNr, lastDivertingNr, lastDivertingReason);
return p - beg;
}
ELEMENT_1(ParseProcedure, int, procedure)
int
ParseIntResultList(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
{
MY_DEBUG("ParseProcedure");
int i;
INIT;
if (!ParseEnum(el, tag, procedure)) return 0;
for (i = 0; i < 29; i++) {
XSEQUENCE_OPT(ParseIntResult, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED);
}
if ((*procedure < 0) || (*procedure > NProcedure))
return 0;
print_msg(PRT_DEBUG_DECODE, " DEBUG> procedure = %s\n",
Procedure[*procedure]);
return 1;
return p - beg;
}
ELEMENT_1(ParseDiversionReason, int, diversionReason)
int
ParseIntResult(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
{
MY_DEBUG("ParseDiversionReason");
char procedure[10];
char basicService[30];
char servedUserNr[30];
char address[60];
INIT;
if (!ParseEnum(el, tag, diversionReason)) return 0;
XSEQUENCE_1(ParseServedUserNr, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, servedUserNr);
XSEQUENCE_1(ParseBasicService, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, basicService);
XSEQUENCE_1(ParseProcedure, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, procedure);
XSEQUENCE_1(ParseAddress, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, address);
if ((*diversionReason < 0) || (*diversionReason > NDiversionReason))
return 0;
print_msg(PRT_DEBUG_DECODE, " DEBUG> diversionReason = %s\n",
DiversionReason[*diversionReason]);
return 1;
print_msg(PRT_SHOWNUMBERS, " %s (%s), %s -> %s\n",
procedure, basicService, servedUserNr, address);
return p - beg;
}
ELEMENT_1(ParseServedUserNr, char, num)
int
ParseServedUserNrAll(struct Aoc *chanp, u_char *p, u_char *end, char *servedUserNr)
{
MY_DEBUG("ParseServedUserNr");
int ret;
if (el.tag == 0x05) {
strcpy(num, "allNumbers");
} else {
if (!ParsePartyNumber(el, ASN1_NOT_TAGGED, num)) return 0;
}
ret = ParseNull(chanp, p, end, 0);
if (ret < 0)
return ret;
sprintf(servedUserNr, "(all)");
print_msg(PRT_DEBUG_DECODE, " DEBUG> ServedUserNr = %s\n", num);
return 1;
return ret;
}
ELEMENT_1(ParseIntResult, char, s)
int
ParseServedUserNr(struct Aoc *chanp, u_char *p, u_char *end, char *servedUserNr)
{
int procedure, basicService;
char servedUserNr[BUF_SIZE], forwardedToAddress[BUF_SIZE];
INIT;
*servedUserNr = 0;
CHECK_TAG(ASN1_TAG_SEQUENCE);
MY_DEBUG("ParseIntResult");
SEQ_NOT_TAGGED_1(ParseServedUserNr, servedUserNr);
SEQ_NOT_TAGGED_1(ParseBasicService, &basicService);
SEQ_NOT_TAGGED_1(ParseProcedure, &procedure);
SEQ_NOT_TAGGED_1(ParseAddress, forwardedToAddress);
sprintf(s, "%s(%s) %s -> %s", Procedure[procedure],
BasicService[basicService], servedUserNr, forwardedToAddress);
MY_DEBUG(s);
return 1;
XCHOICE_1(ParseServedUserNrAll, ASN1_TAG_NULL, ASN1_NOT_TAGGED, servedUserNr);
XCHOICE_1(ParsePartyNumber, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, servedUserNr);
XCHOICE_DEFAULT;
}
ELEMENT_1(ParseIntResultList, char, s)
int
ParseProcedure(struct Aoc *chanp, u_char *p, u_char *end, char *str)
{
int i;
char res[BUF_SIZE];
int ret;
int procedure;
CHECK_TAG(ASN1_TAG_SET);
MY_DEBUG("ParseIntResultList");
ret = ParseEnum(chanp, p, end, &procedure);
if (ret < 0)
return ret;
switch (procedure) {
case 0: sprintf(str, "CFU"); break;
case 1: sprintf(str, "CFB"); break;
case 2: sprintf(str, "CFNR"); break;
default: sprintf(str, "(%d)", procedure); break;
}
for (i = 0; i < el.length; i++) {
if (!ParseIntResult(el.content.elements[i], ASN1_NOT_TAGGED, res)) return 0;
if (i == 0) {
sprintf(s, "%s", res);
} else {
sprintf(s, "%s; %s", s, res);
}
}
return 1;
return ret;
}
int
ParseServedUserNumberList(struct Aoc *chanp, u_char *p, u_char *end, char *str)
{
char partyNumber[30];
int i;
INIT;
for (i = 0; i < 9; i++) { // 99
partyNumber[0] = 0;
XSEQUENCE_OPT_1(ParsePartyNumber, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, partyNumber);
if (partyNumber[0]) {
str += sprintf(str, "%s ", partyNumber);
}
}
return p - beg;
}
int
ParseDiversionReason(struct Aoc *chanp, u_char *p, u_char *end, char *str)
{
int ret;
int diversionReason;
ret = ParseEnum(chanp, 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;
}

View File

@ -0,0 +1,54 @@
/* $Id: asn1_diversion.h,v 1.1 2000/01/20 07:30:09 kai Exp $
*
* ISDN accounting for isdn4linux. (ASN.1 parser)
*
* Copyright 1995 .. 2000 by Andreas Kool (akool@isdn4linux.de)
*
* ASN.1 parser written by Kai Germaschewski <kai@thphy.uni-duesseldorf.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: asn1_diversion.h,v $
* Revision 1.1 2000/01/20 07:30:09 kai
* rewrote the ASN.1 parsing stuff. No known problems so far, apart from the
* following:
*
* I don't use buildnumber() anymore to translate the numbers to aliases, because
* it apparently did never work quite right. If someone knows how to handle
* buildnumber(), we can go ahead and fix this.
*
*
*
*/
// ======================================================================
// Diversion Supplementary Services ETS 300 207-1 Table 3
int ParseARGActivationDiversion(struct Aoc *chanp, u_char *p, u_char *end, int dummy);
int ParseARGActivationStatusNotificationDiv(struct Aoc *chanp, u_char *p, u_char *end, int dummy);
int ParseARGDeactivationDiversion(struct Aoc *chanp, u_char *p, u_char *end, int dummy);
int ParseARGDeactivationStatusNotificationDiv(struct Aoc *chanp, u_char *p, u_char *end, int dummy);
int ParseARGInterrogationDiversion(struct Aoc *chanp, u_char *p, u_char *end, int dummy);
int ParseRESInterrogationDiversion(struct Aoc *chanp, u_char *p, u_char *end, int dummy);
int ParseARGInterrogateServedUserNumbers(struct Aoc *chanp, u_char *p, u_char *end, int dummy);
int ParseRESInterrogateServedUserNumbers(struct Aoc *chanp, u_char *p, u_char *end, int dummy);
int ParseARGDiversionInformation(struct Aoc *chanp, u_char *p, u_char *end, int dummy);
int ParseIntResult(struct Aoc *chanp, u_char *p, u_char *end, int dummy);
int ParseIntResultList(struct Aoc *chanp, u_char *p, u_char *end, int dummy);
int ParseServedUserNr(struct Aoc *chanp, u_char *p, u_char *end, char *str);
int ParseProcedure(struct Aoc *chanp, u_char *p, u_char *end, char *str);
int ParseServedUserNumberList(struct Aoc *chanp, u_char *p, u_char *end, char *str);
int ParseDiversionReason(struct Aoc *chanp, u_char *p, u_char *end, char *str);

View File

@ -1,4 +1,4 @@
/* $Id: asn1_generic.c,v 1.3 1999/12/31 13:30:01 akool Exp $
/* $Id: asn1_generic.c,v 1.4 2000/01/20 07:30:09 kai Exp $
*
* ISDN accounting for isdn4linux. (ASN.1 parser)
*
@ -21,6 +21,14 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: asn1_generic.c,v $
* Revision 1.4 2000/01/20 07:30:09 kai
* rewrote the ASN.1 parsing stuff. No known problems so far, apart from the
* following:
*
* I don't use buildnumber() anymore to translate the numbers to aliases, because
* it apparently did never work quite right. If someone knows how to handle
* buildnumber(), we can go ahead and fix this.
*
* Revision 1.3 1999/12/31 13:30:01 akool
* isdnlog-4.00 (Millenium-Edition)
* - Oracle support added by Jan Bolt (Jan.Bolt@t-online.de)
@ -41,91 +49,113 @@
*
*/
#include "asn1.h"
#include "asn1_generic.h"
ELEMENT_1(ParseInteger, int, integer)
// ======================================================================
// general ASN.1
int
ParseBoolean(struct Aoc *chanp, u_char *p, u_char *end, int *i)
{
CHECK_TAG(ASN1_TAG_INTEGER);
INIT;
*integer = octets2Int(el);
print_msg(PRT_DEBUG_DECODE, " DEBUG> Integer = %d\n", *integer);
return 1;
*i = 0;
while (len--) {
CHECK_P;
*i = (*i >> 8) + *p;
p++;
}
print_msg(PRT_DEBUG_DECODE, " DEBUG> BOOL = %d %#x\n", *i, *i);
return p - beg;
}
ELEMENT_1(ParseOctetString, char, s)
int
ParseNull(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
{
char *px;
int i;
INIT;
CHECK_TAG(ASN1_TAG_OCTET_STRING);
px = s;
for (i = 0; i < el.length; i++) {
px += strlen(px);
sprintf(px, "%2x ", el.content.octets[i]);
}
print_msg(PRT_DEBUG_DECODE, " DEBUG> Octet String = %s\n", s);
return 1;
return p - beg;
}
ELEMENT(ParseNull)
int
ParseInteger(struct Aoc *chanp, u_char *p, u_char *end, int *i)
{
CHECK_TAG(ASN1_TAG_NULL);
INIT;
return 1;
*i = 0;
while (len--) {
CHECK_P;
*i = (*i >> 8) + *p;
p++;
}
print_msg(PRT_DEBUG_DECODE, " DEBUG> INT = %d %#x\n", *i, *i);
return p - beg;
}
ELEMENT_1(ParseEnum, int, num)
int
ParseEnum(struct Aoc *chanp, u_char *p, u_char *end, int *i)
{
CHECK_TAG(ASN1_TAG_ENUM);
INIT;
*num = octets2Int(el);
print_msg(PRT_DEBUG_DECODE, " DEBUG> Enum = %d\n", *num);
return 1;
*i = 0;
while (len--) {
CHECK_P;
*i = (*i >> 8) + *p;
p++;
}
print_msg(PRT_DEBUG_DECODE, " DEBUG> ENUM = %d %#x\n", *i, *i);
return p - beg;
}
ELEMENT_1(ParseBoolean, int, bl)
int
ParseIA5String(struct Aoc *chanp, u_char *p, u_char *end, char *str)
{
CHECK_TAG(ASN1_TAG_BOOLEAN);
INIT;
if (octets2Int(el))
*bl = 1;
else
*bl = 0;
print_msg(PRT_DEBUG_DECODE, " DEBUG> Bool = %d\n", *bl);
return 1;
print_msg(PRT_DEBUG_DECODE, " DEBUG> IA5 = ");
while (len--) {
CHECK_P;
print_msg(PRT_DEBUG_DECODE, "%c", *p);
*str++ = *p;
p++;
}
print_msg(PRT_DEBUG_DECODE, "\n");
*str = 0;
return p - beg;
}
ELEMENT_1(ParseNumericString, char, s)
int
ParseNumericString(struct Aoc *chanp, u_char *p, u_char *end, char *str)
{
CHECK_TAG(ASN1_TAG_NUMERIC_STRING);
INIT;
strncpy(s, el.content.octets, el.length);
s[el.length] = 0;
print_msg(PRT_DEBUG_DECODE, " DEBUG> NumericString = %s\n", s);
return 1;
print_msg(PRT_DEBUG_DECODE, " DEBUG> NumStr = ");
while (len--) {
CHECK_P;
print_msg(PRT_DEBUG_DECODE, "%c", *p);
*str++ = *p;
p++;
}
print_msg(PRT_DEBUG_DECODE, "\n");
*str = 0;
return p - beg;
}
ELEMENT_1(ParseIA5String, char, s)
int
ParseOctetString(struct Aoc *chanp, u_char *p, u_char *end, char *str)
{
CHECK_TAG(ASN1_TAG_IA5_STRING);
INIT;
strncpy(s, el.content.octets, el.length);
s[el.length] = 0;
print_msg(PRT_DEBUG_DECODE, " DEBUG> IA5String = %s\n", s);
return 1;
print_msg(PRT_DEBUG_DECODE, " DEBUG> Octets = ");
while (len--) {
CHECK_P;
print_msg(PRT_DEBUG_DECODE, " %02x", *p);
*str++ = *p;
p++;
}
print_msg(PRT_DEBUG_DECODE, "\n");
*str = 0;
return p - beg;
}

View File

@ -0,0 +1,46 @@
/* $Id: asn1_generic.h,v 1.1 2000/01/20 07:30:09 kai Exp $
*
* ISDN accounting for isdn4linux. (ASN.1 parser)
*
* Copyright 1995 .. 2000 by Andreas Kool (akool@isdn4linux.de)
*
* ASN.1 parser written by Kai Germaschewski <kai@thphy.uni-duesseldorf.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: asn1_generic.h,v $
* Revision 1.1 2000/01/20 07:30:09 kai
* rewrote the ASN.1 parsing stuff. No known problems so far, apart from the
* following:
*
* I don't use buildnumber() anymore to translate the numbers to aliases, because
* it apparently did never work quite right. If someone knows how to handle
* buildnumber(), we can go ahead and fix this.
*
*
*
*/
// ======================================================================
// general ASN.1
int ParseBoolean(struct Aoc *chanp, u_char *p, u_char *end, int *i);
int ParseNull(struct Aoc *chanp, u_char *p, u_char *end, int dummy);
int ParseInteger(struct Aoc *chanp, u_char *p, u_char *end, int *i);
int ParseEnum(struct Aoc *chanp, u_char *p, u_char *end, int *i);
int ParseIA5String(struct Aoc *chanp, u_char *p, u_char *end, char *str);
int ParseNumericString(struct Aoc *chanp, u_char *p, u_char *end, char *str);
int ParseOctetString(struct Aoc *chanp, u_char *p, u_char *end, char *str);

View File

@ -1,4 +1,4 @@
/* $Id: processor.c,v 1.95 2000/01/12 23:22:52 akool Exp $
/* $Id: processor.c,v 1.96 2000/01/20 07:30:09 kai Exp $
*
* ISDN accounting for isdn4linux. (log-module)
*
@ -19,6 +19,14 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: processor.c,v $
* Revision 1.96 2000/01/20 07:30:09 kai
* rewrote the ASN.1 parsing stuff. No known problems so far, apart from the
* following:
*
* I don't use buildnumber() anymore to translate the numbers to aliases, because
* it apparently did never work quite right. If someone knows how to handle
* buildnumber(), we can go ahead and fix this.
*
* Revision 1.95 2000/01/12 23:22:52 akool
* - isdnlog/tools/holiday.c ... returns ERVERYDAY for '*'
* - FAQ/configure{,.in} ... test '==' => '='
@ -864,6 +872,7 @@
#include "isdnlog.h"
#include "sys/times.h"
#include "asn1.h"
#include "asn1_comp.h"
#include "zone.h"
#include "telnum.h"
#if HAVE_ABCEXT
@ -1219,25 +1228,29 @@ void aoc_debug(int val, char *s)
*/
static int parseRemoteOperationProtocol(char **asnp, Aoc *aoc)
static int parseRemoteOperationProtocol(char **asnp, struct Aoc *aoc)
{
auto Element el;
char msg[255];
char *p = msg;
char *asne = *asnp + strlen(*asnp);
*asnp += 3;
while (*asnp < asne) {
*p++ = strtol(*asnp, NIL, 16);
*asnp += 3;
}
ParseASN1(msg, p, 0);
if (ParseComponent(aoc, msg, p) < 0)
return 0;
splitASN1(asnp, 0, &el);
printASN1(el, 0);
if (!ParseComponent(el, ASN1_NOT_TAGGED, aoc))
return(0);
return(1);
return 1;
} /* parseRemoteOperationProtocol */
static int facility(int l, char* p)
{
auto int c;
static Aoc aoc;
static struct Aoc aoc;
asnp = p;
@ -1271,7 +1284,7 @@ static int facility(int l, char* p)
currency_factor = aoc.multiplier;
if (*aoc.currency)
currency = aoc.currency;
currency = aoc.currency;
return(aoc.amount);