Showing posts with label unixODBC. Show all posts
Showing posts with label unixODBC. Show all posts

Sunday, January 9, 2011

Asterisk with Oracle


Now Asterisk:

Having installed unixODBC and unixODBC-devel, I download Asterisk and installed it.

./configure

make or make menuselect

make install

During the execution of ./configure script, on finding uinxODBC and unixODBC-devel installed, it prepares all ODBC related modules for installation, it can be verified it by using ‘make select’ instead of ‘make’. After ‘make install’ had finished, my Asterisk was ODBC enabled, all I needed to do was configure the conf files. 


Before changing the conf files, I created a table called ‘sip_buddies’ in my database, schema can be found here, I had to make some changes in the schema according to my database. I was planning to test peer registration from database.

On Asterisk, I was interested in dynamic mode of Asterisk Realtime Arcitecture (ARA), based on that, I had to change the following conf files:

/etc/asterisk/modules.conf
 /etc/asterisk/res_odbc.conf
/etc/asterisk/extconfig.conf

In modules.conf, I uncommented following two lines:

preload => res_odbc.so
preload => res_config_odbc.so

In res_odbc.conf, I added following context:

[asterisk_oracle]
enabled  => yes
dsn => OracleODBC-11g     ; the context added to odbc.ini
;username => testdb            ;already provided in odbc.ini , may be provided here too
;password => testdb           ;already provided in odbc.ini, may be provided here too
pooling => no
limit => 0
pre-connect => yes

Like username and password, there are other parameters in odbc.ini which may be overridden here in this file, as has been mentioned at the above link.

Finally, I changed the extconfig.conf and added the following line:

sippeers => odbc, asterisk_oracle, sip_buddies

‘asterisk_oracle’ is the database as I created in res_odbc.conf. sip_buddies was the table in my database where peers resided.

After running asterisk, I executed following command on CLI
odbc show

The output showed that I was connected to OracleODBC-11g.

Then I added some peers in my peers table while Asterisk was running and tried to register them on Asterisk through Soft Phones.


Note: I had a little problem here while registering the peer with following output:
chan_sip.c:20603 handle_request_register: Registration from…….. failed for…….. - No
matching peer found.
It was fixed by populating the ‘defaultip’ field of my table sip_buddies, a null value in this field was creating the problem. This problem has been discussed with a patch that is available here. I hope the future release of Asterisk would have it fixed or you can do it yourself from above link by changing the source.
 
It’s all worth it. I was successfully able to register my peers without a reload. Everything I did was working fine especially about unixODBC-devel which seemed like a nightmare!!!!!!

You can do more things with this, I hope this long post (splited into four parts) is helpful to all you guys who dealing with the same issue. Let me know, if it is useful for you.




Saturday, January 8, 2011

Asterisk with Oracle

...continuation


Put it all Together:

As a summary of above discussion, l used following components:
  •  unixODBC 2.3.0 (available here)
  •  Oracle Instant Client 11g  11.2.0.2-both Basic and ODBC Supplement Packages (available here)
  •  unixODBC-devel 2.2.11 (Initially unixODBC 2.2.11 is also needed to identify the inter-dependency between both)
As said before, I’ll be using absolute paths for referring directories and file in this discussion. Also I executed all the commands as super user—root.

Following command installed unixODBC 2.2.11 and unixODBC -devel 2.2.11 from repository (you may install them by downloading rpm packages from internet).

yum –install unixodbc unixodbc-devel

Files related to both of these packages resided in different directories after installation which can be check using the commands ‘rpm -ql unixodbc-devel’ and rpm ‘rpm -ql unixodbc’.  Here I was merely interested in identifying the dependency of unixODBC-devel on unixODBC. Apart from other files, both packages had their Static and Shared library files in /usr/lib/ directory.  Some of the Shared library files of unixODBC-devel were actually soft links to the Shared library files of unixODBC which formed the dependency on unixODBC. I was interested only in these shared library files of unixODBC, others had no importance. My plan was to provide unixODBC-devel with these shared library files from unixODBC 2.3.0. That was the only purpose of installing unixODBC 2.2.11 and was supposed to be uninstalled after it had served its purpose. But before uninstalling it I decided to make a copy of all of its files especially shared library files, so that I could use them if I didn’t find any of the shared libraries from unixODBC 2.3.0. I used the following Shell script to copy all files of unixODBC 2.2.11 in a directory /usr/backup/ unixODBC/.

