Changeset 11497

Show
Ignore:
Timestamp:
02/20/11 02:08:04 (2 years ago)
Author:
escape2mtns
Message:

added pulldown to select pre-configured odbc dsn's from Asterisk's res_odbc.conf, allow SmartRoutes? to be primary processor for trunk calls, allow override extension/context for destinations other than trunks, allow standard FreePBX inbound routes as a SmartRoutes? destination (with override extension), minor bug fixes

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • contributed_modules/modules/smartroutes/functions.inc.php

    r11441 r11497  
    2020include '../fax/functions.inc.php';  // so we can include the same fax hook code that the standard inbound route includes (if available) 
    2121 
    22  
     22// return a list of smartroutes for menu/display 
    2323function smartroutes_list() { 
    2424  global $db; 
     
    3232 
    3333 
     34// return the asterisk dialplan goto destination for a specific smartroute 
    3435function smartroutes_getdest($id) { 
    3536  return array('smartroute-'.$id.',s,1'); 
    3637  } 
    37  
    38    
     38   
     39   
     40// return the database record for a given smartroute 
    3941function smartroutes_get_route($id) { 
    4042  global $db; 
     
    4951  } 
    5052 
     53 
     54// return the queries for a given route  
    5155function smartroutes_get_queries($id) { 
    5256  global $db; 
     
    5862  } 
    5963 
     64   
     65// return the destinations for a given route   
    6066function smartroutes_get_dests($id) { 
    6167  global $db; 
     
    6874   
    6975   
     76// return the name of the smartroute marked as trunk default   
     77function smartroutes_get_trunkdefault() { 
     78  global $db; 
     79   
     80  $route = $db->getRow("SELECT name FROM smartroute where trunkdefault=1"); 
     81   
     82  if(DB::IsError($route) || count($route) == 0) { 
     83    return null; 
     84    } 
     85     
     86  if(!empty($route[0]) && !DB::IsError($route) && isset($route[0])) return $route[0]; 
     87   
     88  return null; 
     89  } 
     90 
     91   
     92// return the dialplan destination for the smartroute marked as trunk default  
     93function smartroutes_get_trunkdefault_gotoroute() { 
     94  global $db; 
     95   
     96  $route = $db->getRow("SELECT id FROM smartroute where trunkdefault=1"); 
     97   
     98  if(DB::IsError($route) || count($route) == 0) { 
     99    return null; 
     100    } 
     101     
     102  if(!empty($route[0]) && !DB::IsError($route) && isset($route[0])) return smartroutes_getdest($route[0]); 
     103   
     104  return null; 
     105  } 
     106   
     107 
     108// return a list of the Asterisk odbc resources defined  
     109function smartroutes_get_dsns() { 
     110  $ret_dsns = array(); 
     111   
     112  $asterisk_dsns = smartroutes_read_config('/etc/asterisk/res_odbc.conf');   
     113  if(count($asterisk_dsns)) { 
     114    $ret_dsns = array_keys($asterisk_dsns); 
     115    } 
     116  return $ret_dsns; 
     117  } 
     118   
     119 
     120// add a smartroute entry  
    70121function smartroutes_add_route($name) { 
    71122  global $db; 
     
    86137  } 
    87138 
     139   
     140// delete a smartroute entry   
    88141function smartroutes_del($id) { 
    89142  global $db; 
     
    96149} 
    97150 
     151 
     152// save a smartroute entry 
    98153function smartroutes_save($id) { 
    99154  global $db;  
     
    113168   
    114169  foreach ($_POST as $key => $value) { 
     170    if($key == 'trunkdefault' && $value == '1') { 
     171      // only one smartroute can be the trunk default so disable all  
     172      sql("UPDATE `smartroute` SET `trunkdefault` = '0'");       
     173      } 
     174     
    115175    switch ($key) { 
    116176      case 'faxenabled': 
     
    146206      case 'faxdetection': 
    147207      case 'legacy_email': 
     208      case 'trunkdefault': 
    148209      case 'faxdetectionwait': 
    149210        $sql_value = $db->escapeSimple($value); 
     
    293354 
    294355   
     356// return an array of smartroute destinations  
    295357function smartroutes_destinations() { 
    296358  $destinations = array(); 
    297359  $smartroutes = smartroutes_list(); 
    298360 
     361  // first destination is static inbound routes 
     362  //  
     363  // ** in case we translated a DID and want to process based on static inbound routes) 
     364  // ** or if a smartroute is set for default trunk call processing but we want to hand off to static inbound routes 
     365  $destinations[] = array('destination' => 'from-pstn,${EXTEN},1','description' => '* FreePBX Std Inbound Routes *'); 
     366   
    299367  if(isset($smartroutes)) { 
    300368    foreach($smartroutes as $route){ 
     
    315383} 
    316384 
     385 
     386// write the dialplan for smartroutes 
    317387function smartroutes_get_config($engine) { 
    318388  global $ext; 
     
    344414//  $ob_file = fopen('/tmp/smartroute.log','w'); 
    345415//  ob_start('ob_file_callback'); 
     416 
     417    // do we need to configure smartroutes to handle all trunk calls (before static inbound routes)      
     418    $trunk_default_gotoroute = smartroutes_get_trunkdefault_gotoroute(); 
     419    if($trunk_default_gotoroute != null) { 
     420      // smartroutes are taking point on inbound trunk calls 
     421      // create a new from-trunk context 
     422      $ext->add('from-trunk', '_.', '', new ext_setvar('__FROM_DID','${EXTEN}')); 
     423      $ext->add('from-trunk', '_.', '', new ext_setvar('__CATCHALL_DID','${EXTEN}')); 
     424      $ext->add('from-trunk', '_.', '', new ext_goto($trunk_default_gotoroute[0]));    
     425      $ext->add('from-trunk', 'i', '', new ext_setvar('__CATCHALL_DID','${INVALID_EXTEN}')); 
     426      $ext->add('from-trunk', 'i', '', new ext_goto($trunk_default_gotoroute[0])); 
     427 
     428      // to get to the original static "inbound routes" we go to "from-pstn" (which is the sole inclusion of the existing from-trunk)    
     429      }    
     430     
    346431 
    347432  // *** FIRST FIX CATCHALL TO SET FROM_DID  (we need this when the catch-all is routed to smartroutes for processing - that way we can search on FROM_DID) 
     
    726811            $macrodestination = true; 
    727812            } 
     813             
     814          // also exchange EXTEN for SR_OR_EXTVAR if set FOR ANY PRIMARY DESTINATION 
     815          // also set the actual context for any destination with an ,s, extension FOR ANY PRIMARY DESTINATION 
     816          $dest['extvar'] = trim($dest['extvar']); 
     817          if(!empty($dest['extvar'])) { 
     818            $dest['destination'] = str_replace('${EXTEN}',$dest['extvar'],$dest['destination']); 
     819            $dest_str_part_pos = strpos($dest['destination'], ',s,'); 
     820            if(is_numeric($dest_str_part_pos) ) { 
     821              $dest['destination'] = $dest['extvar'].substr($dest['destination'],$dest_str_part_pos); 
     822              } 
     823            }            
    728824           
    729825          // set processing vars 
     
    739835            // clear these 
    740836            $ext->add($context, $extension, '', new ext_setvar('SR_MACRO', "")); 
    741             $ext->add($context, $extension, '', new ext_setvar('SR_MACRO_TRUNK', "")); 
     837            $ext->add($context, $extension, '', new ext_setvar('SR_MACRO_TRUNK', ""));            
    742838            } 
    743839          $ext->add($context, $extension, '', new ext_goto("process_match_found")); 
     
    862958//  fclose($ob_file);    
    863959  } 
    864    
    865  
    866      
     960 
     961 
     962// helper function for the dialplan generation code - process an individual odbc query     
    867963function smartroutes_create_odbc_query($smartroute, $query) { 
    868964  $odbc_query = array(); 
     
    9161012 
    9171013   
     1014// read an asterisk config file into an array  
    9181015function smartroutes_read_config($config_file) { 
    9191016  $config = array(); 
     
    9681065   
    9691066 
    970    
     1067// save the Asterisk odbc queries/funcs file /etc/asterisk/func_odbc.conf    
    9711068function smartroutes_save_odbc_funcs($odbc_queries) { 
    9721069  global $version; 
     
    10261123   
    10271124} 
    1028    
    1029    
    1030    
     1125 
     1126 
     1127// when a smartroute is setup for default trunk call processing, provide notification on the static inbound route page 
     1128function smartroutes_hook_core($viewing_itemid, $target_menuid) { 
     1129  $html = ''; 
     1130   
     1131  if ($target_menuid == 'did')  {  
     1132    $trunk_default_route_name = smartroutes_get_trunkdefault(); 
     1133       
     1134    if($trunk_default_route_name != null) { 
     1135      $html = '<tr><td colspan="2"><h5><hr>'; 
     1136      $html .= '<p><span style="background-color: #CCFFFF; color: black; line-height: 125%; padding:2pt;">&nbsp;<b style="color: red;">'._("Important:").'</b>&nbsp;&nbsp;'._("Inbound trunk calls first processed by SmartRoute:").' ['.$trunk_default_route_name.']&nbsp;</span></p>'."\n";        
     1137        $html .= '<hr></h5></td></tr>'; 
     1138      } 
     1139    } 
     1140 
     1141  return $html; 
     1142  } 
     1143 
     1144 
     1145// from fax module - provide fax functions for smartroutes (like on the static inbound route pages)  
    10311146function smartroutes_fax_hook_core($viewing_itemid, $target_menuid, $smartroute){  // ejr 2-31-11 modified to pass smartroute array 
    10321147  //hmm, not sure why engine_getinfo() isnt being called here?! should probobly read: $info=engine_getinfo(); 
     
    11481263 
    11491264} 
    1150      
    1151    
    11521265   
    11531266 
  • contributed_modules/modules/smartroutes/install.sql

    r11417 r11497  
    1313  `id` int unsigned NOT NULL PRIMARY KEY auto_increment, 
    1414  `name` varchar(40) NOT NULL,   
    15   `destination` varchar(50) default NULL, 
     15  `trunkdefault` tinyint(1) default '0',   
     16  `destination` varchar(50) default NULL,   
    1617  `faxenabled` tinyint(1) default NULL,   
    1718  `faxdetection` varchar(20) default NULL, 
     
    3940  `search-type` varchar(20) default 'EXACT' 
    4041); 
     42 
     43-- 
     44-- Upgrade existing tables with a new field for version 1.1 
     45-- 
     46ALTER TABLE `smartroute` ADD `trunkdefault` TINYINT(1) default '0'; 
    4147 
    4248-- 
  • contributed_modules/modules/smartroutes/module.xml

    r11417 r11497  
    22  <rawname>smartroutes</rawname> 
    33  <name>SmartRoutes</name> 
    4   <description>Route inbound calls based on ANI, CID, or other variables using external databases.</description> 
    5   <version>1.0</version> 
     4  <description>SmartRoutes is a module that allows you to control inbound call routing based on external database values. Using SmartRoutes you can pre-process incoming DIDs, route incoming calls to the appropriate queue (skills based routing), you can automatically route calls from one trunk to another (sip->tdm gateway), you can set variables in the dial plan (like cdr, caller id name, etc), strip unnecessary caller-id and did prefixes from inbound calls, and much more based on the caller id, did called or other Asterisk call values. As an example, you can route customer calls differently based on how much money they do with your business.</description> 
     5  <version>1.1</version> 
     6  <publisher>VoiceNation Live</publisher> 
     7  <license>GPLv2</license> 
    68  <type>setup</type> 
    79  <category>Addons</category> 
     
    911    <smartroutes category="Inbound Call Control">SmartRoutes</smartroutes> 
    1012  </menuitems> 
    11   <location>release/smartroutes-1.0.tgz</location> 
     13  <location>contributed_modules/release/smartroutes-1.1.tgz</location> 
    1214  <info>http://www.qualityansweringservice.com/anatomy-oscc/freepbx/smartroutes</info> 
     15    <changelog> 
     16          *1.1* added pulldown to select pre-configured odbc dsn's from Asterisk's res_odbc.conf, allow SmartRoutes to be primary processor for trunk calls, allow override extension/context for destinations other than trunks, allow standard FreePBX inbound routes as a SmartRoutes destination (with override extension), minor bug fixes, new database field value trunkdefault in table smartroute   
     17          *1.0* initial commit   
     18    </changelog> 
     19  <depends> 
     20    <version>2.7.0beta1</version> 
     21    <phpversion>5.1.0</phpversion> 
     22  </depends> 
    1323</module> 
  • contributed_modules/modules/smartroutes/page.smartroutes.php

    r11440 r11497  
    9797    <h2><?php echo _("SmartRoutes"); ?></h2> 
    9898    <!--  Splash Screen / Instructions here --> 
    99     <p>SmartRoutes is a module that allows you to control inbound call routing based on external database values.  Using SmartRoutes you can route incoming calls to the appropriate queue (skills based routing), you can automatically route calls from one trunk to another (sip->tdm gateway), you can set variables in the dial plan (like cdr, caller id name, etc), strip unnecessary caller-id and did prefixes from inbound calls, and much more based on the caller id, did called or other Asterisk call values.  As an example, you can route customer calls differently based on how much money they do with your business.</p>  
     99    <p>SmartRoutes is a module that allows you to control inbound call routing based on external database values.  Using SmartRoutes you can route incoming calls to the appropriate queue (skills based routing), you can automatically route calls from one trunk to another (sip->tdm gateway), you can set variables in the dial plan (like cdr, caller id name, etc), strip unnecessary caller-id and did prefixes from inbound calls, and much more based on the caller id, did called or other Asterisk call values.  As an example, you can route customer calls differently based on how much money they do with your business.</p> 
     100    <?php 
     101      $trunk_default_route_name = smartroutes_get_trunkdefault(); 
     102       
     103      if($trunk_default_route_name != null) { 
     104        echo('<p><span style="background-color: #CCFFFF; color: black; line-height: 125%; padding:2pt;">&nbsp;<b style="color: red;">'._("Important:").'</b>&nbsp;&nbsp;'._("Inbound trunk calls processed by SmartRoute:").' ['.$trunk_default_route_name.']&nbsp;</span><br>'."\n"); 
     105        echo('<span style="color:gray;">To process standard inbound routes, choose destination "SmartRoutes" and specify "* FreePBX Std Inbound Routes *"</span></p>');        
     106        } 
     107    ?> 
     108      
    100109    <b>Notes:</b> 
    101110    <ul> 
     
    111120    <?php } ?> 
    112121     
    113     <li>Digium has recommended that MySQL interaction use the more stable ODBC as opposed to Asterisk Addons MySQL commands (which have been deprecated).  Fore more info see: <a href="https://issues.asterisk.org/view.php?id=17964" target="_blank">this report</a> and <a href="http://forums.digium.com/viewtopic.php?f=13&t=76449" target="_blank">this post</a>.</li> 
     122    <li>Digium has recommended that MySQL interaction use the more stable ODBC as opposed to Asterisk Addons MySQL commands (which have been deprecated).  For more info see: <a href="https://issues.asterisk.org/view.php?id=17964" target="_blank">this report</a> and <a href="http://forums.digium.com/viewtopic.php?f=13&t=76449" target="_blank">this post</a>.</li> 
    114123    <li>To access multiple databases, or for more advanced call routing you can have smartroutes that route to other smartroutes.  Setting the variables in the dialplan will allow database lookup values to persist from one Smartroute to the next.</li> 
    115124    <li>This module will set the FROM_DID variable in the catch-all section for inbound routes.</li> 
     
    171180         
    172181    echo('</table>'."\n");   
    173    
     182     
     183  // ** setup the "default trunk route" row 
     184  // **************************** 
     185  echo('<table>'."\n"); 
     186  echo('<tr><td colspan="2"><h5><a href=# class="info">'._("Default Trunk Route")."\n".'<span>'); 
     187    echo _("Default Trunk Route"); 
     188    echo('<br /><br /></span></a><hr></h5></td></tr>'."\n");     
     189       
     190    echo('<tr><td><a href="#" class="info">'._("Select this SmartRoute as the primary handler for trunk calls?").'<span>'._("Should this SmartRoute be the iniital route for processing trunk calls?  (Note: Will bypass static routes - but can be sent to static routes as destination below).").'</span></a>:</td>'."\n"); 
     191    echo('<td><select name="trunkdefault" tabindex="'.$tabindex++.'"><option value="1" '.($smartroute_route['trunkdefault'] == "1"? 'SELECTED':'').' >Yes</option><option value="0" '.($smartroute_route['trunkdefault'] != "1"? 'SELECTED':'').' >No</option></select></td></tr>'."\n"); 
     192     
     193  if($smartroute_route['trunkdefault'] == "1") { 
     194    echo('<tr><td colspan="2"><br><span style="background-color: #CCFFFF; color: black; line-height: 125%; padding:2pt;">&nbsp;<b style="color: red;">'._("Important:").'</b>&nbsp;&nbsp;'._("Inbound trunk calls processed by this SmartRoute").'&nbsp;</span><br>'."\n"); 
     195    echo('<span style="color:gray;">To process standard inbound routes, choose destination "SmartRoutes" and specify "* FreePBX Std Inbound Routes *"</span></td></tr>'."\n");         
     196    }     
     197             
     198    echo('</table>'."\n"); 
     199       
    174200   
    175201  echo('<table>'."\n"); 
     
    258284     
    259285    echo('<tr><td colspan="2"><div class="smartroutes_dest"><table>'."\n"); 
    260   echo('<tr id="smartroutes_destlabels"><td style="padding-left: 18px;"><a href=# class="info">'._("Match Value").'<span><br>'._("The value returned from the main query that this route defines.").'<br></span></a></td><td><a href=# class="info">'._("Trunk Extension").'<span><br>'._("(optional) When sending to a trunk, allow specifing new destination DID value or variable.  This feature only works for the primary destination as a trunk and requires FreePBX version 2.8 or higher.  To use this capability for failover, have failover go to another smartroute where the primary destination trunk is the failover trunk with an override extension.<br><br>Note that any Asterisk vars used here need to be indicated as they are in Asterisk with '\${asteriskvar}'.").'<br></span></a></td><td><a href=# class="info">'._("Destination").'<span><br>'._("Primary destination for this route.").'<br></span></a></td><td><a href=# class="info">'._("Failover").'<span><br>'._("When primary destination is a *trunk* that is unable to connect, use this destination.").'<br></span></a></td></tr>'."\n"); 
     286  echo('<tr id="smartroutes_destlabels"><td style="padding-left: 18px;"><a href=# class="info">'._("Match Value").'<span><br>'._("The value returned from the main query that this route defines.").'<br></span></a></td><td><a href=# class="info">'._("Override Primary<br>Extension/Context").'<span><br>'._("(optional) When destination normally passes '\${EXTEN}' in the Asterisk dialplan goto call, allow specifing new destination DID value or variable.  If the destination normally passes the 's' extension then we will replace the primary context with this variable or value (the specific target of the type selected is irrelevant because we'll override it).  This feature only applies to the primary destination.  To use this capability for failover, have failover go to another smartroute where the primary destination is the failover destination with a primary override extension/context.<br><br>Note that any Asterisk vars used here need to be indicated in Asterisk value notation with '\${asteriskvar}'.<br><br>Example extension translation uses: Custom Contexts, Smartroutes, Trunks (FreePBX 2.8+), and the FreePBX Std Inbound Routes.<br><br>Example context translation uses: IVR, and Announcements.").'<br></span></a></td><td><a href=# class="info">'._("Destination").'<span><br>'._("Primary destination for this route.").'<br></span></a></td><td><a href=# class="info">'._("Failover").'<span><br>'._("When primary destination is a *trunk* that is unable to connect, use this destination.  Note: This feature requires FreePBX version 2.8 or higher. ").'<br></span></a></td></tr>'."\n"); 
    261287   
    262288  // get freepbx version 
     
    344370     
    345371    echo('<tr><td><a href="#" class="info">'._("Database Type").'<span>'._("Select the database type to use.").'</span></a>:</td>'."\n"); 
    346     echo('<td><select name="dbengine" tabindex="'.$tabindex++.'"><option value="odbc" '.($smartroute_route['dbengine'] == "odbc"? 'SELECTED':'').' >ODBC (Recommended)</option><option value="mysql" '.($smartroute_route['dbengine'] != "odbc"? 'SELECTED':'').' >MySQL</option></select></td></tr>'."\n"); 
    347      
    348   echo('<tr><td><a href="#" class="info">'._("MySQL Host").'<span>'._("Enter the MySQL Host (if using MySQL).").'</span></a></td>'."\n"); 
     372    echo('<td><select name="dbengine" tabindex="'.$tabindex++.'"><option value="odbc" '.($smartroute_route['dbengine'] == "odbc"? 'SELECTED':'').' >ODBC (Recommended)</option><option value="mysql" '.($smartroute_route['dbengine'] != "odbc"? 'SELECTED':'').' >MySQL (Deprecated)</option></select></td></tr>'."\n"); 
     373     
     374  echo('<tr><td><a href="#" class="info">'._("MySQL Host").'<span>'._("Enter the MySQL Host (if using MySQL) DEPRECATED.").'</span></a></td>'."\n"); 
    349375  echo('<td><input type="text" name="mysql-host" value="'.$smartroute_route['mysql-host'].'" tabindex="'.$tabindex++.'"></td></tr>'."\n"); 
    350376   
     
    360386  echo('<br>'."\n"); 
    361387 
    362   echo('<tr><td><a href="#" class="info">'._("ODBC DSN").'<span>'._("Enter the ODBC DSN (if using ODBC) RECOMMENDED").'</span></a></td>'."\n"); 
    363   echo('<td><input type="text" name="odbc-dsn" value="'.$smartroute_route['odbc-dsn'].'" tabindex="'.$tabindex++.'"></td></tr>'."\n");     
     388  // list dsn's configured in Asterisk (/etc/asterisk/res_odbc.conf 
     389  $dsn_list = smartroutes_get_dsns(); 
     390  if(is_array($dsn_list) && count($dsn_list)) { 
     391    echo('<tr><td><a href="#" class="info">'._("ODBC DSN").'<span>'._("Enter the ODBC DSN (if using ODBC) RECOMMENDED").'</span></a></td>'."\n"); 
     392    echo('<td><select name="odbc-dsn" tabindex="'.$tabindex++.'">."\n"'); 
     393    foreach($dsn_list as $dsn_name) { 
     394        echo('<option value="'.$dsn_name.'" '.($smartroute_route['odbc-dsn'] == $dsn_name? 'SELECTED':'').' >'.$dsn_name.'</option>'."\n"); 
     395      } 
     396     
     397      echo('</select></td></tr>'."\n"); 
     398    } 
     399  else {     
     400    // just provide an entry field (assume they will add the odbc source to asterisk later 
     401    echo('<tr><td><a href="#" class="info">'._("ODBC DSN  (Note: None found configured in Asterisk)").'<span>'._("Enter the ODBC DSN (if using ODBC) RECOMMENDED").'</span></a></td>'."\n");     
     402    echo('<td><input type="text" name="odbc-dsn" value="'.$smartroute_route['odbc-dsn'].'" tabindex="'.$tabindex++.'"></td></tr>'."\n");     
     403    }      
    364404     
    365405    echo('</table>'."\n");   
     
    649689      // *** NOTE THAT WE USE THE SAME FORM FIELD LINES AS ABOVE EXCEPT THAT THE ++ IS REMOVED FROM tabindex AND WE ADJUST THE VAL BEFORE EACH LINE 
    650690      // we also modified the $destSetNum value to support dynamic creation 
     691       
     692      // get freepbx version 
     693      $installed_ver = getversion();     
    651694        
    652695      // fix for our .js here from loop above 
     
    670713      $tabindex = "'+tabindex1+'";     
    671714      echo('<td><input type="text" class="smartroute_dest_extvar" id="smartroute_dest_extvar_'.$destRowsUsed.'" name="smartroute_dest_extvar['.$destRowsUsed.']" value="'.$dest['extvar'].'" tabindex="'.$tabindex.'" /></td>'); 
    672  
    673       // get freepbx version 
    674       $installed_ver = getversion(); 
    675715       
    676716      //removed the ++ from $destSetNum and hard-coded the destSet numbers (from original code in form above)