335 lines
9.8 KiB
C
335 lines
9.8 KiB
C
/* $Id: asn1_diversion.c,v 1.5 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.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)
|
|
*
|
|
* 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"
|
|
#include "asn1_generic.h"
|
|
#include "asn1_address.h"
|
|
#include "asn1_basic_service.h"
|
|
#include "asn1_diversion.h"
|
|
|
|
// ======================================================================
|
|
// Diversion Supplementary Services ETS 300 207-1 Table 3
|
|
|
|
int
|
|
ParseARGActivationDiversion(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
|
|
{
|
|
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);
|
|
|
|
print_msg(PRT_SHOWNUMBERS, "Activation Diversion %s (%s), %s -> %s\n",
|
|
procedure, basicService, servedUserNr, address);
|
|
return p - beg;
|
|
}
|
|
|
|
int
|
|
ParseARGDeactivationDiversion(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
|
|
{
|
|
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);
|
|
|
|
print_msg(PRT_SHOWNUMBERS, "Deactivation Diversion %s (%s), %s\n",
|
|
procedure, basicService, servedUserNr);
|
|
return p - beg;
|
|
}
|
|
|
|
int
|
|
ParseARGActivationStatusNotificationDiv(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
|
|
{
|
|
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);
|
|
|
|
print_msg(PRT_SHOWNUMBERS, "Notification: Activated Diversion %s (%s), %s -> %s\n",
|
|
procedure, basicService, servedUserNr, address);
|
|
return p - beg;
|
|
}
|
|
|
|
int
|
|
ParseARGDeactivationStatusNotificationDiv(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
|
|
{
|
|
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);
|
|
|
|
print_msg(PRT_SHOWNUMBERS, "Notification: Deactivated Diversion %s (%s), %s\n",
|
|
procedure, basicService, servedUserNr);
|
|
return p - beg;
|
|
}
|
|
|
|
int
|
|
ParseARGInterrogationDiversion(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
|
|
{
|
|
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);
|
|
|
|
print_msg(PRT_SHOWNUMBERS, "Interrogation Diversion %s (%s), %s\n",
|
|
procedure, basicService, servedUserNr);
|
|
return p - beg;
|
|
}
|
|
|
|
int
|
|
ParseRESInterrogationDiversion(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
|
|
{
|
|
print_msg(PRT_SHOWNUMBERS, "Interrogation Diversion Result\n");
|
|
|
|
return ParseIntResultList(chanp, p, end, dummy);
|
|
}
|
|
|
|
int
|
|
ParseARGInterrogateServedUserNumbers(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
|
|
{
|
|
print_msg(PRT_SHOWNUMBERS, "Interrogate Served User Numbers\n");
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
ParseRESInterrogateServedUserNumbers(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
|
|
{
|
|
int ret;
|
|
char servedUserNumberList[200] = "";
|
|
|
|
ret = ParseServedUserNumberList(chanp, p, end, servedUserNumberList);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
print_msg(PRT_SHOWNUMBERS, "Interrogate Served User Numbers: %s\n",
|
|
servedUserNumberList);
|
|
|
|
return ret;
|
|
}
|
|
|
|
int
|
|
ParseARGDiversionInformation(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
|
|
{
|
|
char diversionReason[20];
|
|
char basicService[30];
|
|
char servedUserSubaddress[30] = "";
|
|
char callingAddress[80] = "-";
|
|
char originalCalledNr[80] = "-";
|
|
char lastDivertingNr[80] = "-";
|
|
char lastDivertingReason[20] = "-";
|
|
INIT;
|
|
|
|
XSEQUENCE_1(ParseDiversionReason, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, diversionReason);
|
|
XSEQUENCE_1(ParseBasicService, ASN1_TAG_ENUM, ASN1_NOT_TAGGED, basicService);
|
|
XSEQUENCE_OPT_1(ParsePartySubaddress, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED, servedUserSubaddress);
|
|
XSEQUENCE_OPT_1(ParsePresentedAddressScreened, ASN1_NOT_TAGGED, 0 | ASN1_TAG_EXPLICIT, callingAddress);
|
|
XSEQUENCE_OPT_1(ParsePresentedNumberUnscreened, ASN1_NOT_TAGGED, 1 | ASN1_TAG_EXPLICIT, originalCalledNr);
|
|
XSEQUENCE_OPT_1(ParsePresentedNumberUnscreened, ASN1_NOT_TAGGED, 2 | ASN1_TAG_EXPLICIT, lastDivertingNr);
|
|
XSEQUENCE_OPT_1(ParseDiversionReason, ASN1_TAG_ENUM, 3 | ASN1_TAG_EXPLICIT, lastDivertingReason);
|
|
// XSEQUENCE_OPT_1(ParseQ931InformationElement, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, userInfo);
|
|
|
|
print_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;
|
|
}
|
|
|
|
int
|
|
ParseIntResultList(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
|
|
{
|
|
int i;
|
|
INIT;
|
|
|
|
for (i = 0; i < 29; i++) {
|
|
XSEQUENCE_OPT(ParseIntResult, ASN1_TAG_SEQUENCE, ASN1_NOT_TAGGED);
|
|
}
|
|
|
|
return p - beg;
|
|
}
|
|
|
|
int
|
|
ParseIntResult(struct Aoc *chanp, u_char *p, u_char *end, int dummy)
|
|
{
|
|
char procedure[10];
|
|
char basicService[30];
|
|
char servedUserNr[30];
|
|
char address[60];
|
|
INIT;
|
|
|
|
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);
|
|
|
|
print_msg(PRT_SHOWNUMBERS, " %s (%s), %s -> %s\n",
|
|
procedure, basicService, servedUserNr, address);
|
|
return p - beg;
|
|
}
|
|
|
|
int
|
|
ParseServedUserNrAll(struct Aoc *chanp, u_char *p, u_char *end, char *servedUserNr)
|
|
{
|
|
int ret;
|
|
|
|
ret = ParseNull(chanp, p, end, 0);
|
|
if (ret < 0)
|
|
return ret;
|
|
sprintf(servedUserNr, "(all)");
|
|
|
|
return ret;
|
|
}
|
|
|
|
int
|
|
ParseServedUserNr(struct Aoc *chanp, u_char *p, u_char *end, char *servedUserNr)
|
|
{
|
|
INIT;
|
|
*servedUserNr = 0;
|
|
|
|
XCHOICE_1(ParseServedUserNrAll, ASN1_TAG_NULL, ASN1_NOT_TAGGED, servedUserNr);
|
|
XCHOICE_1(ParsePartyNumber, ASN1_NOT_TAGGED, ASN1_NOT_TAGGED, servedUserNr);
|
|
XCHOICE_DEFAULT;
|
|
}
|
|
|
|
int
|
|
ParseProcedure(struct Aoc *chanp, u_char *p, u_char *end, char *str)
|
|
{
|
|
int ret;
|
|
int procedure;
|
|
|
|
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;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|