login | register
Sat 06 of Sep, 2008 [17:08 UTC]

voip-info.org

History

Realtime Integration Of Asterisk With OpenSER

Created by: voicesistem,Last modification on Thu 01 of Nov, 2007 [17:45 UTC] by JustRumours
valid for openser 1.1.x and asterisk 1.2.x


OpenSER is a pure VoIP signaling server using Session Initiation Protocol - SIP. It is flexible and highly configurable but cannot be used to provide media services as voicemail, anounncements or conferencing. For such services, Asterisk is the most suitable open source product. In this document we present how to configure Asterisk to use OpenSER's subscribers database to provide voicemail service. A basic configuration file for OpenSER is posted down the page, allowing to have a functional system by following the steps in this tutorial.

Requirements



UnixODBC Installation


Get the sources from http://www.unixodbc.org, compile and install them on your system

cd /usr/local/src
wget http://www.unixodbc.org/unixODBC-2.2.11.tar.gz
tar xvfz unixODBC-2.2.11.tar.gz
cd unixODBC-2.2.11
./configure –enable-gui=no
make
make install

NOTE: if you get error during compilation in 'sqp/lex.l', the line 240, related to 'YY_FLUSH_BUFFER', you can safely comment/remove that line.

NOTE: you must have /usr/local/lib in your /etc/ld.so.conf file or LD_LIBRARY_PATH environment variable.

MySQL Installation


You can install MySQL using the packaging system from you Linux distribution. The only requirements is to be MySQL 5.0+. For example, http://dotdeb.org provides packages for Debian stable.

After installation, you can set the MySQL root password with a command like:
/usr/bin/mysqladmin -u root password 'your-new-password'


Asterisk Installation


Get Asterisk sources from http://www.asterisk.org. At this moment Asterisk 1.2.9.1 is the latest stable version.

cd /usr/local/src
wget http://ftp.digium.com/pub/asterisk/releases/asterisk-1.2.9.1.tar.gz
tar xvfz asterisk-1.2.9.1.tar.gz
cd asterisk-1.2.9.1


Edit 'apps/Makefile' and uncomment lines:

CFLAGS+=-DUSE_ODBC_STORAGE
CFLAGS+=-DEXTENDED_ODBC_STORAGE


Edit 'apps/app_voicemail.c' and change the size of memeber 'uniqueid' in 'struct ast_vm_user' to 64:

