<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML xmlns="http://www.w3.org/TR/REC-html40" xmlns:o = 
"urn:schemas-microsoft-com:office:office" xmlns:w = 
"urn:schemas-microsoft-com:office:word"><HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">


<META content="MSHTML 6.00.2800.1476" name=GENERATOR>
<STYLE>@page Section1 {size: 8.5in 11.0in; margin: 1.0in 1.25in 1.0in 1.25in; }
P.MsoNormal {
        FONT-SIZE: 12pt; MARGIN: 0in 0in 0pt; FONT-FAMILY: "Times New Roman"
}
LI.MsoNormal {
        FONT-SIZE: 12pt; MARGIN: 0in 0in 0pt; FONT-FAMILY: "Times New Roman"
}
DIV.MsoNormal {
        FONT-SIZE: 12pt; MARGIN: 0in 0in 0pt; FONT-FAMILY: "Times New Roman"
}
A:link {
        COLOR: blue; TEXT-DECORATION: underline
}
SPAN.MsoHyperlink {
        COLOR: blue; TEXT-DECORATION: underline
}
A:visited {
        COLOR: purple; TEXT-DECORATION: underline
}
SPAN.MsoHyperlinkFollowed {
        COLOR: purple; TEXT-DECORATION: underline
}
SPAN.EmailStyle17 {
        COLOR: windowtext; FONT-FAMILY: Arial; mso-style-type: personal-compose
}
DIV.Section1 {
        page: Section1
}
</STYLE>
</HEAD>
<BODY lang=EN-US vLink=purple link=blue>
<DIV><SPAN class=278405716-22092005><FONT face=Arial color=#0000ff size=2>lol 
just posted this yesterday, it's for any ODBC DSN so Access or SQL or an Excel 
spreadsheet, as long as it's set as a DSN. This will work with outgoing Caller 
ID as well, it's just how you set it up in your dialplan. If you want I can 
email you the .agi since email will undoubtedly mangle the script. 
hth.</FONT></SPAN></DIV>
<DIV><SPAN class=278405716-22092005><FONT face=Arial color=#0000ff 
size=2></FONT></SPAN>&nbsp;</DIV>
<DIV><SPAN class=278405716-22092005><FONT face=Arial color=#0000ff 
size=2><STRONG>HOWTO: A simple AGI application to modify incoming CallerID on 
the fly using SQL Server (or any ODBC DSN)</STRONG></FONT></SPAN></DIV>
<DIV><SPAN class=278405716-22092005><FONT face=Arial color=#0000ff 
size=2></FONT></SPAN>&nbsp;</DIV>
<DIV><SPAN class=278405716-22092005><FONT face=Arial color=#0000ff 
size=2>Requirements: </FONT></SPAN></DIV>
<DIV>&nbsp;</DIV>
<DIV><SPAN class=278405716-22092005><FONT face=Arial color=#0000ff size=2>1. <A 
href="http://sourceforge.net/projects/odbcsock">http://sourceforge.net/projects/odbcsock</A></FONT></SPAN></DIV>
<DIV>&nbsp;</DIV>
<DIV><SPAN class=278405716-22092005><FONT face=Arial color=#0000ff size=2>2. The 
SQL server must be in the same subnet as your * server</FONT></SPAN></DIV>
<DIV>&nbsp;</DIV>
<DIV><SPAN class=278405716-22092005><FONT face=Arial color=#0000ff 
size=2>Howto:</FONT></SPAN></DIV>
<DIV>&nbsp;</DIV>
<DIV><SPAN class=278405716-22092005><FONT face=Arial color=#0000ff size=2>1. 
Install ODBCSocketServer on your SQL server and verify connection with<BR>the 
included VB COM app from a Windows box.</FONT></SPAN></DIV>
<DIV><FONT face=Arial color=#0000ff size=2></FONT>&nbsp;</DIV>
<DIV><SPAN class=278405716-22092005><FONT face=Arial color=#0000ff size=2>2. 
Decide how you want to transform the Caller ID. In my case, I want to do<BR>a 
lookup of the CallerID number in SQL server and prepend the Caller ID with<BR>a 
"job number" which is a unique ID we assign to each 
customer.</FONT></SPAN></DIV>
<DIV>&nbsp;</DIV>
<DIV><SPAN class=278405716-22092005><FONT face=Arial color=#0000ff size=2>3. In 
the case of a large database with lots of fields it's a good idea to<BR>create a 
view in SQL server that has *only* the records you want, then you<BR>can filter 
from there. Note the view name.</FONT></SPAN></DIV>
<DIV>&nbsp;</DIV>
<DIV><SPAN class=278405716-22092005><FONT face=Arial color=#0000ff size=2>4. 
Create an ODBC system DSN on the SQL server that points to your SQL<BR>server 
DB</FONT></SPAN></DIV>
<DIV>&nbsp;</DIV>
<DIV><SPAN class=278405716-22092005><FONT face=Arial color=#0000ff size=2>5. 
Modify the following PHP script to your taste. Ensure your PHP.ini in<BR>/etc 
has error and warning suppression ON or else the AGI will return<BR>invalid 
characters:</FONT></SPAN></DIV>
<DIV>&nbsp;</DIV>
<DIV><SPAN class=278405716-22092005><FONT face=Arial color=#0000ff 
size=2>#!/usr/bin/php -q<BR>&lt;?php</FONT></SPAN></DIV>
<DIV>&nbsp;</DIV>
<DIV><SPAN class=278405716-22092005><FONT face=Arial color=#0000ff 
size=2>&nbsp;class ODBCSocketServer 
{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var 
$sHostName; //name of the host to connect to<BR>&nbsp;&nbsp;var $nPort; //port 
to connect to<BR>&nbsp;&nbsp;var $sConnectionString; //connection string to 
use<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
<BR>&nbsp;&nbsp;//function to parse the SQL 
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
function ExecSQL($sSQL) {</FONT></SPAN></DIV>
<DIV>&nbsp;</DIV>
<DIV><SPAN class=278405716-22092005><FONT face=Arial color=#0000ff 
size=2>&nbsp;&nbsp;&nbsp;$fToOpen = fsockopen($this-&gt;sHostName, 
$this-&gt;nPort,<BR>&amp;$errno, &amp;$errstr, 30);<BR>&nbsp;&nbsp;&nbsp;if 
(!$fToOpen)<BR>&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;//contruct error 
string to return<BR>&nbsp;&nbsp;&nbsp;&nbsp;$sReturn = 
"&lt;?xml<BR>version=\"1.0\"?&gt;\r\n&lt;result<BR>state=\"failure\"&gt;\r\n&lt;error&gt;$errstr&lt;/error&gt;\r\n&lt;/result&gt;\r\n";<BR>&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;else<BR>&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;//construct 
XML to send<BR>&nbsp;&nbsp;&nbsp;&nbsp;//search and replace HTML chars in SQL 
first<BR>&nbsp;&nbsp;&nbsp;&nbsp;$sSQL = 
HTMLSpecialChars($sSQL);<BR>&nbsp;&nbsp;&nbsp;&nbsp;$sSend = 
"&lt;?xml<BR>version=\"1.0\"?&gt;\r\n&lt;request&gt;\r\n&lt;connectionstring&gt;$this-&gt;sConnectionString<BR>&lt;/connectionstring&gt;\r\n&lt;sql&gt;$sSQL&lt;/sql&gt;\r\n&lt;/request&gt;\r\n";<BR>&nbsp;&nbsp;&nbsp;&nbsp;//write 
request&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;fputs($fToOpen, 
$sSend);<BR>&nbsp;&nbsp;&nbsp;&nbsp;//now read 
response<BR>&nbsp;&nbsp;&nbsp;&nbsp;while 
(!feof($fToOpen))<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$sReturn 
= $sReturn .<BR>fgets($fToOpen, 
128);<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;fclose($fToOpen);<BR>&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;return 
$sReturn;<BR>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
}//class</FONT></SPAN></DIV>
<DIV>&nbsp;</DIV>
<DIV><SPAN class=278405716-22092005><FONT face=Arial color=#0000ff 
size=2>&nbsp;//Here is the code that uses this class.&nbsp; First we create the 
class<BR>&nbsp;$oTest = new ODBCSocketServer;</FONT></SPAN></DIV>
<DIV>&nbsp;</DIV>
<DIV><SPAN class=278405716-22092005><FONT face=Arial color=#0000ff 
size=2>&nbsp;//Set the Hostname, port, and connection 
string<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $oTest-&gt;sHostName = 
"192.168.1.17";<BR>&nbsp;$oTest-&gt;nPort = 
9628;<BR>&nbsp;$oTest-&gt;sConnectionString = 
"DSN=intranet;UID=sa;PWD=12345;";</FONT></SPAN></DIV>
<DIV>&nbsp;</DIV>
<DIV><SPAN class=278405716-22092005><FONT face=Arial color=#0000ff size=2>//It 
is bad practice to use the SA account; in sane installations you use 
a<BR>non-priviledge elevated user<BR>&nbsp;//now exec the SQL<BR>&nbsp;$sResult 
= $oTest-&gt;ExecSQL("SELECT * FROM AsteriskCallerID where<BR>homephonecd like 
'".$argv[1]."'"); </FONT></SPAN></DIV>
<DIV>&nbsp;</DIV>
<DIV><SPAN class=278405716-22092005><FONT face=Arial color=#0000ff size=2>//the 
$argv[x] variable array contains any arguments you pass to the script.<BR>The 
array is <BR>// $argv[0] the script itself, $argv[1] the first argument, 
$argv[2] the<BR>second, etc.</FONT></SPAN></DIV>
<DIV>&nbsp;</DIV>
<DIV><SPAN class=278405716-22092005><FONT face=Arial color=#0000ff size=2>$p = 
xml_parser_create();<BR>xml_parse_into_struct($p, $sResult, $vals, 
$index);</FONT></SPAN></DIV>
<DIV>&nbsp;</DIV>
<DIV><SPAN class=278405716-22092005><FONT face=Arial color=#0000ff 
size=2>//xml_parse_into_struct takes the returned XML and parses it out into 
a<BR>variable array</FONT></SPAN></DIV>
<DIV>&nbsp;</DIV>
<DIV><SPAN class=278405716-22092005><FONT face=Arial color=#0000ff 
size=2>xml_parser_free($p); //clean up</FONT></SPAN></DIV>
<DIV>&nbsp;</DIV>
<DIV><SPAN class=278405716-22092005><FONT face=Arial color=#0000ff size=2>//the 
print statement returns your SQL data to Asterisk using the SET<BR>VARIABLE 
statement. <BR>//$vals[x][value] returns the contents of the variable based on 
it's<BR>variable index, you will<BR>//have to play with the index to determine 
which one has the data you want<BR>to return</FONT></SPAN></DIV>
<DIV>&nbsp;</DIV>
<DIV><SPAN class=278405716-22092005><FONT face=Arial color=#0000ff size=2>print 
"SET VARIABLE LANDMARKCID \"".$vals[4][value];<BR>print " 
".$vals[2][value].":\"";</FONT></SPAN></DIV>
<DIV>&nbsp;</DIV>
<DIV><SPAN class=278405716-22092005><FONT face=Arial color=#0000ff 
size=2>?&gt;</FONT></SPAN></DIV>
<DIV>&nbsp;</DIV>
<DIV><SPAN class=278405716-22092005><FONT face=Arial color=#0000ff size=2>6. 
Rename this script to transformcallerid.agi and drop it 
into<BR>/var/lib/asterisk/agi-bin, &amp; chmod 755 it.</FONT></SPAN></DIV>
<DIV>&nbsp;</DIV>
<DIV><SPAN class=278405716-22092005><FONT face=Arial color=#0000ff size=2>7. 
Modify your dialplan with the AGI script called in a distinct context 
and<BR>that context returns control to the original context when 
done.</FONT></SPAN></DIV>
<DIV>&nbsp;</DIV>
<DIV><SPAN class=278405716-22092005><FONT face=Arial color=#0000ff 
size=2>[my-inbound-context-with-did]</FONT></SPAN></DIV>
<DIV>&nbsp;</DIV>
<DIV><SPAN class=278405716-22092005><FONT face=Arial color=#0000ff 
size=2>'Assumption here is that you have several DID's in this context but 
should<BR>be able to work without a DID</FONT></SPAN></DIV>
<DIV>&nbsp;</DIV>
<DIV><SPAN class=278405716-22092005><FONT face=Arial color=#0000ff size=2>exten 
=&gt; 3078,1,SetVar(CURRENTEXTEN=3078)'Set a variable with the 
current<BR>extension being processed<BR>exten =&gt; 
3078,2,Goto(Transform-CallerID,s,1))<BR>exten =&gt; 
3078,3,DoRegualarDialplanStuffHere</FONT></SPAN></DIV>
<DIV>&nbsp;</DIV>
<DIV><SPAN class=278405716-22092005><FONT face=Arial color=#0000ff 
size=2>[Transform-CallerID]</FONT></SPAN></DIV>
<DIV>&nbsp;</DIV>
<DIV><SPAN class=278405716-22092005><FONT face=Arial color=#0000ff size=2>exten 
=&gt; s,1,SetVar(CIDPREFIX=${CALLERIDNUM:3:3})<BR>exten =&gt; 
s,2,SetVar(CIDSUFFIX=${CALLERIDNUM:6:10})<BR>exten =&gt; 
s,3,agi(transformcallerid.agi|${CIDPREFIX}-${CIDSUFFIX}) 'We keep<BR>phone 
numbers in XXX-XXXX format<BR>exten =&gt; s,4,NoOp(${LANDMARKCID}) 'Display the 
returned variable for<BR>debugging purposes<BR>exten =&gt; 
s,5,Gotoif($["${LANDMARKCID}" = " :" ]?6:7) 'If the AGI didn't fond<BR>a match 
in the database<BR>exten =&gt; s,6,SetVar(LANDMARKCID=UNKNOWN:) 'Prepend the 
caller ID with<BR>UNKNOWN:<BR>exten =&gt; 
s,7,SetCallerID(${LANDMARKCID}${CALLERIDNUM:3:10}) 'Otherwise<BR>prepend with 
the returned SQL data<BR>exten =&gt; 
s,8,Goto(my-inbound-context-with-did,${CURRENTEXTEN},3) 'Return<BR>control to 
calling context</FONT></SPAN></DIV>
<DIV>&nbsp;</DIV>
<DIV><SPAN class=278405716-22092005><FONT face=Arial color=#0000ff 
size=2></FONT></SPAN>&nbsp;</DIV>
<BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px">
  <DIV class=OutlookMessageHeader dir=ltr align=left><FONT face=Tahoma 
  size=2>-----Original Message-----<BR><B>From:</B> Tim King 
  [mailto:tim@compnetwork.net]<BR><B>Sent:</B> Thursday, September 22, 2005 
  10:52 AM<BR><B>To:</B> asterisk-users@lists.digium.com<BR><B>Subject:</B> 
  [Asterisk-Users] AGI Script to interact with ACCESS Databse and Set CID info 
  on the fly.<BR><BR></FONT></DIV>
  <DIV class=Section1>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Well guys here comes the fun part. 
  I have a Microsoft access (VBA) application that interfaces with my SQL 
  database. This app pulls of info from the SQL record and than picks up the 
  phone and dials that locations number. I have purchased a few hundred NpaNxx's 
  for my own use. I want get into too much detail there but no worries this is 
  legal. I need to change my CID info on the fly. So I am thinking it should be 
  easy to make an AGI script that just sets the CID info on a particular line 
  using two variables being passed to it $Line_No to tell it what line to set 
  and than $CID to be the number to set on that extension for that call. It also 
  should be relatively simple to have the access app take a look at the area 
  code and phone number for the location being called and pull a phone number 
  from the NUMBERS table which has all of my numbers in it and pass that over. 
  The real question is how do we get Access to speak to an AGI script. Has 
  anyone done anything like this? Thanks a lot for reading but this will be a 
  fun one. <o:p></o:p></SPAN></FONT></P></DIV></BLOCKQUOTE></BODY></HTML>