- isdnlog Version 3.07

- Michael Reinelt's patch as of 16Mar99 06:58:58
- fix a fix from yesterday with sondernummern
- ignore "" COLP/CLIP messages
- dont show a LCR-Hint, if same price
This commit is contained in:
akool 1999-03-16 17:37:08 +00:00
parent 1e62012337
commit fccf615718
11 changed files with 318 additions and 171 deletions

View File

@ -1,4 +1,4 @@
## $Id: Makefile.in,v 1.59 1999/03/15 21:27:30 akool Exp $ ## $Id: Makefile.in,v 1.60 1999/03/16 17:37:08 akool Exp $
## ##
## ISDN accounting for isdn4linux. ## ISDN accounting for isdn4linux.
## ##
@ -19,6 +19,13 @@
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
## ##
## $Log: Makefile.in,v $ ## $Log: Makefile.in,v $
## Revision 1.60 1999/03/16 17:37:08 akool
## - isdnlog Version 3.07
## - Michael Reinelt's patch as of 16Mar99 06:58:58
## - fix a fix from yesterday with sondernummern
## - ignore "" COLP/CLIP messages
## - dont show a LCR-Hint, if same price
##
## Revision 1.59 1999/03/15 21:27:30 akool ## Revision 1.59 1999/03/15 21:27:30 akool
## - isdnlog Version 3.06 ## - isdnlog Version 3.06
## - README: explain some terms about LCR, corrected "-c" Option of "isdnconf" ## - README: explain some terms about LCR, corrected "-c" Option of "isdnconf"
@ -464,7 +471,7 @@ SERVICEFILE = /etc/services
# DON'T EDIT BELOW THIS LINE # DON'T EDIT BELOW THIS LINE
###################################################################### ######################################################################
VERSION = 3.06 VERSION = 3.07
MANPAGES = isdnlog/callerid.conf.5 isdnlog/isdn.conf.5 isdnlog/isdnformat.5 isdnlog/isdnlog.5 isdnlog/isdnlog.8 isdnlog/isdnlog.users.5 isdnrep/isdnrep.1 isdnconf/isdnconf.1 MANPAGES = isdnlog/callerid.conf.5 isdnlog/isdn.conf.5 isdnlog/isdnformat.5 isdnlog/isdnlog.5 isdnlog/isdnlog.8 isdnlog/isdnlog.users.5 isdnrep/isdnrep.1 isdnconf/isdnconf.1

View File

@ -1,3 +1,5 @@
V:1.0-Austria [15-Mar-1999]
W:1 Montag W:1 Montag
W:2 Dienstag W:2 Dienstag
W:3 Mittwoch W:3 Mittwoch

View File

@ -1,3 +1,5 @@
V:1.0-Switzerland [15-Mar-1999]
W:1 Montag W:1 Montag
W:2 Dienstag W:2 Dienstag
W:3 Mittwoch W:3 Mittwoch

View File

@ -1,3 +1,5 @@
V:1.0-Germany [15-Mar-1999]
W:1 Montag W:1 Montag
W:2 Dienstag W:2 Dienstag
W:3 Mittwoch W:3 Mittwoch

View File

@ -1,3 +1,8 @@
V:0.9-Netherlands [15-Mar-1999]
# Fixme:
# these need to be translated
W:1 Mondag W:1 Mondag
W:2 Thuesdag W:2 Thuesdag
W:3 Wednesdag W:3 Wednesdag

View File