#!/bin/sh
for file in `rpm -ql unixODBC`
do
  cp "$file" /usr/backup/unixODBC/
done



Now I could uninstall unixODBC 2.2.11 using command (yum –e unixodbc) but as unixODBC-devel had a dependency on unixODBC, Package Manager asked to remove unixODBC-devel too which I needed for Asterisk. I used the following command to remove unixODBC package forcing the package not to check the dependencies.

rpm –e  --no-deps unixodbc

This removed the unixODBC package successfully but this made following soft linked shared library files of unixODBC-devel unstable/corrupted having no source file in the directory /usr/lib/ (try ls -lrt). As mentioned before, I had planned to provide these library files from unixODBC 2.3.0.

UnixODBC-devel 2.2.11
UnixODBC 2.2.11
libtemplate.so
libtemplate.so.1.0.0
libtdsS.so
libtdsS.so.1.0.0
libsapdbS.so
libsapdbS.so.1.0.0
liboraodbcS.so
liboraodbcS.so.1.0.0
liboplodbcS.so
liboplodbcS.so.1.0.0
libodbctxtS.so
libodbctxtS.so.1.0.0
libodbcnnS.so
libodbcnnS.so.1.0.0
libodbcminiS.so
libodbcminiS.so.1.0.0
libodbcinst.so
libodbcinst.so.1.0.0
libodbcdrvcfg2S.so
libodbcdrvcfg2S.so.1.0.0
libodbcdrvcfg1S.so
libodbcdrvcfg1S.so.1.0.0
libodbccr.so
libodbccr.so.1.0.0
libnn.so
libnn.so.1.0.0
libmimerS.so
libmimerS.so.1.0.0
libgtrtst.so
libgtrtst.so.1.0.0
libesoobS.so
libesoobS.so.1.0.0
libboundparam.so
libboundparam.so.1.0.0


















Next I downloaded and put unixODBC-2.3.0.tar.gz in the directory /usr/local/src/ and installed it by executing the following set of commands:

tar zxvf unixODBC-2.3.0.tar.gz  (This created a directory named unixODBC-2.3.0)

cd unixODBC-2.3.0

./configure --prefix=/usr/

make

make install

This installed the unixODBC-2.3.0’s binary files in /usr/bin/, header files in /usr/include, ini files (odbc.ini, odbcinst.ini) in /usr/etc/ and shared library files in /usr/lib/. The prefix (--prefix=/usr/) passed to the ‘configure’ script purposely so that shared libray files of unixODBC 2.3.0 are put in /usr/lib/ directory to resolve the unstable linked shared library files of unixODBC-devel 2.2.11.

I noticed there were only two files (libodbcinst.so.1.0.0 and libodbccr.so.1.0.0) from unixODBC 2.3.0 which matched two of unstable/corrupted shared library files of unixODBC-devel (libodbcinst.so and libodbccr.so);  highlighted in yellow in above table. For the rest of the files, I copied the original shared library files of unixODBC 2.2.11 of which I had made a backup in /usr/backup/ unixODBC/ previously. After copying these shared library files, all unstable files of devel were stable now. (Again try ls -lrt).

unixODBC can be checked by through  following command:

odbcinst –j

Next I downloaded Oracle Instant Client 11g, both Basic and ODBC Supplement packages and unzipped both of them in same directory /opt/instantclient_11/.

/opt/instantclient_11/ directory contains a script called odbc_update_ini.sh. This script takes four arguments, three of which are optional. I passed only the compulsory argument and leave the optional arguments. The only argument I sent (the one which is mandatory) is the path to Driver Manager that simply means the prefix of etc/odbc.ini and etc/odbcinst.ini.

As I mentioned before when I installed unixODBC 2.3.0, it put ini files in /usr/etc/ so I executed the above script as below:

 cd /opt/instantclient_11/

./odbc_update_ini.sh ‘/usr/’

This script automatically configures the Oracle Driver with unixODBC 2.3.0 by updating two files; /usr/etc/odbcinst.ini and /root/.odbc.ini. (If non-super user is logged in while executing this script, then /home/username/.odbc.ini is update)

In /usr/etc/odbcinst.ini, I had an entry like the one below: 

