Application LCDial() - Least Cost Dial
Synopsis
Does a mysql Database lookup to find the cheapest Provider for a given destination number, and than it invokes the dial command. If the channel is unavailable then it will fall back to the next configured Provider.Description
- LCDial(number to dial,timeout,options,URL) — dial one channel
Parameters:
- number to dial specifes the number which should get dial.
- all other options are the same as within the standard Asterisk cmd dial command (the are directly passed to the dial comand)
Return codes
Behaves exactly like Asterisk cmd dialExample:
exten => 4000,1,LCDial(${EXTEN},15)
mysql Database Layout
| table | description |
| provider | Informations about each Provider (name,id,dialstr,status) |
| providerdestination | Which destinations (countryprefixid) are available with which provider |
| providerrate | The tariffrate for the given provider / destination |
| countryprefix | Table with dial codes |
| country | optional - not really needed - but if you want to have nice names for the countries |
CREATE TABLE `countryprefix` (
`countryprefixid` int(11) NOT NULL auto_increment,
`prefix` text NOT NULL,
`countrycode` char(3) default NULL,
`subcode` varchar(10) NOT NULL default '',
PRIMARY KEY (`countryprefixid`)
) TYPE=MyISAM;
CREATE TABLE `provider` (
`providerid` int(11) NOT NULL auto_increment,
`providername` text NOT NULL,
`dialstr` varchar(200) NOT NULL default '',
`status` tinyint(3) unsigned NOT NULL default '0',
PRIMARY KEY (`providerid`)
) TYPE=MyISAM;
CREATE TABLE `providerdestination` (
`providerdestinationid` int(11) NOT NULL auto_increment,
`countryprefixid` int(11) NOT NULL default '0',
`providerid` int(11) NOT NULL default '0',
PRIMARY KEY (`providerdestinationid`)
) TYPE=MyISAM;
CREATE TABLE `providerrate` (
`providerrateid` int(11) NOT NULL auto_increment,
`providerid` int(11) NOT NULL default '0',
`countryprefixid` int(11) NOT NULL default '0',
`rate` double NOT NULL default '0',
PRIMARY KEY (`providerrateid`)
) TYPE=MyISAM;
CREATE TABLE `country` (
`countrycode` char(3) default NULL,
`countryname` text NOT NULL,
`countryid` int(11) default NULL
) TYPE=MyISAM;
Configuration
LCDial needs a configuration file called lcdial.conf in the standard asterisk configuration directory.Example Configuration:
global
hostname=localhost
dbname=asterisk
user=asterisk
password=asterisk
port=3306
sql
getproviders=SELECT providerrate.rate, dialstr, countryprefix.countryprefixid, provider.providerid, provider.providername FROM countryprefix LEFT JOIN providerdestination USING ( countryprefixid ) LEFT JOIN provider USING ( providerid ) LEFT JOIN providerrate ON concat( provider.providerid, countryprefix.countryprefixid ) = concat( providerrate.providerid, providerrate.countryprefixid ) WHERE prefix = substring( '%s', 1, length( prefix ) ) AND provider.status=0 ORDER BY length( prefix ) DESC , providerrate.rate ASC
Get it
Here <- Here you will find the new version which is now based on MysqlPool - please take a look at the documentation.Compile It
It assumes that the asterisk sources can be found at /usr/src/asterisk, that the asterisk modules directory is at /usr/lib/asterisk/modules and that the asterisk configuration is at /etc/asterisk/.For compiling it you need to have already installed asterisk ;-) - and the mysql client libary and header files.
From asterisk stable to asterisk cvs head the channel structure has changed a little bit - so if you want to compile against asterisk stable then you have to comment this "CFLAGS+=-DUSE_CVS" line to get it to compile (else you would get an error like "error: structure has no member named `cid'"
Help
If you are having trouble getting the application up and running and need professional help, feel free to drop us a line at support@yosd.atManagement Interface
If you are looking for a management frontend or a turn-key-solution please get in touch with us: support@yosd.atA modified version of LCDial() which uses REGEXP prefix and only 2 simple tables
LCDial is very powerful and versatile solution for least cost routing, because it get information about routing from database using only one SQL statement which is defined in lcdial.conf configuration file.I've modified the original SQL query to use only two tables:
- lcdial_providers, within the provider name, dial string, and a flag to enable/disable it
- lcdial_rates, within the regexp prefix, provider name, rate, and a comment
| id | provider | dialstr | enabled |
|---|---|---|---|
| 1 | fastweb | Zap/g1/%s|40 | 1 |
| 2 | freevoip | IAX2/freevoip/%s|20 | 0 |
| 3 | wind-leonardo | SIP/%s@100|40 | 1 |
| 4 | voipvoice | IAX2/voipvoicenumber/%s|40 | 1 |
| prefix | provider | rate | note |
|---|---|---|---|
| ^005521 | freevoip | 0.03 | brazil rio de janeiro |
| ^32....... | wind-leonardo | 0 | wind cellulars |
| ^3[3469]....... | wind-leonardo | 0.06 | italian cellulars (not wind) |
When LCDial(number,options) is called, the LCDial application perform a regular expression search into lcdial_rates, and order all records by expression length, taking only one record per provider, then sort by cost.
In this way I can, for example, add records like
^00393[234689] to match italian cellular phones
^0039 to match all italian phones but not italian cellulars, because they will match the previous rule
You'll find this customized version of LCDial() into www.creasol.it/unix/lcdial-psubiaco.tgz within an example of database (file doc/sample2.sql).
If you add rates information to the provided database, please send the modification to psubiaco@creasol.it so they will be added to the lcdial-psubiaco.tgz archive.
See also
Asterisk | Asterisk cmd dial
Page Changes
very wrong code
then #2..
un 9 22:11:40 DEBUG58317 config.c: Parsing /usr/local/etc/asterisk/lcdial.conf
Jun 9 22:11:40 DEBUG58317 app_lcdial.c: LCDial: got hostname of localhost
Jun 9 22:11:40 DEBUG58317 app_lcdial.c: LCDial: got port of 3306
Jun 9 22:11:40 DEBUG58317 app_lcdial.c: LCDial: got user of bob
Jun 9 22:11:40 DEBUG58317 app_lcdial.c: LCDial: got dbname of cdr
Jun 9 22:11:40 DEBUG58317 app_lcdial.c: LCDial: got password of SOMETHINGSECRETIWOTPOSTHERE
Jun 9 22:11:40 DEBUG58317 app_lcdial.c: LCDial: got getproviders query of 'somecustomized SQL string'
Jun 9 22:11:40 WARNING58317 app_lcdial.c: LCDIAL using database 'cdr'.
Jun 9 22:11:40 DEBUG58317 app_lcdial.c: LCDial: Successfully connected to database 'cdr@localhost'.
right ?
WRONG.. LCD still tryed asterisk DB..
check this log.
Jun 9 22:16:24 DEBUG58317 app_lcdial.c: LCDial: FATAL DB ERROR AT QUERY: SELECT THISISJUSTTHESQLSTRING -
(Table 'asterisk.cdr' doesn't exist)
NOW.. WHY it tries asterisk DB is out of hands.. the defaults have been changed.. no where in code i see reference to it.. it still does..
Re: No time-based tarriffs
How to deal with LCDial not finding a provider
exten => s,s+101,Set(DIALSTATUS=${IF($ ${ISNULL(${DIALSTATUS})}=1 ?"NOPROVIDER":${DIALSTATUS})})
Compiling on Fedora Core 4
Compiling on Fedora Core 4
No time-based tarriffs
Unfortunately this tool can't process this.