@ -1,4 +1,4 @@
/* $Id: processor.c,v 1.43 1999/03/15 21:27:58 akool Exp $ /* $Id: processor.c,v 1.44 1999/03/16 17:37:18 akool Exp $
* *
* ISDN accounting for isdn4linux. (log-module) * ISDN accounting for isdn4linux. (log-module)
* *
@ -19,6 +19,13 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *
* $Log: processor.c,v $ * $Log: processor.c,v $
* Revision 1.44 1999/03/16 17:37:18 akool
* - isdnlog Version 3.07
* - Michael Reinelt's patch as of 16Mar99 06:58:58
* - fix a fix from yesterday with sondernummern
* - ignore "" COLP/CLIP messages
* - dont show a LCR-Hint, if same price
*
* Revision 1.43 1999/03/15 21:27:58 akool * Revision 1.43 1999/03/15 21:27:58 akool
* - isdnlog Version 3.06 * - isdnlog Version 3.06
* - README: explain some terms about LCR, corrected "-c" Option of "isdnconf" * - README: explain some terms about LCR, corrected "-c" Option of "isdnconf"
@ -756,8 +763,10 @@ static void buildnumber(char *num, int oc3, int oc3a, char *result, int version,
if (*sondernummer == UNKNOWN) if (*sondernummer == UNKNOWN)
*sondernummer = is_sondernummer(num, *provider); *sondernummer = is_sondernummer(num, *provider);
if (*sondernummer == UNKNOWN) if (*sondernummer == UNKNOWN) {
*sondernummer = !memcmp(num, "019", 3); /* anything like 019xx is a Sondernummer! */ if (!memcmp(num, "019", 3)) /* anything like 019xx is a Sondernummer! */
*sondernummer = 1;
} /* if */
} /* if */ } /* if */
@ -2417,10 +2426,15 @@ static void decode(int chan, register char *p, int type, int version, int tei)
*pd = 0; *pd = 0;
if (!*s) {
info(chan, PRT_SHOWNUMBERS, STATE_RING, "COLP *INVALID* -- ignored!");
break;
} /* if */
if (dual && !*s) if (dual && !*s)
strcpy(s, call[chan].onum[CALLED]); strcpy(s, call[chan].onum[CALLED]);
else else
strcpy(call[chan].onum[CALLED], s); strcpy(call[chan].onum[CALLED], s);
/* bei "national" numbers evtl. fuehrende "0" davor */ /* bei "national" numbers evtl. fuehrende "0" davor */
if (((oc3 & 0x70) == 0x20) && (*s != '0')) { if (((oc3 & 0x70) == 0x20) && (*s != '0')) {
@ -2431,7 +2445,7 @@ static void decode(int chan, register char *p, int type, int version, int tei)
buildnumber(s, oc3, oc3a, call[chan].num[CALLED], version, &call[chan].provider, &call[chan].sondernummer[CALLED], &call[chan].intern[CALLED], 0, CALLED); buildnumber(s, oc3, oc3a, call[chan].num[CALLED], version, &call[chan].provider, &call[chan].sondernummer[CALLED], &call[chan].intern[CALLED], 0, CALLED);
if (!dual) if (!dual)
strcpy(call[chan].vnum[CALLED], vnum(chan, CALLED)); strcpy(call[chan].vnum[CALLED], vnum(chan, CALLED));
#ifdef Q931 #ifdef Q931
if (q931dmp && (*call[chan].vnum[CALLED] != '?') && *call[chan].vorwahl[CALLED] && oc3 && ((oc3 & 0x70) != 0x40)) { if (q931dmp && (*call[chan].vnum[CALLED] != '?') && *call[chan].vorwahl[CALLED] && oc3 && ((oc3 & 0x70) != 0x40)) {

View File

@ -1,4 +1,4 @@
/* $Id: takt_de.c,v 1.13 1999/03/15 21:28:04 akool Exp $ /* $Id: takt_de.c,v 1.14 1999/03/16 17:37:27 akool Exp $
* *
* ISDN accounting for isdn4linux. (log-module) * ISDN accounting for isdn4linux. (log-module)
* *
@ -19,6 +19,13 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *
* $Log: takt_de.c,v $ * $Log: takt_de.c,v $
* Revision 1.14 1999/03/16 17:37:27 akool
* - isdnlog Version 3.07
* - Michael Reinelt's patch as of 16Mar99 06:58:58
* - fix a fix from yesterday with sondernummern
* - ignore "" COLP/CLIP messages
* - dont show a LCR-Hint, if same price
*
* Revision 1.13 1999/03/15 21:28:04 akool * Revision 1.13 1999/03/15 21:28:04 akool
* - isdnlog Version 3.06 * - isdnlog Version 3.06
* - README: explain some terms about LCR, corrected "-c" Option of "isdnconf" * - README: explain some terms about LCR, corrected "-c" Option of "isdnconf"
@ -800,7 +807,7 @@ void price(int chan, char *hint, int viarep)
if (call[chan].tarifknown && !viarep) { if (call[chan].tarifknown && !viarep) {
cheapest = UNKNOWN; cheapest = UNKNOWN;
payx = 99999.9; payx = call[chan].pay;
for (p = 0; p < MAXPROVIDER; p++) { for (p = 0; p < MAXPROVIDER; p++) {
payy = tpreis(p, call[chan].zone, call[chan].tz, tm->tm_hour, duration); payy = tpreis(p, call[chan].zone, call[chan].tz, tm->tm_hour, duration);
@ -826,17 +833,17 @@ void price(int chan, char *hint, int viarep)
WAEHRUNG, WAEHRUNG,
double2str(call[chan].pay - payx, 6, 3, DEB)); double2str(call[chan].pay - payx, 6, 3, DEB));
if ((call[chan].provider != preselect) && (prepreis != -1.00)) if ((call[chan].provider != preselect) && (prepreis != -1.00) && (prepreis != call[chan].pay))
sprintf(sy, " saving vs. preselect (010%02d:%s) %s %s", sprintf(sy, " saving vs. preselect (010%02d:%s) %s %s",
preselect, t[preselect].Provider, preselect, t[preselect].Provider,
WAEHRUNG, WAEHRUNG,
double2str(prepreis - call[chan].pay, 6, 3, DEB)); double2str(prepreis - call[chan].pay, 6, 3, DEB));
if ((call[chan].hint != UNKNOWN) && (call[chan].hint != cheapest)) if ((call[chan].hint != UNKNOWN) && (call[chan].hint != cheapest))
sprintf(sz, " saving vs. hint (010%02d:%s) %s %s", sprintf(sz, " saving vs. hint (010%02d:%s) %s %s",
call[chan].hint, t[call[chan].hint].Provider, call[chan].hint, t[call[chan].hint].Provider,
WAEHRUNG, WAEHRUNG,
double2str(hintpreis - call[chan].pay, 6, 3, DEB)); double2str(hintpreis - call[chan].pay, 6, 3, DEB));
if (*sx || *sy || *sz) if (*sx || *sy || *sz)
sprintf(hint, "HINT: %s%s%s LCR:%s", sx, sy, sz, ((cheapest == call[chan].provider) ? "OK" : "FAILED")); sprintf(hint, "HINT: %s%s%s LCR:%s", sx, sy, sz, ((cheapest == call[chan].provider) ? "OK" : "FAILED"));

View File

@ -1,4 +1,4 @@
/* $Id: holiday.c,v 1.1 1999/03/14 12:16:23 akool Exp $ /* $Id: holiday.c,v 1.2 1999/03/16 17:38:03 akool Exp $
* *
* Feiertagsberechnung * Feiertagsberechnung
* *
@ -19,6 +19,13 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *
* $Log: holiday.c,v $ * $Log: holiday.c,v $
* Revision 1.2 1999/03/16 17:38:03 akool
* - isdnlog Version 3.07
* - Michael Reinelt's patch as of 16Mar99 06:58:58
* - fix a fix from yesterday with sondernummern
* - ignore "" COLP/CLIP messages
* - dont show a LCR-Hint, if same price
*
* Revision 1.1 1999/03/14 12:16:23 akool * Revision 1.1 1999/03/14 12:16:23 akool
* - isdnlog Version 3.04 * - isdnlog Version 3.04
* - general cleanup * - general cleanup
@ -63,7 +70,7 @@
#include <time.h> #include <time.h>
#include "holiday.h" #include "holiday.h"
#define LENGTH 80 /* max length of lines in data file */ #define LENGTH 120 /* max length of lines in data file */
typedef unsigned int julian; typedef unsigned int julian;
@ -113,7 +120,7 @@ static void julian2date(julian jd, int *yp, int *mp, int *dp)
{ {
julian j,c,y,m,d; julian j,c,y,m,d;
j=d*4-1; j=jd*4-1;
c=(j/146097)*100; c=(j/146097)*100;
d=(j%146097)/4; d=(j%146097)/4;
y=(4*d+3)/1461; y=(4*d+3)/1461;
@ -179,12 +186,14 @@ void exitHoliday(void)
Holiday=NULL; Holiday=NULL;
} }
int initHoliday(char *path) int initHoliday(char *path, char **msg)
{ {
FILE *stream; FILE *stream;
int i,m,d;
char *s, *date, *name; char *s, *date, *name;
char buffer[LENGTH]; char buffer[LENGTH];
int i,m,d; char version[LENGTH]="";
static char message[LENGTH];
exitHoliday(); exitHoliday();
@ -241,12 +250,19 @@ int initHoliday(char *path)
nHoliday++; nHoliday++;
break; break;
case 'V': /* V:xxx Version der Datenbank */
strcpy(version, s+2);
break;
default: default:
warning("Unknown tag '%c'", *s); warning("Unknown tag '%c'", *s);
} }
} }
fclose(stream); fclose(stream);
if (msg) snprintf (*msg=message, LENGTH, "Holiday Version %s loaded [%d entries from %s]",
version, nHoliday, path);
return nHoliday; return nHoliday;
} }
@ -255,12 +271,12 @@ int isHoliday(struct tm *tm, char **name)
int i; int i;
julian easter, day; julian easter, day;
day=date2julian(tm->tm_year,tm->tm_mon,tm->tm_mday); day=date2julian(tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday);
easter=getEaster(tm->tm_year); easter=getEaster(tm->tm_year+1900);
for (i=0; i<nHoliday; i++) { for (i=0; i<nHoliday; i++) {
if ((Holiday[i].month==-1 && Holiday[i].day==day-easter) || if ((Holiday[i].month==-1 && Holiday[i].day==day-easter) ||
(Holiday[i].month==tm->tm_mon && Holiday[i].day==tm->tm_mday)) { (Holiday[i].month==tm->tm_mon+1 && Holiday[i].day==tm->tm_mday)) {
if(name) if(name)
*name=Holiday[i].name; *name=Holiday[i].name;
return 1; return 1;
@ -276,29 +292,31 @@ int getDay(struct tm *tm, char **name)
if (isHoliday(tm, name)) if (isHoliday(tm, name))
return HOLIDAY; return HOLIDAY;
day=(date2julian(tm->tm_year,tm->tm_mon,tm->tm_mday)-6)%7+1; day=(date2julian(tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday)-6)%7+1;
if (name) if (name)
*name=Weekday[day-1]; *name=Weekday[day-1];
return day; return day;
} }
#ifdef STANDALONE #ifdef HOLITEST
void main (int argc, char *argv[]) void main (int argc, char *argv[])
{ {
int i, d; int i, d;
char *name; char *msg, *name;
struct tm tm; struct tm tm;
printf ("%d Feiertage\n", initHoliday("../holiday-de.dat"));
initHoliday("../holiday-at.dat", &msg);
printf ("%s\n", msg);
for (i=1; i < argc; i++) { for (i=1; i < argc; i++) {
tm.tm_mday=atoi(strsep(argv+i,".")); tm.tm_mday=atoi(strsep(argv+i,"."));
tm.tm_mon=atoi(strsep(argv+i,".")); tm.tm_mon=atoi(strsep(argv+i,"."))-1;
tm.tm_year=atoi(strsep(argv+i,".")); tm.tm_year=atoi(strsep(argv+i,"."))-1900;
d=getDay(&tm,&name); d=getDay(&tm,&name);
printf ("%d.%d.%d\t%d=%s\n", tm.tm_mday,tm.tm_mon, tm.tm_year,d,name); printf ("%02d.%02d.%04d\t%d=%s\n", tm.tm_mday,tm.tm_mon+1,tm.tm_year+1900,d,name);
} }
} }
#endif #endif

View File

@ -1,4 +1,4 @@
/* $Id: holiday.h,v 1.1 1999/03/14 12:16:41 akool Exp $ /* $Id: holiday.h,v 1.2 1999/03/16 17:38:07 akool Exp $
* *
* Feiertagsberechnung * Feiertagsberechnung
* *
@ -19,6 +19,13 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *
* $Log: holiday.h,v $ * $Log: holiday.h,v $
* Revision 1.2 1999/03/16 17:38:07 akool
* - isdnlog Version 3.07
* - Michael Reinelt's patch as of 16Mar99 06:58:58
* - fix a fix from yesterday with sondernummern
* - ignore "" COLP/CLIP messages
* - dont show a LCR-Hint, if same price
*
* Revision 1.1 1999/03/14 12:16:41 akool * Revision 1.1 1999/03/14 12:16:41 akool
* - isdnlog Version 3.04 * - isdnlog Version 3.04
* - general cleanup * - general cleanup
@ -45,7 +52,7 @@
#define SUNDAY 7 #define SUNDAY 7
#define HOLIDAY 8 #define HOLIDAY 8
int initHoliday(char *path); int initHoliday(char *path, char **msg);
void exitHoliday(void); void exitHoliday(void);
int isHoliday(struct tm *tm, char **name); int isHoliday(struct tm *tm, char **name);
int getDay(struct tm *tm, char **name); int getDay(struct tm *tm, char **name);

View File

@ -1,4 +1,4 @@
/* $Id: rate.c,v 1.1 1999/03/14 12:16:42 akool Exp $ /* $Id: rate.c,v 1.2 1999/03/16 17:38:09 akool Exp $
* *
* Tarifdatenbank * Tarifdatenbank
* *
@ -19,6 +19,13 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *
* $Log: rate.c,v $ * $Log: rate.c,v $
* Revision 1.2 1999/03/16 17:38:09 akool
* - isdnlog Version 3.07
* - Michael Reinelt's patch as of 16Mar99 06:58:58
* - fix a fix from yesterday with sondernummern
* - ignore "" COLP/CLIP messages
* - dont show a LCR-Hint, if same price
*
* Revision 1.1 1999/03/14 12:16:42 akool * Revision 1.1 1999/03/14 12:16:42 akool
* - isdnlog Version 3.04 * - isdnlog Version 3.04
* - general cleanup * - general cleanup
@ -39,33 +46,17 @@
* void exitRate(void) * void exitRate(void)
* deinitialisiert die Tarifdatenbank * deinitialisiert die Tarifdatenbank
* *
* void initRate(char *info) * void initRate(char *conf, char *dat, char **msg)
* initialisiert die Tarifdatenbank, liefert Versionsinfo in `info' * initialisiert die Tarifdatenbank
* zurueck
* *
* char *Providername(int prefix) * int getRate(RATE*Rate, char **msg)
* liefert den Providernamen fuer Kennzahl `prefix', oder NULL, falls * liefert die Tarifberechnung in *Rate, UNKNOWN im
* unbekannt * Fehlerfall, *msg enthält die Fehlerbeschreibung
* *
* char *Zonename(int prefix, int zone) * int getLeastCost (RATE *Rate)
* liefert den Zonennamen fuer Provider `prefix', oder NULL, falls * berechnet den billigsten Provider zu *Rate, Rückgabewert
* unbekannt * ist der Prefix des billigsten Providers oder UNKNOWN wenn
* * *Rate bereits den billigsaten Tarif enthält
* int taktlaenge(int chan, char *why)
* liefert fuer die aktuell laufende Verbindung in `chan'
* die Laenge eines Tariftaktes in Sekunden, sowie evtl. in `why'
* eine textuelle Begruendung
*
* void preparecint(int chan, char *msg, char *hint)
* fuellt die aktuell laufende Verbindung in `chan' mit allen
* fuer die weitere Taktberechnung noetigen Daten
* liefert evtl. in `msg' sowie `hint' textuelle Informationen
* fuer die LCR-Optimierung
*
* void price(int chan, char *hint)
* berechnet fuer die gerade beendete Verbindung in `chan' den
* Endpreis, stellt diesen in `chan', und liefert in `hint' evtl.
* textuelle Informationen fuer die LCR-Optimierung
* *
*/ */
@ -77,6 +68,8 @@
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include <time.h> #include <time.h>
#include <unistd.h>
#include "holiday.h"
#include "rate.h" #include "rate.h"
#define MAXPROVIDER 100 #define MAXPROVIDER 100
@ -97,13 +90,13 @@ typedef struct {
bitfield Hour; bitfield Hour;
int nUnit; int nUnit;
UNIT *Unit; UNIT *Unit;
} RATE; } HOUR;
typedef struct { typedef struct {
int used; int used;
char *Name; char *Name;
int nRate; int nHour;
RATE *Rate; HOUR *Hour;
} ZONE; } ZONE;
typedef struct { typedef struct {
@ -115,7 +108,6 @@ typedef struct {
} PROVIDER; } PROVIDER;
static PROVIDER Provider[MAXPROVIDER]; static PROVIDER Provider[MAXPROVIDER];
static int use[MAXPROVIDER];
static int line=0; static int line=0;
static void warning (char *fmt, ...) static void warning (char *fmt, ...)
@ -157,12 +149,12 @@ void exitRate(void)
for (j=0; j<Provider[i].nZone; i++) for (j=0; j<Provider[i].nZone; i++)
if (Provider[i].Zone[j].used) { if (Provider[i].Zone[j].used) {
Provider[i].Zone[j].used=0; Provider[i].Zone[j].used=0;
for (k=0; k<Provider[i].Zone[j].nRate; k++) { for (k=0; k<Provider[i].Zone[j].nHour; k++) {
if (Provider[i].Zone[j].Rate[k].Name) free (Provider[i].Zone[j].Rate[k].Name); if (Provider[i].Zone[j].Hour[k].Name) free (Provider[i].Zone[j].Hour[k].Name);
if (Provider[i].Zone[j].Rate[k].Unit) free (Provider[i].Zone[j].Rate[k].Unit); if (Provider[i].Zone[j].Hour[k].Unit) free (Provider[i].Zone[j].Hour[k].Unit);
} }
if (Provider[i].Zone[j].Name) free (Provider[i].Zone[j].Name); if (Provider[i].Zone[j].Name) free (Provider[i].Zone[j].Name);
if (Provider[i].Zone[j].Rate) free (Provider[i].Zone[j].Rate); if (Provider[i].Zone[j].Hour) free (Provider[i].Zone[j].Hour);
} }
if(Provider[i].Zone) free (Provider[i].Zone); if(Provider[i].Zone) free (Provider[i].Zone);
if (Provider[i].Name) free (Provider[i].Name); if (Provider[i].Name) free (Provider[i].Name);
@ -172,22 +164,24 @@ void exitRate(void)
} }
} }
int initRate(char *conf, char *dat, char *msg) int initRate(char *conf, char *dat, char **msg)
{ {
FILE *stream; FILE *stream;
char buffer[LENGTH]; char buffer[LENGTH];
char Version[LENGTH]=""; char Version[LENGTH]="";
static char message[LENGTH];
int use[MAXPROVIDER];
int nProvider=0; int nProvider=0;
int nZone=0; int nZone=0;
int nRate=0; int nHour=0;
int ignore=0; int ignore=0;
int prefix=UNKNOWN; int prefix=UNKNOWN;
int version=UNKNOWN; int version=UNKNOWN;
int zone1, zone2; int zone=UNKNOWN;
int day1, day2, hour1, hour2; int day1, day2, hour1, hour2;
bitfield day, hour; bitfield day, hour;
double price; double price, duration;
int duration, delay; int delay;
int i, t, u; int i, t, u;
char *s; char *s;
@ -244,7 +238,7 @@ int initRate(char *conf, char *dat, char *msg)
case 'P': /* P:nn[,v]=Bezeichnung */ case 'P': /* P:nn[,v]=Bezeichnung */
ignore = 0; ignore = 0;
version = UNKNOWN; version = UNKNOWN;
zone1 = zone2 = UNKNOWN; zone = UNKNOWN;
prefix = strtol(s+2, &s ,10); prefix = strtol(s+2, &s ,10);
if (*s == ',') { if (*s == ',') {
@ -272,7 +266,7 @@ int initRate(char *conf, char *dat, char *msg)
nProvider++; nProvider++;
break; break;
case 'G': /* P:tt.mm.jjjj Rate gueltig ab */ case 'G': /* P:tt.mm.jjjj Hour gueltig ab */
if (ignore) continue; if (ignore) continue;
break; break;
@ -295,29 +289,22 @@ int initRate(char *conf, char *dat, char *msg)
warning ("Unexpected tag '%c'", *s); warning ("Unexpected tag '%c'", *s);
break; break;
} }
zone1=strtol(s+2,&s,10); zone=strtol(s+2,&s,10);
if (*s=='-') zone2=strtol(s+1,&s,10);
else zone2=zone1;
if (*s=='=')s++; if (*s=='=')s++;
if (zone1>zone2) { if (zone>=Provider[prefix].nZone) {
i=zone2; zone2=zone1; zone1=i; Provider[prefix].Zone=realloc(Provider[prefix].Zone, (zone+1)*sizeof(ZONE));
Provider[prefix].nZone = zone+1;
} }
if (zone2>=Provider[prefix].nZone) { Provider[prefix].Zone[zone].used=1;
Provider[prefix].Zone=realloc(Provider[prefix].Zone, (zone2+1)*sizeof(ZONE)); Provider[prefix].Zone[zone].Name=strdup(strip(s));
Provider[prefix].nZone = zone2+1; Provider[prefix].Zone[zone].nHour=0;
} Provider[prefix].Zone[zone].Hour=NULL;
for (i=zone1; i<=zone2; i++) {
Provider[prefix].Zone[i].used=1;
Provider[prefix].Zone[i].Name=strdup(strip(s));
Provider[prefix].Zone[i].nRate=0;
Provider[prefix].Zone[i].Rate=NULL;
nZone++; nZone++;
}
break; break;
case 'T': /* T:d-d/h-h=p/s:t[=]Bezeichnung */ case 'T': /* T:d-d/h-h=p/s:t[=]Bezeichnung */
if (ignore) continue; if (ignore) continue;
if (zone1 == UNKNOWN) { if (zone == UNKNOWN) {
warning ("Unexpected tag '%c'", *s); warning ("Unexpected tag '%c'", *s);
break; break;
} }
@ -353,6 +340,7 @@ int initRate(char *conf, char *dat, char *msg)
} }
} }
hour=0;
while (1) { while (1) {
if (*s=='*') { /* jede Stunde */ if (*s=='*') { /* jede Stunde */
hour |= 0xffffff; /* alles 1er */ hour |= 0xffffff; /* alles 1er */
@ -382,43 +370,43 @@ int initRate(char *conf, char *dat, char *msg)
warning ("I'm sorry, I don't understand this line..."); warning ("I'm sorry, I don't understand this line...");
continue; continue;
} }
for (i=zone1; i<=zone2; i++) { t=Provider[prefix].Zone[zone].nHour++;
t=Provider[prefix].Zone[i].nRate++; Provider[prefix].Zone[zone].Hour = realloc(Provider[prefix].Zone[zone].Hour, (t+1)*sizeof(HOUR));
Provider[prefix].Zone[i].Rate = realloc(Provider[prefix].Zone[i].Rate, (t+1)*sizeof(RATE)); Provider[prefix].Zone[zone].Hour[t].Name=NULL;
Provider[prefix].Zone[i].Rate[t].Name=NULL; Provider[prefix].Zone[zone].Hour[t].Day=day;
Provider[prefix].Zone[i].Rate[t].Day=day; Provider[prefix].Zone[zone].Hour[t].Hour=hour;
Provider[prefix].Zone[i].Rate[t].Hour=hour; Provider[prefix].Zone[zone].Hour[t].nUnit=0;
Provider[prefix].Zone[i].Rate[t].nUnit=0; Provider[prefix].Zone[zone].Hour[t].Unit=NULL;
Provider[prefix].Zone[i].Rate[t].Unit=NULL;
}
while (1) { while (1) {
price=strtod(s,&s); price=strtod(s,&s);
duration=1; duration=1;
delay=0; delay=UNKNOWN;
if (*s=='/') if (*s=='/')
duration=strtol(s+1,&s,10); duration=strtod(s+1,&s);
if (*s==':') if (*s==':')
delay=strtol(s+1,&s,10); delay=strtol(s+1,&s,10);
if (*s==',' && delay==UNKNOWN)
for (i=zone1; i<=zone2; i++) { delay=duration;
t=Provider[prefix].Zone[i].nRate-1; if (*s!=',' && delay!=UNKNOWN){
u=Provider[prefix].Zone[i].Rate[t].nUnit++; warning("last rate must not have a delay, will be ignored!");
Provider[prefix].Zone[i].Rate[t].Unit=realloc(Provider[prefix].Zone[i].Rate[t].Unit, (u+1)*sizeof(UNIT)); delay=UNKNOWN;
Provider[prefix].Zone[i].Rate[t].Unit[u].Duration=duration;
Provider[prefix].Zone[i].Rate[t].Unit[u].Delay=delay;
Provider[prefix].Zone[i].Rate[t].Unit[u].Price=price;
nRate++;
} }
t=Provider[prefix].Zone[zone].nHour-1;
u=Provider[prefix].Zone[zone].Hour[t].nUnit++;
Provider[prefix].Zone[zone].Hour[t].Unit=realloc(Provider[prefix].Zone[zone].Hour[t].Unit, (u+1)*sizeof(UNIT));
Provider[prefix].Zone[zone].Hour[t].Unit[u].Duration=duration;
Provider[prefix].Zone[zone].Hour[t].Unit[u].Delay=delay;
Provider[prefix].Zone[zone].Hour[t].Unit[u].Price=price;
nHour++;
if (*s!=',') break; if (*s!=',') break;
s++;
} }
if (*s=='=') s++; if (*s=='=') s++;
for (i=zone1; i<=zone2; i++) { t=Provider[prefix].Zone[zone].nHour-1;
t=Provider[prefix].Zone[i].nRate-1; Provider[prefix].Zone[zone].Hour[t].Name=strdup(strip(s));
Provider[prefix].Zone[i].Rate[t].Name=strdup(strip(s));
}
break; break;
case 'V': /* V:xxx Version der Ratedatenbank */ case 'V': /* V:xxx Version der Datenbank */
strcpy(Version, s+2); strcpy(Version, s+2);
break; break;
@ -428,81 +416,152 @@ int initRate(char *conf, char *dat, char *msg)
} }
} }
fclose(stream); fclose(stream);
sprintf (msg, "Rate Version %s loaded [%d Providers, %d Zones, %d Rates]",
Version, nProvider, nZone, nRate); if (msg) snprintf (*msg=message, LENGTH, "Rate Version %s loaded [%d Providers, %d Zones, %d Rates from %s]",
Version, nProvider, nZone, nHour, dat);
return 0; return 0;
} }
char *Providername(int prefix) int getRate(RATE *Rate, char **msg)
{
if (!Provider[prefix].used) return(NULL);
return(Provider[prefix].Name);
}
char *Zonename(int prefix, int zone)
{
if (!Provider[prefix].used) return(NULL);
if (zone<1 || zone>=Provider[prefix].nZone) return (NULL);
if (!Provider[prefix].Zone[zone].used) return (NULL);
return(Provider[prefix].Zone[zone].Name);
}
static double tpreis(int prefix, int zone, int day, int hour, int duration)
{ {
static char message[LENGTH];
bitfield dayMask, hourMask; bitfield dayMask, hourMask;
RATE *Rate; ZONE *Zone;
HOUR *Hour;
UNIT *Unit; UNIT *Unit;
double price; int prefix, zone, day, hour, i;
int delay, i; time_t now, run, end;
struct tm tm;
if (!Provider[prefix].used) return UNKNOWN; if (!Rate)
if (!Provider[prefix].Zone[zone].used) return UNKNOWN ; return UNKNOWN;
dayMask=1<<(day-1); prefix=Rate->prefix;
hourMask=1<<hour; if (prefix<0 || prefix>MAXPROVIDER || !Provider[prefix].used) {
if (msg) snprintf(*msg=message, LENGTH, "unknown provider '%d'", prefix);
for (i=0; i<Provider[prefix].Zone[zone].nRate; i++) { return UNKNOWN;
Rate = Provider[prefix].Zone[zone].Rate+i;
if ((Rate->Day & dayMask) && (Rate->Hour & hourMask))
break;
} }
if (i==Provider[prefix].Zone[zone].nRate) return UNKNOWN;
zone=Rate->zone;
i = 1; if (zone<1 || zone>=Provider[prefix].nZone || !Provider[prefix].Zone[zone].used) {
price = 0.0; if (msg) snprintf(*msg=message, LENGTH, "unknown zone '%d'", zone);
delay = 0; return UNKNOWN;
Unit = Rate->Unit; }
while (duration>0) {
duration -= Unit->Duration; Zone=&Provider[prefix].Zone[zone];
delay += Unit->Duration; Rate->Provider=Provider[prefix].Name;
price += Unit->Price; Rate->Zone=Zone->Name;
if ((delay >= Unit->Delay) && (i < Rate->nUnit)) Rate->Units=0;
Rate->Duration=0;
Rate->Price=0;
Rate->Charge=0;
Rate->Rest=0;
Hour=NULL;
Unit=NULL;
hour=UNKNOWN; /* Stundenwechsel erzwingen */
now=mktime(&Rate->start);
end=mktime(&Rate->now);
Rate->Time=end-now;
run=0;
while (end>=now) {
tm=*localtime(&now);
if (hour!=tm.tm_hour) { /* Neuberechnung bei Stundenwechsel */
hour=tm.tm_hour;
day=getDay(&tm, &Rate->Day);
dayMask=1<<(day-1);
hourMask=1<<tm.tm_hour;
for (i=0; i<Zone->nHour; i++) {
Hour = &Zone->Hour[i];
if ((Hour->Day & dayMask) && (Hour->Hour & hourMask))
break;
}
if (i==Zone->nHour) {
if (msg) snprintf(*msg=message, LENGTH,
"no rate found for provider=%d zone=%d day=%d hour=%d",
prefix, zone, day, tm.tm_hour);
return UNKNOWN;
}
Rate->Hour=Hour->Name;
Unit=Hour->Unit;
}
Rate->Duration=Unit->Duration;
Rate->Price=Unit->Price;
Rate->Charge+=Unit->Price;
Rate->Rest+=Unit->Duration;
now+=Unit->Duration;
run+=Unit->Duration;
if (Unit->Duration>0)
Rate->Units++;
if (Unit->Delay!=UNKNOWN && Unit->Delay<=run)
Unit++; Unit++;
} }
Rate->Rest-=Rate->Time;
return 0;
}
return price; int getLeastCost (RATE *Rate)
{
int i, cheaper;
RATE LC;
LC=*Rate;
cheaper=UNKNOWN;
for (i=0; i<MAXPROVIDER; i++) {
Rate->prefix=i;
if (getRate(Rate, NULL)!=UNKNOWN && Rate->Charge<LC.Charge) {
cheaper=i;
LC=*Rate;
}
}
*Rate=LC;
return cheaper;
} }
#ifdef STANDALONE #ifdef STANDALONE
void main (int argc, char *argv[]) void main (int argc, char *argv[])
{ {
char msg[BUFSIZ]; char *msg;
int provider, zone, day, hour, duration; time_t now;
RATE Rate, LCR;
int i;
initHoliday ("../holiday-at.dat", &msg);
printf ("%s\n", msg);
initRate ("../rate-at.conf", "../rate-at.dat", msg); initRate ("../rate-at.conf", "../rate-at.dat", &msg);
printf ("%s\n", msg); printf ("%s\n", msg);
provider = 0; Rate.prefix = 1;
zone = 1; Rate.zone = 1;
printf ("Providername(%d) = %s\n", provider, Providername(provider)); time(&now);
printf ("Zonename(%d,%d) = %s\n", provider, zone, Zonename(provider, zone)); Rate.start = *localtime(&now);
day=1; while (1) {
hour=12;
duration=300; time(&now);
Rate.now = *localtime(&now);
if (getRate(&Rate, &msg)==UNKNOWN)
printf ("Oops: %s\n", msg);
else
printf ("%02d.%02d.%04d %02d:%02d:%02d %-5s %-12s %-12s %-12s %6.2f %7.3f %3d %6.2f %3ld %3ld\n",
Rate.now.tm_mday, Rate.now.tm_mon+1, Rate.now.tm_year+1900,
Rate.now.tm_hour, Rate.now.tm_min, Rate.now.tm_sec,
Rate.Provider, Rate.Zone, Rate.Day, Rate.Hour,
Rate.Duration, Rate.Price, Rate.Units, Rate.Charge, Rate.Time, Rate.Rest);
LCR=Rate;
if (getLeastCost(&LCR)!=UNKNOWN) {
printf ("least cost would be: %-5s %-12s %-12s %-12s %6.2f %7.3f %3d %6.2f %3ld %3ld\n",
LCR.Provider, LCR.Zone, LCR.Day, LCR.Hour,
LCR.Duration, LCR.Price, LCR.Units, LCR.Charge, LCR.Time, LCR.Rest);
}
printf ("tpreis(%d,%d,%d,%d,%d)=%f\n", provider, zone, day, hour, duration, tpreis(provider, zone, day, hour, duration)); sleep(1);
}
} }
#endif #endif