[Oracle 11g ODBC driver]
Description     = Oracle ODBC driver for Oracle 11g
Driver          = /opt/instantclient_11_2/libsqora.so.11.1
Setup           =
…………….
…………….
…………….

In /root/.odbc.ini, I had an entry like the one below:

[OracleODBC-11g]
Application Attributes = T
…………….
…………….
Driver = Oracle 11g ODBC driver
DSN = OracleODBC-11g
…………….
…………….
……………

I edited the above entry in /root/.odbc.ini, I added some new fields, commented some existing fields (using ;) and changed the values of some of the fields. After these changes its looks like the below:

[OracleODBC-11g]
Application Attributes = T
Attributes = W
BatchAutocommitMode = IfAllSuccessful
BindAsFLOAT = F
CloseCursor = F
DisableDPM = F
DisableMTS = T
Driver = Oracle 11g ODBC driver    ; the entry from odbcinst.ini
DSN = OracleODBC-11g                
EXECSchemaOpt =
EXECSyntax = T
Failover = T
FailoverDelay = 10
FailoverRetryCount = 10
FetchBufferSize = 64000
ForceWCHAR = F
Lobs = T
Longs = T
MaxLargeData = 0
MetadataIdDefault = F
QueryTimeout = T
ResultSets = T
Database = XE                                                   ;db name
ServerName = xxx.xxx.xxx.xxx                  ; db ip
Port = 1521                                                         ;db port
;ServerName = 192.168.0.105:1521/xe                   ; has been commented, may be used as well
SQLGetData extensions = F
Translation DLL =
Translation Option = 0
DisableRULEHint = T
;UserID = testdb                                               ;has been commented
UserName = testdb                                        ;db user
Password = testdb                                          ;db password
StatementCache=F
CacheBufferSize=20
UseOCIDescribeAny=F

I copied this entry i.e. [OracleODBC-11g] in /root/.odbc.ini to /usr/etc/odbc.ini, so both ini files have the entry [OracleODBC-11g] with same fields and their values. 

.odbc.ini (with a dot) is read when db connection is being made by the user himself or herself while odbc.ini (without a preceding dot) is read when a db connection is being made by an application such as Asterisk. (Try odbcinst –q –d to see the driver’s details)

I executed the following command of isql, which is a utility application shipped with unixODBC, to check my Oracle DB connection.

isql –v OracleODBC-11g

I got the following output showing that connection has been successful with the DB.

+---------------------------------------+
| Connected! |
| |
| sql-statement |
| help [tablename] |
| quit |
| |
+---------------------------------------+

This successful connection does not mean that what I did for unixODBC-devel is okay, that could only be confirmed if Asterisk was successful in communicating with the databse. I could make a successful connection with database using isql from unixODBC 2.3.0 without even installing unixODBC-devel. However, unixODBC 2.2.11 wasn’t successful in making a connection with database through isql because that doesn’t work with Oracle Instant Client.

Asterisk with Oracle


Note:  As I mentioned previously, this is not a step by step guide of integration of Asterisk with Oracle, I am just writing down everything which I did to make this integration work, which means some of the things I did may not be necessary i.e. there might be some extra steps I did. I didn’t have the opportunity and the time to identify which steps are exactly required. Also in this discussion, I am using absolute paths to referring to directories and files which I had on my system. You can adjust your paths accordingly or just use the ones I did, they are standard places.

Problems and Solutions:
Asterisk works with any RDBMS through ODBC. I was working on Linux CentOS 5, so I used unixODBC—an ODBC implementation for UNIX based Operating Systems. For more details see here. unixODBC (or any implementation of ODBC) needs a driver to communicate with the RDBMS e.g. in my case, I needed Oracle Driver for unixODBC that allows it to communicate with Oracle. There is one Oracle Driver available from easysoft but for this you have to purchase the license- A Problem!!!!!!

So I decided to use Oracle Instant Client with two of its packages—Basic and ODBC Supplement (see here). These two together solve my first problem of a free Oracle Driver. However, somewhere on the web (I can’t remember the link), I read that Oracle Instant Client 10g works only with specific distros of Linux and CentOS wasn’t there in the list-Another Problem!!!!

For which I opted to use Oracle Instant Client 11g—ver:11.2.0.2.0 (available here), this solves both of my problems.

