Tarifikační modul pro Calom

Úvod

Tarifikace probíhá při generování reportu po tom, co informace o hovoru projde autorizací a lokálními filtry.
Je zajišťována skripty (také označovaných jako tarify), jejichž formát zde bude popsán.

Hlavní skripty

To, jaký skript se pustí pro tarifikování hovoru se určí podle nastavení implicitního "hlavního" skriptu.
Nastavení tohoto skriptu se provede příkazem 'TARIF DEFAULT_MAIN jmeno_skriptu' buď v konfiguračním souboru nebo z příkazové řádky klienta.
Vymazat implicitní hlavní skript lze pomocí 'TARIF NO_DEFAULT_MAIN' (skript se nesmaže, pouze se u něj poznačí, že není hlavní).
Kromě implicitního hlavního skriptu se dá pro každou seanci zvlášť nastavit lokální "hlavní" skript příkazem 'TARIF LOCAL_MAIN jmeno_skriptu'. Pokud je nastaven, použije se při tarifikování místo implicitního.

Správa skriptů

Skripty je možné přidávat pomocí 'TARIF ADD', mazat pomocí 'TARIF DEL', zjišťovat o nich informace 'TARIF DUMP' nebo si nechat vypsat všechny natažené skripty přes 'TARIF LIST'.

Každý skript má tzv. reference count, což je počet objektů, které ho potřebují. Pokud tento čítač klesne na nulu a skript není uložen, smaže se. Za každou funkci daného skriptu, kterou používá nějaký jiný skript se mu o 1 zvýší reference count.
Když z určité cli seance natáhnu nový skript, dostane reference count 1. Když daná seance skončí, čítač se zase sníží. Když je skript "hlavní" (ať už lokálně nebo globálně), má reference count zvýšený o 1 (pokud je jak lokálně tak globálně, tak o 2). To zabraňuje tomu, aby byl smazán.
Pozor na to, že pokud natáhnu nějaký skript pomocí 'TARIF ADD' a skončím seanci, skript se smaže. To platí i pro seanci, ve které se načítá konfigurační soubor. Takže pokud chci skript zachovat, musím buď nahrát jiný skript, který bude využívat jeho funkcí, nebo ho označit jako hlavní.
Tímto vznikají jakésy stromy využívání skriptů, kde v kořeni jsou "hlavní" skripty (globální nebo lokální pro nějakou probíhající seanci) a na ně se napojují skripty, které jsou jimi využívány. Pokud potom smažu kořen, smaže se celý strom (v případě, že jsem skripty načítal ve stejné seanci, ve které toto provádím, smažou se až po jejím skončení).
Pokud ale nějaký skript uložím příkazem 'TARIF STORE', nesmaže se ani když jeho reference count dosáhne 0 (pod 0 klesnout nemůže).

Když chci provést upgrade skriptů, stačí smazat hlavní skript a potom nahrát nové verze skriptů a jednomu z nich přiřadit funkci "hlavního skriptu". Tento reference counting je udělán z důvodu, aby se nemohly mazat skripty, které jsou používány, a aby v systému nezůstávaly nepoužívané skripty.

Skript mohu smazat příkazem 'TARIF DEL'. Pokud měl reference count větší než 0, akce se neprovede. To se může stát, pokud je daný skript lokální (využívá ho aktuální seance, takže mu o 1 zvyšuje reference count), pokud je nastaven jako hlavní skript nebo pokud jeho funkcí využívá nějaký jiný skript. Reference county skriptů a další informace se mi zobrazídané příkazem 'TARIF LIST'.

Příkazy 'TARIF REPARSE', 'TARIF STRIP', 'TARIF STORE', 'TARIF DEL', 'TARIF SET_MAIN', 'TARIF NO_DEFAULT_MAIN', 'TARIF INFO', 'TARIF DUMP' a 'TARIF DUMP_CODE' jsou povolené pouze účtům s administrátorskými právy.