View File

@ -1,4 +1,4 @@
/* $Id: rate.h,v 1.1 1999/03/14 12:16:43 akool Exp $ /* $Id: rate.h,v 1.2 1999/03/16 17:38:10 akool Exp $
* *
* Tarifdatenbank * Tarifdatenbank
* *
@ -19,6 +19,13 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *
* $Log: rate.h,v $ * $Log: rate.h,v $
* Revision 1.2 1999/03/16 17:38:10 akool
* - isdnlog Version 3.07
* - Michael Reinelt's patch as of 16Mar99 06:58:58
* - fix a fix from yesterday with sondernummern
* - ignore "" COLP/CLIP messages
* - dont show a LCR-Hint, if same price
*
* Revision 1.1 1999/03/14 12:16:43 akool * Revision 1.1 1999/03/14 12:16:43 akool
* - isdnlog Version 3.04 * - isdnlog Version 3.04
* - general cleanup * - general cleanup
@ -36,9 +43,26 @@
#ifndef _RATE_H_ #ifndef _RATE_H_
#define _RATE_H_ #define _RATE_H_
typedef struct {
int prefix;
int zone;
struct tm start;
struct tm now;
char *Provider; /* Name des Providers */
char *Zone; /* Name der Zone */
char *Day; /* Wochen- oder Feiertag */
char *Hour; /* Bezeichnung des Tarifs */
double Duration; /* Länge eines Tarifimpulses */
double Price; /* Preis eines Tarifimpulses */
int Units; /* verbrauchte Tarifimpulse */
double Charge; /* gesamte Verbindungskosten */
time_t Time; /* gesamte Verbindungszeit */
time_t Rest; /* bezahlte, aber noch nicht verbrauchte Zeit */
} RATE;
void exitRate(void); void exitRate(void);
int initRate(char *conf, char *dat, char *msg); int initRate(char *conf, char *dat, char **msg);
char *Providername(int prefix); int getRate(RATE *Rate, char **msg);
char *Zonename(int prefix, int zone); int getLeastCost(RATE *Rate);
#endif #endif