As I said earlier, Asterisk needs unixODBC (an implementation of ODBC), it also needs unixODBC-devel to communicate with the RDBMS. You have to have both these packages installed on your Linux box before you make/install Asterisk if you intend to make Asterisk communicate with a RDBMS. On executing ‘yum’ command to install both these packages (yum install unixODBC unixODBC-devel), I was able to install unixODBC 2.2.11 and unixODBC-devel 2.2.11 packages. The worst thing I came to know: Oracle Instant Client does not work with unixODBC 2.2.11, it needs unixODBC > 2.2.11 and the latest available on CentOS’s repository was 2.2.11. (I also checked at Ubuntu’s Repository on another machine, it was same as CentOS)-Yet Another Problem!!!!

Okay fine!!! I decided to use unixODBC 2.3.0 available here, this fixes my problem but I didn’t find the corresponding devel package anywhere on the web (I was assuming it would be something like unixODBC -devel 2.3.0)-Problem after Problem!!!

After doing quite a lot search for some work around, I decided to go with unixODBC -devel 2.2.11 and unixODBC 2.3.0. I tried to install unixODBC -devel 2.2.11 using ‘yum’ command (yum install unixODBC -devel). This also tries to install unixODBC 2.2.11 showing there is a dependency of unixODBC -devel upon unixODBC -PROBLEMS!!!!!!!!!

Now the new task I had was to identify the dependencies of unixODBC -devel 2.2.11 upon unixODBC 2.2.11 and map them to unixODBC 2.3.0 instead of unixODBC 2.2.11. That means I was going to use unixODBC 2.3.0 and satisfy unixODBC -devel 2.2.11 from unixODBC 2.3.0 for what it needed from unixODBC 2.2.11. If there still are dependencies unresolved from unixODBC 2.3.0, I resolved them through unixODBC 2.2.11 as you see later.

Luckily, this proved to be the last problem that I had to resolve. Following discussion describes how I actually did all the above things.



 

Friday, January 7, 2011

Asterisk with Oracle

Asterisk works with its conf files where it finds the information it needs. At start up, Asterisk loads all the information from those files, now if you make a change in any of the conf, you have to either restart Asterisk or reload the module the file belongs to. This is our first situation, let’s call it Scenario A.
Now think about a practical deployment of Asterisk where you want do some sort of load sharing having multiple instances of Asterisk. However, you want to have same configuration for all instances of Asterisk e.g. dial plans, peers, users etc. You will have to do the tedious job of updating the conf files for each instance of Asterisk; the situation worsens if you have to make a change in any of the conf files. This is our second situation, let’s call it Scenario B.

Both of these scenarios are not a big problem, if they don’t have to be performed frequently but there are some files which might be required to be updated frequently e.g. changes in dial plans, adding/removing/updating peers or users, these files includes extensions.conf, sip.conf, iax.conf, users.conf etc.

Well scenario A may be resolved by having someone reloading the conf files after the changes, or you may write an external script (e.g. Shell Script) using a command something like asterisk reload and have that script running on regular basis in a scheduler e.g. crontab. However, that doesn’t sound like a reasonable solution, moreover, it doesn’t fit with our Scenario B.

How about putting this configuration information in an external database and having Asterisk to load that information from the database rather than files. That’s solves our problem in scenario B, put the configuration in one database and configure all instances of Asterisk to load the configuration from a single place--Database. Asterisk is equipped with the capability/feature to read the configuration from database through a feature called Asterisk Real-time Architecture (ARA). You can find more information about ARA here. Or you can find this information in ‘doc’ directory of untarred Asterisk directory. ARA mainly works in two modes: Static Real-time and Dynamic Real-time. Static Mode works like the plain conf files i.e. configuration is loaded at the startup and if you make changes, you have to do a reload; asterisk loads the configuration from the database. On the other hand, Dynamic Real-time works in dynamic way, it does load the information at the startup from database but if you make a change in database, it automatically reflects on Asterisk, that means NO RELOAD. Isn’t it great? For example, you add a sip user to database through a front end interface; it gets provisioned automatically on Asterisk!!!!! That fixes our problem for scenario A.

You can find ample information on ARA and its configuration with MySQL and PostgreSQL on the internet and Asterisk’s free book available here.  I’m going to discuss Asterisk’s integration with Oracle. My discussion is more a kind of itinerary rather than a guide towards the issue, it describes what problems I faced with and what did I do to resolve them. 

to be continued...