/* Structure for linked list of users */
struct ast_vm_user {
       char context[AST_MAX_CONTEXT];  /* Voicemail context */
       char mailbox[AST_MAX_EXTENSION];/* Mailbox id, unique within vm context
       char password[80];              /* Secret pin code, numbers only */
       char fullname[80];              /* Full name, for directory app */
       char email[80];                 /* E-mail address */
       char pager[80];                 /* E-mail address to pager (no attachme
       char serveremail[80];           /* From: Mail address */
       char mailcmd[160];              /* Configurable mail command */
       char language[MAX_LANGUAGE];    /* Config: Language setting */
       char zonetag[80];               /* Time zone */
       char callback[80];
       char dialout[80];
       char uniqueid[64];              /* Unique integer identifier */ 
       char exit[80];
       unsigned int flags;             /* VM_ flags */
       int saydurationm;
       int maxmsg;                     /* Maximum number of msgs per folder fo
       struct ast_vm_user *next;
};


Proceed with usual Asterisk installation:

make
make install


OpenSER Installation


You can download latest stable version via CVS snapshots. For branch 1.0.0 (latest release in this branch is 1.0.1) you can do:

cd /usr/local/src
wget http://www.openser.org/downloads/snapshots/openser-1.0.0/openser-1.0.0-cvs-latest.tgz
tar xvfz openser-1.0.0-cvs-latest.tgz
cd openser-1.0.0
make all include_modules="mysql"
make install include_modules="mysql"


UnixODBC MySQL Driver Installation


Simply install the package using the tools from your linux distribution. For example, for Debian:

apt-get install libmyodbc


Create OpenSER Database


To create the database needed by OpenSER:

/usr/local/sbin/openser_mysql.sh create


This will create a database named 'openser' and will add a MySQL user 'openser' with full access to it. The default password is 'openserrw', do change it before (by editing usr/local/sbin/openser_mysql.sh) or immediately after you create the database.

Once you create the database, you need to add a new column to the 'subscriber' table to store the PIN for voicemail access:

ALTER TABLE subscriber ADD vmail_password varchar(32);


Create Asterisk Database


The database needed by Asterisk will contain two views ('vmusers' and 'sipusers') of tables from OpenSER database, therefore it is required to have MySQL 5.0+ since the views were introduced in this version. There is a real MySQL table ('voicemessages') which will store the voice messages.

Log in as root in MySQL server:

create database asterisk;

use asterisk;

CREATE TABLE `voicemessages` (
  `id` int(11) NOT NULL auto_increment,
  `msgnum` int(11) NOT NULL default '0',
  `dir` varchar(80) default '',
  `context` varchar(80) default '',
  `macrocontext` varchar(80) default '',
  `callerid` varchar(40) default '',
  `origtime` varchar(40) default '',
  `duration` varchar(20) default '',
  `mailboxuser` varchar(80) default '',
  `mailboxcontext` varchar(80) default '',
  `recording` longblob,
  PRIMARY KEY  (`id`),
  KEY `dir` (`dir`)
) ENGINE=InnoDB;

CREATE VIEW vmusers AS
SELECT phplib_id as uniqueid,
  username as customer_id,
  'default' as context,
  username as mailbox,
  vmail_password as password,
  CONCAT(first_name,' ',last_name) as fullname,
  email_address as email,
  NULL as pager,
  datetime_created as stamp 
FROM openser.subscriber;

CREATE VIEW sipusers AS
SELECT username as name,
  username,
  'friend' as type,
  NULL as secret,
  domain as host,
  CONCAT(rpid, ' ','<',username,'>') as callerid,
  'default' as context,
  username as mailbox,
  'yes' as nat,
  'no' as qualify,
  username as fromuser,
  NULL as authuser,
  domain as fromdomain,
  NULL as insecure,
  'no' as canreinvite,
  NULL as disallow,
  NULL as allow,
  NULL as restrictcid,
  domain as defaultip,
  domain as ipaddr,
  '5060' as port,
  NULL as regseconds
FROM openser.subscriber;


Add a MySQL user which will have full access right to 'asterisk' database.

GRANT ALL ON asterisk.* to asterisk@localhost IDENTIFIED BY 'some_password';


Configure UnixODBC



In the file ‘/usr/local/etc/odbcinst.ini’ you must add:

[MySQL]
Description = MySQL driver
Driver = /usr/lib/odbc/libmyodbc.so
Setup = /usr/lib/odbc/libodbcmyS.so
CPTimeout =
CPReuse =
UsageCount = 1


In the file '/usr/local/etc/odbc.ini' you must add:

[MySQL-asterisk]
Description = MySQL Asterisk database
Trace = Off
TraceFile = stderr
Driver = MySQL
SERVER = localhost
USER = asterisk
PASSWORD = some_password
PORT = 3306
DATABASE = asterisk


Configure Asterisk


In '/etc/asterisk/res_odbc.conf':

[asterisk]
enabled => yes
dsn => MySQL-asterisk
username => asterisk
password => asterisk
pre-connect => yes


In '/etc/asterisk/extconfig.conf':

sipusers => odbc,asterisk,sipusers
sippeers => odbc,asterisk,sipusers
voicemail => odbc,asterisk,vmusers


In '/etc/asterisk/sip.conf':

If you want to enable MWI, do not forget to set checkmwi attribute.

checkmwi=10


Guidelines about configuring the SIP channel you find at http://www.voip-info.org/wiki-Asterisk+config+sip.conf. You do not need to add any SIP user or peer in the configuration file, they will be loaded from database.

In ‘/etc/asterisk/voicemail.conf’ you do not need to add any mailbox. They will be loaded from database. The general configuration part of voicemail application is presented at http://www.voip-info.org/wiki/index.php?page=Asterisk+config+voicemail.conf

For our tutorial, we consider that the users will have 4-digit ID. To implement a clear dialing plan in Asterisk which allow extensibility and clear extentions for different services, the calls to voicemail will be prefixed with '1' in OpenSER proxy. This prefix will be transpartent for users. If voice mailbox does not exist, Asterisk will play "invalid extension" message.

In '/etc/asterisk/extensions.conf':

exten => 1,1,Ringing
exten => 1,2,VoicemailMain(${CALLERIDNUM})
exten => 1,3,Hangup

exten => 11,1,Ringing
exten => 11,2,VoicemailMain()
exten => 11,3,Hangup

exten => _1XXXX,1,Ringing
exten => _1XXXX,2,MailboxExists(${EXTEN:1})
exten => _1XXXX,3,Playback(invalid)
exten => _1XXXX,4,Hangup
exten => _1XXXX,103,Voicemail(u${EXTEN:1})
exten => _1XXXX,104,Hangup


Configure OpenSER


Dialing plan:
- local users have 4-digit extension
- to listen its voice messages from its SIP phone, the user has to dial *98 (Asterisk will prompt only for PIN)
- to listen its voice messages from another SIP phone, the user has to dial *981 (Asterisk will prompt for mailbox ID and PIN)
- to call directly to leave voice message to user XXXX, the user has to dial *89XXXX

In '/usr/local/etc/openser/openser.cfg':



#
# $Id$
#

# ----------- global configuration parameters ------------------------

debug=3           # debug level (cmd line: -dddddddddd)
fork=yes          # daemonize
log_stderror=no   # (cmd line: -E)

check_via=no      # (cmd. line: -v)
dns=no            # (cmd. line: -r)
rev_dns=no        # (cmd. line: -R)
children=4
fifo="/tmp/openser_fifo"

listen=udp:10.10.10.10:5060

#
# ------------------ module loading ----------------------------------

# Uncomment this if you want to use SQL database
mpath="/usr/local/lib/openser/modules"
loadmodule "mysql.so"

loadmodule "xlog.so"
loadmodule "sl.so"
loadmodule "tm.so"
loadmodule "rr.so"
loadmodule "maxfwd.so"
loadmodule "usrloc.so"
loadmodule "registrar.so"
loadmodule "textops.so"
loadmodule "avpops.so"
loadmodule "auth.so"
loadmodule "auth_db.so"
loadmodule "group.so"
loadmodule "uri.so"

# ----------------- setting module-specific parameters ---------------
modparam("usrloc|auth_db|avpops|group",
    "db_url", "mysql://openser:openserrw@localhost/openser")

# -- usrloc params --
# persistent storage
modparam("usrloc", "db_mode", 2)

# -- auth params --
# Uncomment if you are using auth module
#
modparam("auth_db", "calculate_ha1", yes)
#
# If you set "calculate_ha1" parameter to yes (which true in this config), 
# uncomment also the following parameter)
#
modparam("auth_db", "password_column", "password")

# -- rr params --
# add value to ;lr param to make some broken UAs happy
modparam("rr", "enable_full_lr", 1)


modparam("avpops", "avp_table", "usr_preferences")

# -------------------------  request routing logic -------------------

# main routing logic

route{

	# initial sanity checks -- messages with
	# max_forwards==0, or excessively long requests
	if (!mf_process_maxfwd_header("10")) {
		sl_send_reply("483","Too Many Hops");
		exit;
	};

	if (msg:len >=  2048 ) {
		sl_send_reply("513", "Message too big");
		exit;
	};

	# we record-route all messages -- to make sure that
	# subsequent messages will go through our proxy; that's
	# particularly good if upstream and downstream entities
	# use different transport protocol
	if (!method=="REGISTER")
		record_route();

	# subsequent messages withing a dialog should take the
	# path determined by record-routing
	if (loose_route()) {
		# mark routing logic in request
		append_hf("P-hint: rr-enforced\r\n"); 
		route(1);
	};

	if (!uri==myself) {
		# mark routing logic in request
		append_hf("P-hint: outbound\r\n"); 
		route(1);
	};

	# if the request is for other domain use UsrLoc
	# (in case, it does not work, use the following command
	# with proper names and addresses in it)
	if (uri==myself) {

		if (method=="REGISTER") {
			if (!www_authorize("openser.org", "subscriber")) {
				www_challenge("openser.org", "0");
				exit;
			};

			save("location");
			exit;
		};

		# requests for Media server
		if(is_method("INVITE") && !has_totag() && uri=~"sip:\*9") {
			route(3);
			exit;
		}

		# mark transaction if user is in voicemail group
		if(is_method("INVITE") && !has_totag()
			&& is_user_in("Request-URI","voicemail"))
		{
			xdbg("user [$ru] has voicemail redirection enabled\n");
			# backup R-URI
			avp_write("$ruri", "i:10");
			setflag(2);
		};
		# native SIP destinations are handled using our USRLOC DB
		if (!lookup("location")) {
			if(isflagset(2)) {
				# route to Asterisk Media Server
				prefix("1");
				rewritehostport("10.10.10.11:5060");
				route(1);
			} else {
				sl_send_reply("404", "Not Found");
				exit;
			}
		};
		append_hf("P-hint: usrloc applied\r\n"); 
	};

	route(1);
}


route[1] {
	
	if(isflagset(2))
		t_on_failure("1");

	if (!t_relay()) {
		sl_reply_error();
	};
	exit;
}


# voicemail access
# - *98 - listen caller's voice messages, being prompted for pin
# - *981 - listen voice messages, being promted for mailbox and pin
# - *98XXXX - leave voice message to XXXX
#
route[3] {
  	# direct voicemail
	if (uri =~ "sip:\*98@" ) {
        	rewriteuser("1");
		xdbg("voicemail access\n");
	} else if (uri =~ "sip:\*981@" ) {
 		strip(4);
		rewriteuser("11");
	} else if (uri =~ "sip:\*98.+@" ) {
 		strip(3);
		prefix("1");
	} else {
		xlog("unknown media extension $rU\n");
		sl_send_reply("404", "Unknown media service");
		exit;
	}

	# route to Asterisk Media Server
	rewritehostport("10.10.10.11:5060");
	route(1);
}

failure_route[1] {
	if (t_was_cancelled()) {
		xdbg("transaction was cancelled by UAC\n");
		return;
	}
	# restore initial uri
	avp_pushto("$ruri", "i:10");
	prefix("1");
	# route to Asterisk Media Server
	rewritehostport("10.10.10.11:5060");
	resetflag(2);
	route(1);
}



See also


Comments

Comments Filter
222

333openser asterisk realtime

by psuarez, Tuesday 18 of September, 2007 [19:31:14 UTC]
hi i have been trying to route calls from openser to asterisk to use the voicemail feature but i cant seen to config my openser.cfg correctly, is the configuration of this file much different is i have asterisk and openser in two different servers but sharing the same database ??

please
Any help will be much appreciated

thank you in advance

here is my openser.cfg file now

  1. $Id: openser.cfg 1676 2007-02-21 13:16:34Z bogdan_iancu $
  2. simple quick-start config script
  3. Please refer to the Core CookBook at http://www.openser.org/dokuwiki/doku.php
  4. for a explanation of possible statements, functions and parameters.

  1. ----------- global configuration parameters ------------------------

debug=3
fork=yes
log_stderror=yes

listen=192.168.2.98
port=5060
children=4
sip_warning=yes
log_facility=LOG_LOCAL0

dns=yes
rev_dns=yes
alias=192.168.2.97


  1. ------------------ module loading ----------------------------------

mpath="/usr/local/lib/openser/modules/"
loadmodule "mysql.so"
loadmodule "xlog.so"
loadmodule "sl.so"
loadmodule "tm.so"
loadmodule "rr.so"
loadmodule "maxfwd.so"
loadmodule "usrloc.so"
loadmodule "registrar.so"
loadmodule "textops.so"
loadmodule "avpops.so"
loadmodule "auth.so"
loadmodule "auth_db.so"
loadmodule "group.so"
loadmodule "uri.so"

  1. ----------------- setting module-specific parameters ---------------

modparam("usrloc|auth_db|avpops|group",
   "db_url", "mysql://openser:openserrw@localhost/openser")

  1. — usrloc params --
  2. persistent storage
modparam("usrloc", "db_mode", 2)

  1. — auth params --
  2. Uncomment if you are using auth module
modparam("auth_db", "calculate_ha1", yes)
  1. If you set "calculate_ha1" parameter to yes (which true in this config),
  2. uncomment also the following parameter)
modparam("auth_db", "password_column", "password")

  1. — rr params --
  2. add value to ;lr param to make some broken UAs happy
modparam("rr", "enable_full_lr", 1)


modparam("avpops", "avp_table", "usr_preferences")

modparam("tm", "fr_timer", 25)
modparam("tm", "fr_inv_timer", 25)
modparam("tm", "noisy_ctimer", 1)


  1. ------------------------- request routing logic -------------------

  1. main routing logic

route{

# initial sanity checks — messages with
# max_forwards==0, or excessively long requests
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483","Too Many Hops");
exit;
};

if (msg:len >= 2048 ) {
sl_send_reply("513", "Message too big");
exit;
};

# we record-route all messages — to make sure that
# subsequent messages will go through our proxy; that's
# particularly good if upstream and downstream entities
# use different transport protocol
if (!method=="REGISTER")
record_route();

# subsequent messages withing a dialog should take the
# path determined by record-routing
if (loose_route()) {
# mark routing logic in request
append_hf("P-hint: rr-enforced\r\n");
route(1);
};

if (!uri==myself) {
# mark routing logic in request
append_hf("P-hint: outbound\r\n");
route(1);
};

# if the request is for other domain use UsrLoc
# (in case, it does not work, use the following command
# with proper names and addresses in it)
if (uri==myself) {

if (method=="REGISTER") {
if (!www_authorize("openser.org", "subscriber")) {
www_challenge("openser.org", "0");
exit;
};

save("location");
exit;
};

# requests for Media server
if(is_method("INVITE") && !has_totag() && uri=~"sip:\*9") {
route(3);
exit;
}

# mark transaction if user is in voicemail group
if(is_method("INVITE") && !has_totag()
&& is_user_in("Request-URI","voicemail"))
{
xdbg("user $ru has voicemail redirection enabled\n");
# backup R-URI
avp_pushto("$ruri", "$avp(i:10)");
setflag(2);
};
# native SIP destinations are handled using our USRLOC DB
if (!lookup("location")) {
if(isflagset(2)) {
# route to Asterisk Media Server
prefix("1");
rewritehostport("192.168.2.97:5065");
route(1);
} else {
sl_send_reply("404", "Not Found");
exit;
}
};
append_hf("P-hint: usrloc applied\r\n");
};

route(1);
}


route1 {

if(isflagset(2))
t_on_failure("1");

if (!t_relay()) {
sl_reply_error();
};
exit;
}


  1. voicemail access
  2. - *86 - listen caller's voice messages, being prompted for pin
  3. - *861 - listen voice messages, being promted for mailbox and pin
  4. - *86XXXX - leave voice message to XXXX
route3 {
  # direct voicemail
if (uri =~ "sip:\*86@" ) {
        rewriteuser("1");
xdbg("voicemail access\n");
} else if (uri =~ "sip:\*861@" ) {
strip(4);
rewriteuser("11");
} else if (uri =~ "sip:\*86.+@" ) {
strip(3);
prefix("1");
} else {
xlog("unknown media extension $rU\n");
sl_send_reply("404", "Unknown media service");
exit;
}

# route to Asterisk Media Server
rewritehostport("192.168.2.97:5065");
route(1);
}

failure_route1 {
if (t_was_cancelled()) {
xdbg("transaction was cancelled by UAC\n");
return;
}
# restore initial uri
avp_pushto("$ruri", "$avp(i:10)");
prefix("1");
# route to Asterisk Media Server
rewritehostport("192.168.2.97:5065");
resetflag(2);
route(1);
}




please
Any help will be much appreciated

thank you in advance
222

333Almost works

by kovzol, Friday 10 of August, 2007 [14:02:28 UTC]
I tried this for openser 1.1 but I had to modify the routing script a bit to be syntactically correct.

I had to write

avp_write("$ruri", "$avp(i:10)");

instead of

avp_write("$ruri", "i:10");

A similar change was needed for the avp_pushto statement. See more details on http://www.openser.org/docs/modules/1.0 ... tml#AEN234 and http://www.openser.org/docs/modules/1.1 ... tml#AEN287.

The full thing doesn't work yet, my work is in progress yet.
222

333

by macallowey.peter, Wednesday 02 of May, 2007 [15:15:18 UTC]
I don't know wether or not anybody have had the same problem but I needed to add a context at the outset of extensions.conf ( default context in my case)

222

333

by openser, Friday 05 of January, 2007 [22:52:15 UTC]
It should be possible to use it with PostgreSQL — OpenSER has support for it, ODBC as well, but I have no much experience with PostgreSQL to give the guidelines.


You can make asterisk listen on other port than 5060 with bindport (e.g., bindport=5064) in sip.conf. Also, OpenSER can use other port, in config file you can use port=xyz or listen=ip:port to set it.
222

333

by kniveton, Thursday 14 of December, 2006 [00:26:46 UTC]
How do OpenSER and Asterisk run on the same machine in this configuration? Won't they both try to bind SIP port(s)?
222

333

by kniveton, Thursday 14 of December, 2006 [00:10:03 UTC]
On debian, you can also install ODBC using the package system (aptitude), instead of compiling from source.

How about using this with PostgreSQL? Should be possible considering the use of odbc.
222

333

by openser, Tuesday 14 of November, 2006 [14:57:45 UTC]
There are some bits of extensions.conf you can use as start point to integrate in your bigger file. there is no specific config in sip.conf to get this working.
222

333Excellent Tutorial, but...

by voipnovice, Thursday 24 of August, 2006 [19:12:42 UTC]
This is an excellent and explicit tutorial. Thanks to voicesistem. I am a bit confused about the last openser.cfg file and thereafter. Could you explain how should the box be configured for the realtime communications like the configurations of the VSPs (sip.conf, extensions.conf) etc. Thanks again,
222

333

by voipnovice, Thursday 24 of August, 2006 [19:12:19 UTC]