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:
parent
c972a91eea
commit
450863ca2b
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue