365 lines
10 KiB
C
365 lines
10 KiB
C
/* $Id: asn1_diversion.c,v 1.3 1999/05/04 19:32:33 akool Exp $
|
|
*
|
|
* ISDN accounting for isdn4linux. (ASN.1 parser)
|
|
*
|
|
* Copyright 1995, 1999 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.c,v $
|
|
* Revision 1.3 1999/05/04 19:32:33 akool
|
|
* isdnlog Version 3.24
|
|
*
|
|
* - fully removed "sondernummern.c"
|
|
* - removed "gcc -Wall" warnings in ASN.1 Parser
|
|
* - many new entries for "rate-de.dat"
|
|
* - better "isdnconf" utility
|
|
*
|
|
* Revision 1.2 1999/04/26 22:11:56 akool
|
|
* isdnlog Version 3.21
|
|
*
|
|
* - CVS headers added to the asn* files
|
|
* - repaired the "4.CI" message directly on CONNECT
|
|
* - HANGUP message extended (CI's and EH's shown)
|
|
* - reactivated the OVERLOAD message
|
|
* - rate-at.dat extended
|
|
* - fixes from Michael Reinelt
|
|
*
|
|
*
|
|
* Revision 0.1 1999/04/25 20:00.00 akool
|
|
* Initial revision
|
|
*
|
|
*/
|
|
|
|
|
|
#include "asn1.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, );
|
|
|
|
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 procedure, basicService;
|
|
char forwardedToAddress[BUF_SIZE], servedUserNr[BUF_SIZE];
|
|
auto char vsrc[BUFSIZ], vdst[BUFSIZ];
|
|
auto int a1, a2, a3, a4;
|
|
|
|
|
|
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;
|
|
}
|
|
|
|
ELEMENT_1(ParseARGDeactivationDiversion, char, s)
|
|
{
|
|
int procedure, basicService;
|
|
char servedUserNr[BUF_SIZE];
|
|
auto char vsrc[BUFSIZ];
|
|
auto int a1, a2, a3, a4;
|
|
|
|
|
|
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;
|
|
}
|
|
|
|
ELEMENT_1(ParseARGActivationStatusNotificationDiv, char, s)
|
|
{
|
|
int procedure, basicService;
|
|
char forwardedToAddress[BUF_SIZE], servedUserNr[BUF_SIZE];
|
|
|
|
CHECK_TAG(ASN1_TAG_SEQUENCE)
|
|
MY_DEBUG("ParseARGActivationStatusNotificationDiv");
|
|
|
|
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;
|
|
}
|
|
|
|
ELEMENT_1(ParseARGDeactivationStatusNotificationDiv, char, s)
|
|
{
|
|
int procedure, basicService;
|
|
char servedUserNr[BUF_SIZE];
|
|
|
|
CHECK_TAG(ASN1_TAG_SEQUENCE)
|
|
MY_DEBUG("ParseARGDeactivationStatusNotificationDiv");
|
|
|
|
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;
|
|
}
|
|
|
|
ELEMENT_1(ParseARGInterrogationDiversion, char, s)
|
|
{
|
|
int procedure, basicService;
|
|
char servedUserNr[BUF_SIZE];
|
|
|
|
|
|
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;
|
|
}
|
|
|
|
ELEMENT_1(ParseARGDiversionInformation, char, res)
|
|
{
|
|
int diversionReason, basicService, lastDivertingReason;
|
|
char servedUserSubaddress[25], callingAddress[255], originalCalledNr[255],
|
|
lastDivertingNr[255]; // , userInfo[255];
|
|
|
|
|
|
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;
|
|
}
|
|
|
|
ELEMENT_1(ParseRESInterrogationDiversion, char, res)
|
|
{
|
|
char s[BUF_SIZE];
|
|
|
|
MY_DEBUG("ParseRESInterrogationDiversion");
|
|
if (!ParseIntResultList(el, tag, s)) return 0;
|
|
sprintf(res, "InterrogationDiversion Result: %s", s);
|
|
|
|
return 1;
|
|
}
|
|
|
|
ELEMENT_1(ParseServedUserNumberList, char, res)
|
|
{
|
|
int i;
|
|
char num[BUF_SIZE];
|
|
|
|
CHECK_TAG(ASN1_TAG_SET);
|
|
MY_DEBUG("ParseServedUserNumberList");
|
|
|
|
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;
|
|
}
|
|
|
|
ELEMENT_1(ParseRESInterrogateServedUserNumbers, char, res)
|
|
{
|
|
char s[BUF_SIZE];
|
|
|
|
MY_DEBUG("ParseRESInterrogateServedUserNumbers");
|
|
if (!ParseServedUserNumberList(el, tag, s)) return 0;
|
|
sprintf(res, "InterrogateServedUserNumbers Result: %s", s);
|
|
|
|
return 1;
|
|
}
|
|
|
|
ELEMENT_1(ParseProcedure, int, procedure)
|
|
{
|
|
MY_DEBUG("ParseProcedure");
|
|
|
|
if (!ParseEnum(el, tag, procedure)) return 0;
|
|
|
|
if ((*procedure < 0) || (*procedure > NProcedure))
|
|
return 0;
|
|
|
|
print_msg(PRT_DEBUG_DECODE, " DEBUG> procedure = %s\n",
|
|
Procedure[*procedure]);
|
|
return 1;
|
|
}
|
|
|
|
ELEMENT_1(ParseDiversionReason, int, diversionReason)
|
|
{
|
|
MY_DEBUG("ParseDiversionReason");
|
|
|
|
if (!ParseEnum(el, tag, diversionReason)) return 0;
|
|
|
|
if ((*diversionReason < 0) || (*diversionReason > NDiversionReason))
|
|
return 0;
|
|
|
|
print_msg(PRT_DEBUG_DECODE, " DEBUG> diversionReason = %s\n",
|
|
DiversionReason[*diversionReason]);
|
|
return 1;
|
|
}
|
|
|
|
ELEMENT_1(ParseServedUserNr, char, num)
|
|
{
|
|
MY_DEBUG("ParseServedUserNr");
|
|
|
|
if (el.tag == 0x05) {
|
|
strcpy(num, "allNumbers");
|
|
} else {
|
|
if (!ParsePartyNumber(el, ASN1_NOT_TAGGED, num)) return 0;
|
|
}
|
|
|
|
print_msg(PRT_DEBUG_DECODE, " DEBUG> ServedUserNr = %s\n", num);
|
|
|
|
return 1;
|
|
}
|
|
|
|
ELEMENT_1(ParseIntResult, char, s)
|
|
{
|
|
int procedure, basicService;
|
|
char servedUserNr[BUF_SIZE], forwardedToAddress[BUF_SIZE];
|
|
|
|
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;
|
|
}
|
|
|
|
ELEMENT_1(ParseIntResultList, char, s)
|
|
{
|
|
int i;
|
|
char res[BUF_SIZE];
|
|
|
|
CHECK_TAG(ASN1_TAG_SET);
|
|
MY_DEBUG("ParseIntResultList");
|
|
|
|
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;
|
|
}
|