Standardní postup je načíst skripty v konfiguračním souboru serveru v takovém pořadí, aby skript, který načítám se odkazoval pouze na skripty už načtené a na závěr načtu hlavní skript a označím ho jako hlavní. Příklad konfiguračního souboru:

; Ruzne servisni funkce
TARIF ADD global tarifs/global.trf

; Telecom
TARIF ADD telecom tarifs/telecom_fcn.trf
TARIF ADD tabulky tarifs/telecom_standard.trf

; Aliatel
TARIF ADD aliatel tarifs/aliatel.trf

; Main
TARIF ADD main tarifs/main.trf

TARIF STORE main
TARIF SET_MAIN main

Seznam nových příkazů serveru (dají se použít z klienta z příkazové řádky nebo v konfiguračním souboru serveru):
TARIF ADD jméno_tarifu jméno_souboru Načte tarif ze souboru 'jméno_souboru' a pojmenuje ho 'jméno_tarifu'. Reference count bude mít 1 a po skončení seance se o 1 sníží. Takže ho ve stejné seanci musím označit jako hlavní, uložit ho pomocí 'TARIF STORE' nebo načíst jiný skript, který ho používá. V opačném případě se po ukončení seance smaže. Načítání konfiguračního souboru je bráno jako seance.
TARIF DEL jméno_tarifu Smaže skript 'jméno tarifu', pokud měl reference count 0. Pokud má reference count větší než 0, systém ho odmítne smazat.
Je-li skript lokální, má reference count větší než 0 a musí se nejdřív provést 'TARIF STORE'. Pokud jeho funkcí využívá jiný skript, také bude mít reference count větší než 0. V takovém případě se nejdříve musí smazat skripty, které ho používají.
Je-li nastaven jako lokální nebo globální hlavní skript (pomocí 'TARIF DEFAULT_MAIN' nebo 'TARIF LOCAL_MAIN'), také tím získá vyšší reference count. Potom se musí odstranit příznak globálního skriptu (pomocí 'TARIF NO_DEFAULT_MAIN' a 'TARIF NO_LOCAL_MAIN).
TARIF CREATE jméno_tarifu Vytvoří skript 'jméno tarifu', ale nepřiřadí mu žádný kód. Kód se musí doplnit pomocí příkazů 'TARIF DEFINE'. Dokud se neprovede 'TARIF PARSE' nebo 'TARIF REPARSE', skript nelze spouštět.
TARIF DEFINE jméno_tarifu "definice tarifu" Přidá řádku kódu do definice skriptu 'jméno_tarifu'.
TARIF PARSE jméno_tarifu Spustí překlad skriptu 'jméno_tarifu'. Lze použít pouze pokud ještě není přeložen. Smí ho použít každý uživatel (aby si uživatelé mohli definovat svoje vlastní tarify). Dokud se skript nepřeloží, nelze jej spouštět.
TARIF REPARSE jméno_tarifu Podobně jako 'TARIF PARSE', ale skript už může být přeložen. Využije se v případě, že se zdrojový kód skriptu změnil. Vyžaduje administrátorská práva (aby normální uživatelé nemohli měnit stávající tarify).
TARIF STRIP jméno_tarifu Odstraní ze skriptu zdrojový kód. Takový skript může být spouštěn, ale nemůže být znova přeložen (pokud se znova nedodefinuje zdrojový kód).
TARIF STORE jméno_tarifu Uloží skript 'jméno_tarifu' mezi globální skripty. Tyto skripty se nemažou při dosáhnutí reference countu 0. Lokální skripty (které nebyly uloženy) se po skončení sezení smažou (pokud není zvláštní důvod, proč je nesmazat - jako třeba že je používá nějaký globální skript). Tímto způsobem lze uchovat skripty "do zásoby" i když nejsou nastaveny jako hlavní ani je nepoužívají jiné skripty. Například pro uložení tarifikace podle alternativního operátora, o jehož zavedení se teprve rozhoduje.
TARIF DEFAULT_MAIN jméno_tarifu (nebo TARIF SET_MAIN jméno_tarifu) Nastaví 'jméno_tarifu' jako implicitní (globální) hlavní skript. Pokud v nějaké seanci není nastaven lokální hlavní skript, bude se tento skript spouštět pro tarifikaci hovorů.
TARIF NO_DEFAULT_MAIN U globálního hlavního skriptu odstraní příznak hlavního skriptu. Pak nebude globální hlavní skript specifikován a bude se tarifikovat pouze pomocí lokálního hlavního skriptu (bude-li specifikován).
TARIF LOCAL_MAIN jméno_tarifu Nastaví 'jméno_tarifu' jako lokální hlavní skript. Ten se bude pro danou seanci spouštět pro tarifikaci hovorů (i když je nastaven globální hlavní skript).
TARIF NO_LOCAL_MAIN U lokálního hlavního skriptu odstraní příznak hlavního skriptu. Pak se bude tarifikovat pouze pomocí globálního hlavního skriptu (bude-li uveden).
TARIF LIST Vypíše všechny načtené skripty s různými informacemi (o velikosti kódu, dat, o tom, zda jde o hlavní skripty, a o reference countu). Je to užitečné například pro určení, jaký skript je hlavní.
TARIF LIST_LOCAL Vypíše seznam lokálních skriptů. Lokální skripty se po skončení seance automaticky smažou pokud mají během seance reference count 1 nebo menší.
TARIF INFO jméno_tarifu Vypíše seznam deklarovaných funkcí skriptu 'jméno_tarifu' a také funkce importované z jiných skriptů.
TARIF DUMP jméno_tarifu Vypíše zdrojový kód skriptu 'jméno_tarifu'.
TARIF DUMP_CODE jméno_tarifu Vypíše byte-kód skriptu 'jméno_tarifu'. Pro uživatele asi nemá význam.

Syntaxe tarifikačních skriptů

Jazyk pro skripty je syntaxí podobný jazyku C. Zdrojový kód se skládá ze dvou částí: deklarační a příkazové.
V deklarační části jsou deklarace proměnných (jsou lokální pro daný skript) a funkcí (ty jsou globální, tj. přístupné z jiných skriptů).
V příkazové části jsou příkazy, které se budou spouštět při tarifikaci pokud je daný skript hlavní (pokud není, daná část nemá smysl).

Deklarace globálních proměnných vypadá takto (hranaté závorky udávají nepovinnou část):
TYP jméno1 [, jméno2 [, ...]] [= iniciální hodnota];

Typy

TYP může být:
int klasické 32-bitové znaménkové celé číslo
ulong odpovídá unsigned longu: 32 bitů, bez znaménka, celé číslo
byte 8 bitů bez znaménka, celé číslo
word 16 bitů bez znaménka, celé číslo
float odpovídá floatu v programovacích jazycích: 32 bitů, číslo s pohyblivou řádovou čárkou (desetinné).
Konstanta typu float se zapisuje s desetinou tečkou.
string řetězec znaků o délce maximálně 256 znaků.
Konstanta typu string se zapisuje mezi uvozovky (").
time označuje délku časového úseku, je uložen jako int (může být záporný), přesnost na sekundy. Konstanta typu time se zapisuje ve formátu 13:24 nebo včetně sekund 13:25:14.
timestamp označuje časový okamžik, přesnost na sekundy.
Konstanta typu timestamp se zapisuje v jednom z formátů:
  • t"2006/02/12 13:24:14"
  • t"2006/02/12 13:24"
  • t"2006/02/12"
  • t"12/02/2006 13:24:14"
  • t"12/02/2006 13:24"
  • t"12/02/2006"
Místo lomítka je možné použít pro oddělení data také pomlčku (-) nebo tečku (.). Pro uvedení roku je možné použít zápis s dvouciferným uvedením roku <rok/měsíc/den> nebo <den/měsíc/rok>. Pokud by došlo k možné dvojí interpretaci, interpretuje se údaj jako zápis začínající dnem.
money peníze - celé číslo udávající počet haléřů.
Konstanta typu money se zapisuje jako celé číslo bez desetinné tečky nebo čárky, které vyjadřuje množství v haléřích.

Mezi mnoha typy jsou prováděny implicitní konverze.

Pokud je v deklaraci proměnné uvedena iniciální hodnota, je daná proměnná na tuto hodnotu inicializována při každém spuštění reportu.

Předdefinované proměnné

Poznámka: obsahují aktuální informace o hovoru a mají stejný význam jako proměnné stejného jména v reportech nebo filtrech

Deklarace funkcí:

TYP jméno_funkce ([TYP [&] parametr1 [, TYP [&] parametr2 [,...]]])
{
    [lokální deklarace proměnných (stejné jako globální)]
    [seznam příkazů]
}

TYP je stejný jako u proměnné, ale navíc může být 'void', který označuje, že funkce nic nevrací.
Pokud je v lokální deklaraci uvedena iniciální hodnota, dosadí se do dané proměnné při každém volání funkce (než se začnou vykonávat příkazy). Parametry, u kterých je uvedeno '&' se předávají odkazem, tj. funkce může měnit hodnotu proměnné uvedené jako skutečný parametr (ten, který se píše do volání funkce).
Ve volání funkce musí být parametry předávané odkazem uvedeny také s '&'.

Předdefinované funkce

Poznámka: není problém na požádání přidat další. Zatím jsou tam ty, které byly potřeba při tarifikování
int split_timestamp(
        timestamp t,
        int &year, int &month, int &month_day,
        int &week_day, int &day_seconds
);
Rozdělí údaj o časovém okamžiku ('t') na jednotlivé části:
  • rok
  • měsíc (číslováno od 0)
  • den v měsíci (číslováno od 1)
  • den v týdnu (neděle je 0, pondělí 1, ...)
  • počet sekund od začátku dne.
int make_timestamp(
        timestamp &t,
        int year, int month, int month_day, int day_seconds
);
Spojí údaje o časovém okamžiku do jedné proměnné ('t'):
  • rok
  • měsíc (číslováno od 0)
  • den v měsíci (číslováno od 1)
  • počet sekund od začátku dne.
int day_intersect(
        time end0, time length0,
        time begin1, time end1
);
Spočítá počet sekund průsečíku dvou časových období: jedno končí end0 (počítáno od začátku dne) a má délku length0, druhé začíná begin1 a končí end1.
int strlen(string s);
Vrací délku řetězce s
int stridx(string s, string search, int start);
Vrací první výskyt řetězce search od pozice start v řetězci s. Není-li řetězec nalezen, vrací -1.
string substr(string s, int start, int length);
Vrací podřetězec s začínající start a s délkou length
int begins_with(string str, string pattern);
Vrací 1 pokud řetězec str začíná řetězcem pattern
int str2int(string s);
Konvertuje řetězec s na číslo
int parse_trunk(
        string trunk,
        int &t1, int &t2, int &t3
);
Rozdělí trunk na tři čísla (podle formátu trunku jsou v řetězci trunk uloženy dvojciderně nebo trojciferně)
void get_day_before_native(
        int year, int month, int day,
        int &year_out, int &month_out, int &day_out
);
Vrátí den před specifikovaným datem.
void get_day_after_native(
        int year, int month, int day,
        int &year_out, int &month_out, int &day_out
);
Vrátí den po specifikovaném datu.
int round(int value);
int round_50(int value);
int round_50_down(int value);
int round_50_up(int value);
Zaokrouhlování čísel na celá čísla, resp. padesátníky, padesátníky směrem dolů, padesátníky směrem nahoru.

Příkazy:

{ příkaz1; [příkaz2; [příkaz3; [...]]]}
Skupina příkazů. Chápe se jako jeden příkaz.
if (podmínka) příkaz
if (podmínka) příkaz1 else príkaz2
Pokud je splněna podmínka (tj. výraz 'podmínka' bude mít hodnotu nenulovou), provede se příkaz/příkaz1 (může být i víc příkazů uvedených mezi '{' a '}'). V opačném případě se provede příkaz2 (je-li uveden).
while (podmínka) příkaz
Dokud je splněna podmínka, provádí se příkaz
for (příkaz1; podmínka; příkaz3;) příkaz4
Na začátku se provede příkaz1, potom dokud platí podmínka, provádí se příkaz4 a příkaz3.
switch (výraz) {
        case a: příkazy_a; [break;]
        case b: příkazy_b; [break;]
        [...]
        [default: příkazy_default;]
}
Na základě hodnoty výrazu se provádění přesune na příkazy uvedené u hodnoty výrazu (např. je-li výraz roven 5, a 'b' je 5, začnou se provádět příkazy_b. Pokud hodnota výrazu není mezi a, b, ..., skočí se na větev default. Výraz musí být převeditelný na int.
break;
break n;
Skočí se na konec určité oblasti (pokud je uveden parametr n, skočí se na konec n-té oblasti nad aktuálně prováděnou. Oblastí pro break je for a while cykly a switch příkaz. break 3 ukončí třeba tři právě prováděné do sebe vnořené cykly.
return výraz;
Vrátí výraz jako výsledek z funkce.
print string [, string2 [, ...]];
println string [, string2 [, ...]];
Vypíše dané řetězce (pouze pokud je tarifikátor spouštěn samostatně, ne z reportu). println navíc za posledním z nich odřádkuje.
stop;
Zastaví provádění skriptu (bez chybového hlášení).
fail;
fail "Chybová hláška";
Zastaví provádění skriptu a ohlásí chybu (pokud je to spuštěno z reportu, ukončí se jeho zpracování).
funkce(parametr [, parametr]);
Volání funkce. 'parametr' může být buď výraz nebo může být tvaru '& proměnná' (v případě předávání parametru odkazem). Je striktně požadováno, aby souhlasily parametry předávané odkazem a hodnotou v deklaraci funkce i ve volání. U paramtrů předávaných odkazem navíc musí přesně sedět typ. Pokud funkce vrací hodnotu, může být použita i jako výraz.

Výrazy

Klasické výrazy v infixové notaci se závorkami.
Používají se operátory (seřazeno podle priorit, první řádek má nejvyšší):

'-' (unární), '++', '--', '(typ)', '(+typ)', '(-typ) (přetypování)
'*', '/', '%'
'+', '-'
'<', '>', '<=', '>='
'==', '!='
'&'
'|'
'&&'
'||'
'=' a všechny varianty jako '+=', '*=', ...
','

Poznámky:

Překlad

Překlad probíhá těsně po příkazu serveru 'TARIF ADD', 'TARIF PARSE' nebo 'TARIF REPARSE'. Výskyt chyby je hlášen serverem klientovi a detailní popis důvodu je zapsán do logu.

Standardní tarifikační skripty:

main.trf:

Hlavní skript; v něm se tarifikace rozskakuje podle trunku do tarifikačních funkcí jednotlivých operátorů. Tento soubor je potřeba upravit podle přiřazení trunků jednotlivým operátorům.

global.trf:

Zde jsou uloženy obecné servisní funkce, které je možné použít pro libovolného operátora.
int is_easter(int year, int month, int day)
Vrací 1, pokud jsou v daném dnu velikonoce
int is_holiday(int year, int month, int day)
Vrací 1, pokud je daný den svátkem
void get_day_before(
        int year, int month, int day,
        int &year1, int &month1, int &day1
)
Do proměnných year1, month1 a day1 uloží datum dne před dnem určeným year, month a day
money do_tarif_1pasmo(
        time mintime,
        money mincost,
        time timeslice,
        money slicecost,
        time &begin, time &length,
        int is_continuation
)
Spočítá cenu hovoru, který končí v čase 'begin' (počítá se od půlnoci) s délkou 'length'. Parametr is_continuation určuje, zda se počítá první část hovoru (potom je potřeba dbát na minimální zpoplatněnou částku, hodnota is_continuation je 0) nebo zda se jedná o pokračování hovoru jdoucího přes víc dnů, jehož první část byla spočítána. Parametr 'mintime' určuje minimální zpoplatněný čas, parametr 'mincost' určuje cenu za tento minimální čas, 'timeslice' je délka úseků, po kterých se navyšuje cena a konečně 'slicecost' je cena za jeden takovýto úsek. Celý hovor musí ležet v rámci jednoho dne. Parametry 'begin' a 'length' jsou předávány odkazem, uloží se do nich informace nutné pro tarifikování zbytku hovoru pro případ, kdy hovor přejde přes půlnoc. V parametru 'length' se vrátí rozdíl konce hovoru a okamžiku, kdy by se znova navýšila cena (pokud hovor končil přesně na násobku timeslice, bude length 0, jinak je záporná - určuje vlastně na kolik sekund by ještě volající měl "nárok"). V parametru 'begin' se vrátí začátek nepředplacené doby (vždy je větší nebo roven času 'begin' na vstupu). Pokud je třeba 'min_time' 1 minuta a 'timeslice' 30 sekund, hovor trval 1:05 a začal v 7:20:00, bude ma konci v 'begin' 7:21:30 (v tuto dobu by se do hovoru započítala další půlminuta) a 'length' bude -0:25 (protože mohl mluvit ještě 25 sekund bez navýšení ceny).
money do_tarif_2pasma(
        time T1, time T2,
        time mintime1, time mintime2,
        money mincost1, money mincost2,
        time timeslice1, time timeslice2,
        money slicecost1, money slicecost2,
        time &begin, time &length,
        int is_continuation
)
Rozdíl od do_tarif_1pasmo je v tom, že zde je den rozdělen na dvě časová pásma, která mají vlastní parametry mincost, mintime, timeslice a slicecost. Parametry končící 1 jsou pro první pásmo, parametry končící 2 jsou pro druhé pásmo. První pásmo má dvě části, od 0:00:00 do (T1 - 1 sekunda) včetně a od T2 do 23:59:59 včetně, druhé je od T1 do (T2 - 1 sekunda) včetně. Jinak význam ostatních parametrů je jako u do_tarif_1pasmo.
money do_tarif_3pasma(
        time T1, time T2, time T3, time T4,
        time mintime1, time mintime2, time mintime3,
        money mincost1, money mincost2, money mincost3,
        time timeslice1, time timeslice2, time timeslice3,
        money slicecost1, money slicecost2, money slicecost3,
        time &begin, time &length,
        int is_continuation
)
Rozdíl od do_tarif_1pasmo je v tom, že zde je den rozdělen na tři časová pásma, která mají vlastní parametry mincost, mintime, timeslice a slicecost. Parametry končící 1 jsou pro první pásmo, parametry končící 2 jsou pro druhé pásmo a parametry končící 3 pro třetí. První pásmo má dvě části, od 0:00:00 do (T1 - 1 sekunda) a od T4 do 23:59:59, druhé má také dvě části: od T1 do (T2 - 1 sekunda) a od T3 do (T4 - 1 sekunda), třetí je od T2 do (T3 - 1 sekunda) (vše včetně).
money do_tarif_internet2002(
        time T1, time T2,
        money low_cost1, money high_cost1,
        money low_cost2, money high_cost2,
        time &begin,
        time &length1, time &length2
)
Tarifikuje hovor podle internetového tarifu, kde se počítá v minutových intervalech, ale minuta v prvních 10 minutách od začátku hovoru má jinou cenu než minuta ve zbytku hovoru. 'low_cost1' je cena v prvním pásmu v prvních 10 minutách. 'low_cost2' je cena v prvním pásmu mimo prvních 10 minut. 'high_cost1' je cena ve druhém pásmu v prvních 10 minutách. 'high_cost2' je cena ve druhém pásmu mimo prvních 10 minut. Pásma se stanovují stejně jako u do_tarif_2pasma, význam ostatních parametrů je také stejný jako u ostatních funkcí.

telecom_fcn.trf:

Zde jsou funkce uzpůsobené konkrétně pro Telecom, používají ale funkce z global.trf.
money tarif_telecom_mistni02(
        money cost_low, money cost_high,
        timestamp end, time length
)
Tarifikuje místní hovor s cenou 'cost_low' za minutu v slabém pásmu, 'cost_high' za minutu v silném pásmu. 'end' je konec hovoru, length je délka hovoru.
money tarif_telecom_mezimesto02(
        money cost_night, money cost_low, money cost_high,
        timestamp end, time length
)
Tarifikuje meziměstský hovor s cenou 'cost_night' za minutu v nočním pásmu, 'cost_low' za minutu v slabém pásmu a 'cost_high' za minutu v silném pásmu. 'end' je konec hovoru, length je délka hovoru.
money tarif_telecom_mobil02(
        money cost,
        timestamp end, time length
)
Tarifikuje hovor na mobil, 'cost' je cena za minutu, ostatní parametry mají stejný význam jako u tarif_telecom_mistni02.
money tarif_telecom_mezinarodni02(
        money cost_low, money cost_high,
        timestamp end, time length
)
Tarifikuje mezinárodní hovor s cenou 'cost_low' za minutu v slabém pásmu, 'cost_high' za minutu v silném pásmu. 'end' je konec hovoru, length je délka hovoru. Od místního se liší tím, že je tarifikován po sekundách a minimální zpoplatněná délka je jedna minuta.
money tarif_telecom_2pasma_02(
        time min_time, time interval,
        money cost_low, money cost_high,
        timestamp end, time length
)
Tarifikuje speciální tarify Telecomu, které jsou rozděleny do dvou časových pásem a mají různě dlouhé minimální doby a intervaly, ale vždy se počítá se stejnou cenou vztaženou k jedné minutě. Slouží např. pro tarifikování různých barevných linek. 'min_time' je minimální zpoplatněná doba. 'interval' je interval, po kterých se tarikuje. 'cost_low' je cena za minutu ve slabém pásmu. 'cost_low' je cena za minutu v silném pásmu.
money tarif_telecom_1pasmo_02(
        time min_time, time interval, money cost_per_minute,
        timestamp end, time length
)
Tarifikuje speciální tarify Telecomu, které nejsou rozděleny do časových pásem a mají různě dlouhé minimální doby a intervaly, ale vždy se počítá se stejnou cenou vztaženou k jedné minutě. Slouží např. pro tarifikování různých barevných linek. 'min_time' je minimální zpoplatněná doba. 'interval' je interval, po kterých se tarikuje. 'cost_per_minute' je cena za minutu.
money tarif_telecom_internet2002(
        money cost1_low, money cost1_high,
        money cost2_low, money cost2_high,
        timestamp end, time length
)
Tarif Telecom Internet2002. 'cost1_low' je cena za minutu ve slabém pásmu v prvních 10 minutách, 'cost1_high' je cena za minutu v silném pásmu v prvních 10 minutách, 'cost2_low' je cena za minutu ve slabém pásmu ve zbytku hovoru. 'cost2_high' je cena za minutu ve slabém pásmu ve zbytku hovoru.

telecom_standard.trf:

Je zde hlavní tarifikovací funkce tarif_telecom(), která na základě BCATu určí, jaké tarifikovací funkce a s jakými cenami zavolá. Tento soubor je potřeba upravit podle konkrétní konfigurace BCATů a podle konkrétního cenového programu.