[server] / trunk / server / src / dialogicchannelmanager.cxx Repository:
ViewVC logotype

View of /trunk/server/src/dialogicchannelmanager.cxx

Parent Directory Parent Directory | Revision Log Revision Log


Revision 311 - (download) (annotate)
Wed Jul 1 07:17:18 2009 UTC (3 years, 10 months ago) by jtarlton
File size: 22115 byte(s)
    1 /*
    2  * This file is part of Dialogic Woomera Server project.
    3  *
    4  * More information about this project can be found at:
    5  * http://www.opendialogic.org.
    6  *
    7  * Copyright (C) 2009 Dialogic Corp.
    8  *
    9  * This program is free software; you can redistribute it and/or
   10  * modify it under the terms of the GNU General Public License
   11  * as published by the Free Software Foundation; either version 2
   12  * of the License, or (at your option) any later version.
   13  *
   14  * This program is distributed in the hope that it will be useful,
   15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   17  * GNU General Public License for more details.
   18  *
   19  * You should have received a copy of the GNU General Public License
   20  * along with this program; if not, write to the Free Software
   21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
   22  * 02110-1301, USA.
   23  * Alternatively see <http://www.gnu.org/licenses/>.
   24  * Or see the LICENSE file included within the source tree.
   25  *
   26  */
   27 
   28 /*!
   29  * \file        dialogicchannelmanager.cxx
   30  * \brief       Channel manager for Dialogic devices.
   31  * \author      Antony Martin <antony.martin@dialogic.com>
   32  * \author      John Tarlton <john.tarlton@dialogic.com>
   33  * \version     30-MAR-2009
   34  */
   35 
   36 /*-------------------------------- Dependencies ------------------------------*/
   37 
   38 #include <iostream>
   39 #include <fstream>
   40 
   41 #include <string.h>        // memset
   42 
   43 #include <gclib.h>
   44 #include <srllib.h>
   45 
   46 #ifndef lint               // suppress warning about ‘_hsw_1_devmapr4_h’
   47 # define lint
   48 #  include <devmapr4.h>
   49 # undef  lint
   50 #else
   51 # include <devmapr4.h>
   52 #endif
   53 
   54 #include "logger.h"
   55 #include "inifile.h"
   56 #include "string-util.h"
   57 #include "dialogicchannelmanager.h"
   58 
   59 /*----------------------------------------------------------------------------*/
   60 
   61 /*
   62  * ctor, store the application's callback client.
   63  */
   64 DialogicChannelManager::DialogicChannelManager( ChannelManagerClient& client )
   65   : client_ (client), total_ (0)
   66 {
   67   LOGDEBUG("DialogicChannelManager::DialogicChannelManager()");
   68 }
   69 
   70 
   71 /*
   72  * Cleanup channels and call shutdown() to cleanup the devices.
   73  */
   74 DialogicChannelManager::~DialogicChannelManager()
   75 {
   76   LOGDEBUG("DialogicChannelManager::~DialogicChannelManager()");
   77 
   78   for ( channel_t::iterator i = channels_.begin(); i != channels_.end(); ++i )
   79   {
   80     delete *i;
   81   }
   82 
   83   shutdown();
   84 }
   85 
   86 
   87 /*
   88  * Start global call, load device configuration and create devices.
   89  * If the conf file is undefined, probe the devices and create a default
   90  * dti group (test mode).
   91  */
   92 bool DialogicChannelManager::start( const std::string& conf )
   93 {
   94   if ( init() )
   95   {
   96     if ( conf.empty() )
   97     {
   98       LOGDEBUG("DialogicChannelManager::start() no conf file specified, using defaults.");
   99       if ( !detectDevices() )
  100       {
  101         return false;
  102       }
  103 
  104       /* create a 'default' group for all dti devices.
  105        */
  106       GroupManager<GcIsdnDevice>::Group* grp = gcGroups_.add("default");
  107       int pos = 1;
  108 
  109       std::vector<DtiConfig>::iterator i;
  110       for ( i = deviceConfig_.dti.begin(); i != deviceConfig_.dti.end(); ++i )
  111       {
  112         (*i).groups.push_back(DtiConfig::group_membership_t(grp, pos++));
  113       }
  114       return openDevices();
  115     }
  116 
  117     if ( loadConf(conf) )
  118     {
  119       return openDevices();
  120     }
  121   }
  122   return false;
  123 }
  124 
  125 
  126 /*
  127  * Close devices, delete device objects and stop global call.
  128  */
  129 void DialogicChannelManager::shutdown()
  130 {
  131   closeDevices();
  132 
  133   for ( device_map_t::iterator i = deviceMap_.begin(); i != deviceMap_.end(); ++i )
  134   {
  135     delete (*i).second;
  136   }
  137 
  138   LOGDEBUG("DialogicChannelManager::shutdown() Stopping Global Call");
  139   gc_Stop();
  140 }
  141 
  142 
  143 /*
  144  * Configure GC, IPM and VOX devices.
  145  */
  146 bool DialogicChannelManager::init()
  147 {
  148   /* Init Dialogic's standard runtime lib.
  149    */
  150 #ifdef _WIN32
  151   int mode = SR_STASYNC | SR_POLLMODE;
  152   if ( sr_setparm(SRL_DEVICE, SR_MODELTYPE, &mode) == -1 )
  153   {
  154     LOGCRIT("DialogicChannelManager::init() sr_setparm(SR_STASYNC | SR_POLLMODE) failed.");
  155     return false;
  156   }
  157 #else
  158   int mode = SR_POLLMODE;
  159   if ( sr_setparm(SRL_DEVICE, SR_MODEID, &mode) == -1 )
  160   {
  161     LOGCRIT("DialogicChannelManager::init() sr_setparm(SR_POLLMODE) failed.");
  162     return false;
  163   }
  164 #endif
  165 
  166   /* Start GlobalCall using DM3 and IPM. Add others (SS7 etc) as needed.
  167    */
  168   GC_START_STRUCT gcLibStart;
  169   memset(&gcLibStart, 0, sizeof(GC_START_STRUCT));
  170 
  171   CCLIB_START_STRUCT ccstart[] = {
  172     { (char*)"GC_DM3CC_LIB", NULL },
  173     { (char*)"GC_IPM_LIB",   NULL }
  174   };
  175 
  176   gcLibStart.cclib_list = ccstart;
  177   gcLibStart.num_cclibs = 2;
  178 
  179   if ( gc_Start(&gcLibStart) != GC_SUCCESS )
  180   {
  181     LOGCRIT ("DialogicChannelManager::init() gc_Start Failed");
  182     return false;
  183   }
  184   return true;
  185 }
  186 
  187 
  188 /*
  189  * Detect devices and generate configuration file.
  190  */
  191 bool DialogicChannelManager::probe( const std::string& conf )
  192 {
  193   if ( init() )
  194   {
  195     if ( detectDevices() )
  196     {
  197       saveConf(conf);
  198       return true;
  199     }
  200   }
  201   return false;
  202 }
  203 
  204 
  205 /*
  206  * Auto detect devices
  207  */
  208 bool DialogicChannelManager::detectDevices()
  209 {
  210   LOGINFO("Detecting hardware, this may take a long time...");
  211 
  212   /* Determine the number of physical boards, the API call will fail
  213    * with a result of ESR_INSUFBUF but physicalBoards will be set to
  214    * the correct count.
  215    */
  216   int physicalBoards = 0;
  217   long rc = SRLGetAllPhysicalBoards(&physicalBoards, NULL);
  218   if ( rc != ESR_INSUFBUF )
  219   {
  220     LOGERROR("DialogicChannelManager::detectDevices() SRLGetAllPhysicalBoards() failed, error = 0x" << std::hex << rc);
  221     return false;
  222   }
  223 
  224   AUID* auids = new AUID[physicalBoards];
  225 
  226   rc = SRLGetAllPhysicalBoards(&physicalBoards, auids);
  227   if ( rc != ESR_NOERR )
  228   {
  229     LOGERROR("DialogicChannelManager::detectDevices() SRLGetAllPhysicalBoards() 2 failed, error = 0x" << std::hex << rc);
  230     delete[] auids;
  231     return false;
  232   }
  233 
  234   /* dti management needs a unique integer identifier for each dti device,
  235    * here a 1 based sequence number is allocated for this purpose.
  236    */
  237   int dti_index = 1; /* 1..n */
  238 
  239   /* For each Physical Board AUID, determine associated virtual board.
  240    */
  241   for ( int indxPhys = 0; indxPhys < physicalBoards; indxPhys++ )
  242   {
  243     AUID* auid = &auids[indxPhys];
  244 
  245     /* Determine number of virtual boards, the API call will fail
  246      * with a result of ESR_INSUFBUF but virtualBoards will be set to
  247      * the correct count.
  248      */
  249     int virtualBoards = 0;
  250     rc = SRLGetVirtualBoardsOnPhysicalBoard(*auid, &virtualBoards, NULL);
  251     if ( rc != ESR_INSUFBUF )
  252     {
  253       LOGERROR("DialogicChannelManager::detectDevices() SRLGetVirtualBoardsOnPhysicalBoard() failed, error = 0x" << std::hex << rc);
  254       delete[] auids;
  255       return false;
  256     }
  257     LOGINFO("DialogicChannelManager::detectDevices() VirtualBoards = " << virtualBoards);
  258 
  259     SRLDEVICEINFO* srlBoards = new SRLDEVICEINFO[virtualBoards];
  260 
  261     rc = SRLGetVirtualBoardsOnPhysicalBoard(*auid, &virtualBoards, srlBoards);
  262     if ( rc != ESR_NOERR )
  263     {
  264       LOGERROR("DialogicChannelManager::detectDevices() SRLGetVirtualBoardsOnPhysicalBoard() 2 failed, error = 0x" << std::hex << rc);
  265       delete[] srlBoards;
  266       delete[] auids;
  267       return false;
  268     }
  269 
  270     /* For each virtual board, determine associated virtual channels
  271      */
  272     for ( int indxBoard = 0; indxBoard < virtualBoards; indxBoard++ )
  273     {
  274       SRLDEVICEINFO* srlBoard = &srlBoards[indxBoard];
  275 
  276       int virtualChans = 0;
  277       /* Determine number of virtual channels, the API call will fail
  278        * with a result of ESR_INSUFBUF but physicalBoards will be set to
  279        * the correct count.
  280        */
  281       rc = SRLGetSubDevicesOnVirtualBoard(srlBoard->szDevName, &virtualChans, NULL);
  282       if ( (rc != ESR_INSUFBUF) && (rc != ESR_NOERR) )
  283       {
  284         LOGERROR("DialogicChannelManager::detectDevices() SRLGetSubDevicesOnVirtualBoard() failed, error = 0x" << std::hex << rc);
  285         delete[] srlBoards;
  286         delete[] auids;
  287         return false;
  288       }
  289 
  290       SRLDEVICEINFO* srlChannels = new SRLDEVICEINFO[virtualChans];
  291 
  292       rc = SRLGetSubDevicesOnVirtualBoard(srlBoard->szDevName, &virtualChans, srlChannels);
  293       if ( rc != ESR_NOERR )
  294       {
  295         LOGERROR("DialogicChannelManager::detectDevices() SRLGetSubDevicesOnVirtualBoard() 2 failed, error = 0x" << std::hex << rc);
  296         delete[] srlChannels;
  297         delete[] srlBoards;
  298         delete[] auids;
  299         return false;
  300       }
  301 
  302       /* Save device info in deviceConfig_
  303        */
  304       for ( int indxChan = 0; indxChan < virtualChans; indxChan++ )
  305       {
  306         SRLDEVICEINFO* srlChannel = &srlChannels[indxChan];
  307 
  308         std::string dev_type = "";
  309         switch ( srlChannel->iDevType )
  310         {
  311           case TYPE_R4_VOX_CHANNEL:      /* E.g. dxxxB1C1 */
  312           {
  313             FEATURE_TABLE feature_table;
  314 
  315             int dev = dx_open(srlChannel->szDevName, 0);
  316             if ( dev == -1 )
  317             {
  318               break;
  319             }
  320             if ( dx_getfeaturelist(dev, &feature_table) == -1 )
  321             {
  322               LOGERROR("DialogicChannelManager::detectDevices() Failed to get featurelist for device: " << srlChannel->szDevName);
  323             }
  324             else
  325             {
  326               /* This check is to deal with dual span cards which
  327                * have tone-detect only vox devices that are not
  328                * usable by this application.
  329                */
  330               if ( feature_table.ft_play )
  331               {
  332                 deviceConfig_.vox.push_back(srlChannel->szDevName);
  333                 dev_type = "R4_VOX_CHANNEL";
  334               }
  335             }
  336             dx_close(dev);
  337             break;
  338           }
  339 
  340           case TYPE_R4_DTI_TIMESLOT:     /* E.g. dxxxB1T1 */
  341             deviceConfig_.dti.push_back(DtiConfig(srlChannel->szDevName, dti_index++));
  342             dev_type = "R4_DTI_TIMESLOT";
  343             break;
  344 
  345           case TYPE_R4_IPM_CHANNEL:      /* E.g. ipmB1C1 */
  346             dev_type = "R4_IPM_CHANNEL";
  347             deviceConfig_.ipm.push_back(srlChannel->szDevName);
  348             break;
  349 
  350           default:
  351             break;
  352         }
  353 
  354         /* Display AUID, virtual board, virtual channel and device type.
  355          * Device type values found in devmapr4.h
  356          */
  357         if ( dev_type.length() == 0 )
  358         {
  359           LOGINFO("DialogicChannelManager::detectDevices() " <<
  360                   srlBoard->szDevName <<
  361                   " " << srlChannel->szDevName <<
  362                   " " << dev_type );
  363         }
  364       }
  365 
  366       delete[] srlChannels;
  367     }
  368 
  369     LOGINFO("DialogicChannelManager::detectDevices() Physical Board No:" <<
  370             indxPhys << " has " <<
  371             deviceConfig_.dti.size() << " Dti channels, " <<
  372             deviceConfig_.ipm.size() << " Ipm channels." <<
  373             deviceConfig_.vox.size() << " Vox channels");
  374 
  375     delete[] srlBoards;
  376   }
  377 
  378   delete[] auids;
  379   return true;
  380 }
  381 
  382 
  383 /*
  384  * Write the device configuration in 'ini file' format to the specified file or
  385  * to std::cout. The latter case is provided to allow shell redirection.
  386  */
  387 void DialogicChannelManager::saveConf( const std::string& conf )
  388 {
  389   std::ostream* out = &std::cout;
  390   std::ofstream fout;
  391   if ( !conf.empty() )
  392   {
  393     fout.open(conf.c_str());
  394     out = &fout;
  395   }
  396 
  397   *out << "; Dialogic Woomera Server - Device Configuration" << std::endl;
  398   time_t now = time(0);
  399   *out << "; Generated: " << ctime(&now) << std::endl;
  400 
  401   std::vector<DtiConfig>::const_iterator i;
  402 
  403   *out << std::endl;
  404   *out << "; The following section is used to define dti (isdn) devices."  << std::endl;
  405   *out << "; Each definition consists of a unique integer identifier and the device's name." << std::endl;
  406   *out << "; e.g. 1 = dtiB1T1" << std::endl;
  407   *out << "[dti]" << std::endl;
  408 
  409   for ( i = deviceConfig_.dti.begin(); i != deviceConfig_.dti.end(); ++i )
  410   {
  411     *out << (*i).id << " = " << (*i).name << std::endl;
  412   }
  413 
  414   std::vector<std::string>::const_iterator j;
  415 
  416   int index = 1;
  417   *out << std::endl;
  418   *out << "; The following section is used to define vox (voice resource) devices."  << std::endl;
  419   *out << "; Each definition consists of a unique integer identifier and the device's name." << std::endl;
  420   *out << "; e.g. 1 = dxxxB1C1" << std::endl;
  421   *out << std::endl << "[vox]" << std::endl;
  422   for ( j = deviceConfig_.vox.begin(); j != deviceConfig_.vox.end(); ++j )
  423   {
  424     *out << index++ << " = " << *j << std::endl;
  425   }
  426 
  427   index = 1;
  428   *out << std::endl;
  429   *out << "; The following section is used to define ipm devices."  << std::endl;
  430   *out << "; Each definition consists of a unique integer identifier and the device's name." << std::endl;
  431   *out << "; e.g. 1 = ipmB1C1" << std::endl;
  432   *out << std::endl << "[ipm]" << std::endl;
  433   for ( j = deviceConfig_.ipm.begin(); j != deviceConfig_.ipm.end(); ++j )
  434   {
  435     *out << index++ << " = " << *j << std::endl;
  436   }
  437 
  438   *out << std::endl;
  439   *out << "; The following section is used to define groups of dti (isdn) devices."  << std::endl;
  440   *out << "; These groups are used when allocating a device for an outbound call." << std::endl;
  441   *out << "; Each definition consists of the group's name followed by a comma separated " << std::endl;
  442   *out << "; list of dti device numbers, which may include ranges defined using a hyphen" << std::endl;
  443   *out << "; e.g. pbxlines = 1,2,3,4,31-60" << std::endl;
  444 
  445   *out << std::endl << "[groups]" << std::endl;
  446   *out << "default = 1-" << deviceConfig_.dti.size() << std::endl;
  447 
  448   *out << std::endl << "; End " << std::endl;
  449 }
  450 
  451 
  452 /*
  453  * Read device and group configurations from a conf file.
  454  */
  455 bool DialogicChannelManager::loadConf( const std::string& conf )
  456 {
  457   IniFile ini;
  458   if ( !ini.load(conf) )
  459   {
  460     LOGERROR("DialogicChannelManager::loadConf() Failed to open: " << conf);
  461     return false;
  462   }
  463 
  464   std::map<std::string, std::string> data;
  465   std::map<std::string, std::string>::const_iterator i;
  466 
  467   ini.getSection("dti", data);
  468   for ( i = data.begin(); i != data.end(); ++i )
  469   {
  470     int id = atoi((*i).first.c_str());  /* should be 1..n */
  471     if ( id == 0 )
  472     {
  473       LOGDEBUG("Bad dti device id " << (*i).first << " = " << (*i).second);
  474     }
  475     else
  476     {
  477       deviceConfig_.dti.push_back(DtiConfig((*i).second, id));
  478     }
  479   }
  480 
  481   data.clear();
  482   ini.getSection("ipm", data);
  483   for ( i = data.begin(); i != data.end(); ++i )
  484   {
  485     deviceConfig_.ipm.push_back((*i).second);
  486   }
  487 
  488   data.clear();
  489   ini.getSection("vox", data);
  490   for ( i = data.begin(); i != data.end(); ++i )
  491   {
  492     deviceConfig_.vox.push_back((*i).second);
  493   }
  494 
  495   data.clear();
  496   ini.getSection("groups", data);
  497   for ( i = data.begin(); i != data.end(); ++i )
  498   {
  499     /* create the group
  500      */
  501     GroupManager<GcIsdnDevice>::Group* grp = gcGroups_.add((*i).first);
  502 
  503     std::stringstream ss;  /* debug */
  504     ss << "Group: " << (*i).first << " Members: ";
  505 
  506     /* set group membership based on the order the devices are defined.
  507      */
  508     int pos = 1;
  509 
  510     std::vector<std::string> ranges;
  511     tokenise((*i).second, ranges, ',');
  512 
  513     std::vector<std::string>::const_iterator i;
  514     for ( i = ranges.begin(); i != ranges.end(); ++i )
  515     {
  516       std::vector<std::string> limits;
  517       tokenise(*i, limits, '-');
  518 
  519       int first = 0;
  520       int last = 0;
  521 
  522       if ( limits.size() == 1 )
  523       {
  524         first = last = atoi(limits[0].c_str());
  525       }
  526       if ( limits.size() == 2 )
  527       {
  528         first = atoi(limits[0].c_str());
  529         last = atoi(limits[1].c_str());
  530       }
  531 
  532       if ( (first > 0) && (last > 0) )
  533       {
  534         for ( int n = first; n <= last; n++ )
  535         {
  536           std::vector<DtiConfig>::iterator j;
  537           for ( j = deviceConfig_.dti.begin(); j != deviceConfig_.dti.end(); ++j )
  538           {
  539             if ( (*j).id == n )
  540             {
  541               ss << n << ", ";
  542               (*j).groups.push_back(DtiConfig::group_membership_t(grp, pos++));
  543               break;
  544             }
  545           }
  546         }
  547       }
  548 
  549       limits.clear();
  550       LOGDEBUG("DialogicChannelManager::loadConf() " << ss.str());
  551     }
  552   }
  553   return true;
  554 }
  555 
  556 
  557 /*
  558  * Create device objects and open their devices.
  559  * Abort immediately if a device fails to open.
  560  */
  561 bool DialogicChannelManager::openDevices()
  562 {
  563   std::vector<DtiConfig>::const_iterator i;
  564   for ( i = deviceConfig_.dti.begin(); i != deviceConfig_.dti.end(); ++i )
  565   {
  566     GcIsdnDevice* gcdev = new GcIsdnDevice((*i).name, *this);
  567     if ( gcdev->open() )
  568     {
  569       deviceMap_.insert(device_map_t::value_type((*i).name, gcdev));
  570 
  571       /* add the device to all of its groups.
  572        */
  573       std::vector<DtiConfig::group_membership_t>::const_iterator j;
  574       for ( j = (*i).groups.begin(); j != (*i).groups.end(); ++j )
  575       {
  576         (*j).first->add(gcdev, (*j).second);
  577       }
  578     }
  579     else
  580     {
  581       delete gcdev;
  582       return false;
  583     }
  584   }
  585 
  586   std::vector<std::string>::const_iterator j;
  587   for ( j = deviceConfig_.vox.begin(); j != deviceConfig_.vox.end(); ++j )
  588   {
  589     VoxDevice* voxdev = new VoxDevice(*j, *this);
  590     if ( voxdev->open() )
  591     {
  592       deviceMap_.insert(device_map_t::value_type(*j, voxdev));
  593       voxDevices_.push(voxdev);
  594     }
  595     else
  596     {
  597       delete voxdev;
  598       return false;
  599     }
  600   }
  601 
  602   for ( j = deviceConfig_.ipm.begin(); j != deviceConfig_.ipm.end(); ++j )
  603   {
  604     IpmDevice* ipmdev = new IpmDevice(*j, *this);
  605     if ( ipmdev->open() )
  606     {
  607       deviceMap_.insert(device_map_t::value_type(*j, ipmdev));
  608       ipmDevices_.push(ipmdev);
  609     }
  610     else
  611     {
  612       delete ipmdev;
  613       return false;
  614     }
  615   }
  616 
  617   LOGINFO("DialogicChannelManager::openDevices() dti: " << deviceConfig_.dti.size() <<
  618           ", ipm: " << deviceConfig_.ipm.size() << ", vox: " << deviceConfig_.vox.size());
  619   return true;
  620 }
  621 
  622 
  623 /*
  624  * Close all devices in the deviceMap_
  625  */
  626 void DialogicChannelManager::closeDevices()
  627 {
  628   device_map_t::iterator i;
  629 
  630   for ( i = deviceMap_.begin(); i != deviceMap_.end(); ++i )
  631   {
  632     LOGDEBUG("DialogicChannelManager::closeDevices() Closing device: " << (*i).first);
  633     (*i).second->close();
  634   }
  635 }
  636 
  637 
  638 /*
  639  * Lookup the device and pass it the event.
  640  */
  641 int DialogicChannelManager::dispatchEvent( METAEVENT& event )
  642 {
  643   char* atdv_name = ATDV_NAMEP(event.evtdev);
  644   if ( atdv_name )
  645   {
  646     device_map_t::const_iterator i = deviceMap_.find(atdv_name);
  647     if ( i != deviceMap_.end() )
  648     {
  649       DialogicDevice* device = (*i).second;
  650       if ( device )
  651       {
  652         return device->processEvent(event);
  653       }
  654     }
  655   }
  656   return 0;
  657 }
  658 
  659 
  660 /*
  661  * Create the channel using a GC device allocated from a specific group.
  662  */
  663 DialogicChannel* DialogicChannelManager::createChannel( const std::string& group )
  664 {
  665   LOGDEBUG("DialogicChannelManager::createChannel() using group: " << group);
  666 
  667   GroupManager<GcIsdnDevice>::Group* grp = gcGroups_.find(group);
  668   if ( !grp )
  669   {
  670     LOGERROR("Unknown group: \"" << group << "\"");
  671     return 0;
  672   }
  673 
  674   if ( grp->empty() )
  675   {
  676     LOGWARN("Unable to create channel, no free GC device available");
  677     return 0;
  678   }
  679 
  680   GcIsdnDevice* gc = grp->get();
  681   DialogicChannel* channel = createChannel(gc);
  682 
  683   if ( !channel ) /* failed, put back in group */
  684   {
  685     std::vector<DtiConfig>::const_iterator i;
  686     for ( i = deviceConfig_.dti.begin(); i != deviceConfig_.dti.end(); ++i )
  687     {
  688       if ( (*i).name == gc->getDeviceName() )
  689       {
  690         std::vector<DtiConfig::group_membership_t>::const_iterator j;
  691         for ( j = (*i).groups.begin(); j != (*i).groups.end(); ++j )
  692         {
  693           if ( (*j).first == grp )
  694           {
  695             grp->add(gc, (*j).second);
  696             break;
  697           }
  698         }
  699         break;
  700       }
  701     }
  702   }
  703 
  704   return channel;
  705 }
  706 
  707 
  708 /*
  709  * Create the channel using a specific GC device.
  710  */
  711 DialogicChannel* DialogicChannelManager::createChannel( GcIsdnDevice* gc )
  712 {
  713   LOGDEBUG("DialogicChannelManager::createChannel() using device: " << gc->getDeviceName());
  714 
  715   if ( ipmDevices_.empty() )
  716   {
  717     LOGERROR("Unable to create channel, no free IPM device available");
  718     return 0;
  719   }
  720   if ( voxDevices_.empty() )
  721   {
  722     LOGERROR("Unable to create channel, no free VOX device available");
  723     return 0;
  724   }
  725 
  726   IpmDevice* ipm = ipmDevices_.front();
  727   ipmDevices_.pop();
  728 
  729   VoxDevice* vox = voxDevices_.front();
  730   voxDevices_.pop();
  731 
  732   /* remove gc from all groups */
  733   std::vector<DtiConfig>::const_iterator i;
  734   for ( i = deviceConfig_.dti.begin(); i != deviceConfig_.dti.end(); ++i )
  735   {
  736     if ( (*i).name == gc->getDeviceName() )
  737     {
  738       std::vector<DtiConfig::group_membership_t>::const_iterator j;
  739       for ( j = (*i).groups.begin(); j != (*i).groups.end(); ++j )
  740       {
  741         (*j).first->remove(gc);
  742       }
  743     }
  744   }
  745 
  746   gc->attachVox(vox);
  747   vox->listen(gc);
  748 
  749   DialogicChannel* channel = new DialogicChannel(gc, ipm, vox);
  750   channels_.push_back(channel);
  751 
  752   LOGINFO("DialogicChannelManager::createChannel() " <<
  753           std::hex << channel <<
  754           " gc: " << gc->getDeviceName() <<
  755           " ipm: " << ipm->getDeviceName() <<
  756           " vox: " << vox->getDeviceName());
  757 
  758   total_++;
  759   LOGINFO("Active channels: " << channels_.size() << ", total: " << total_);
  760   return channel;
  761 }
  762 
  763 
  764 /*
  765  * Free the channel's devices and delete the channel object.
  766  */
  767 void DialogicChannelManager::destroyChannel( DialogicChannel* channel )
  768 {
  769   LOGINFO("DialogicChannelManager::destroyChannel() " << std::hex << channel);
  770 
  771   if ( !channel )
  772   {
  773     return;
  774   }
  775 
  776   GcIsdnDevice* gc = channel->getGcDevice();
  777   if ( gc )
  778   {
  779     gc->detachVox();
  780     VoxDevice* vox = channel->getVoxDevice();
  781     if ( vox )
  782     {
  783       vox->unListen();
  784       voxDevices_.push(vox);
  785     }
  786 
  787     /* return the gc device to its groups
  788      */
  789     std::vector<DtiConfig>::const_iterator i;
  790     for ( i = deviceConfig_.dti.begin(); i != deviceConfig_.dti.end(); ++i )
  791     {
  792       if ( (*i).name == gc->getDeviceName() )
  793       {
  794         std::vector<DtiConfig::group_membership_t>::const_iterator j;
  795         for ( j = (*i).groups.begin(); j != (*i).groups.end(); ++j )
  796         {
  797           (*j).first->add(gc, (*j).second);
  798         }
  799         break;
  800       }
  801     }
  802   }
  803 
  804   IpmDevice* ipm = channel->getIpmDevice();
  805   if ( ipm )
  806   {
  807     ipmDevices_.push(ipm);
  808   }
  809 
  810   channel_t::iterator i;
  811   for ( i = channels_.begin(); i != channels_.end(); ++i )
  812   {
  813     if ( *i == channel )
  814     {
  815       channels_.erase(i);
  816       break;
  817     }
  818   }
  819   delete channel;
  820 
  821   LOGINFO("Active channels: " << channels_.size() << ", total: " << total_);
  822 }
  823 
  824 
  825 /*
  826  * Linear search of the channels_ array.
  827  */
  828 DialogicChannel* DialogicChannelManager::findChannel( IpmDevice* ipm ) const
  829 {
  830   channel_t::const_iterator i;
  831   for ( i = channels_.begin(); i != channels_.end(); ++i )
  832   {
  833     DialogicChannel* channel = *i;
  834     if ( channel && (channel->getIpmDevice() == ipm) )
  835     {
  836       return channel;
  837     }
  838   }
  839   return 0;
  840 }
  841 
  842 
  843 /*
  844  * Linear search of the channels_ array.
  845  */
  846 DialogicChannel* DialogicChannelManager::findChannel( GcIsdnDevice* gc ) const
  847 {
  848   channel_t::const_iterator i;
  849   for ( i = channels_.begin(); i != channels_.end(); ++i )
  850   {
  851     DialogicChannel* channel = *i;
  852     if ( channel && (channel->getGcDevice() == gc) )
  853     {
  854       return channel;
  855     }
  856   }
  857   return 0;
  858 }
  859 
  860 
  861 /*
  862  * Linear search of the channels_ array.
  863  */
  864 DialogicChannel* DialogicChannelManager::findChannel( VoxDevice* vox ) const
  865 {
  866   channel_t::const_iterator i;
  867   for ( i = channels_.begin(); i != channels_.end(); ++i )
  868   {
  869     DialogicChannel* channel = *i;
  870     if ( channel && (channel->getVoxDevice() == vox) )
  871     {
  872       return channel;
  873     }
  874   }
  875   return 0;
  876 }
  877 
  878 
  879 /* vim:ts=4:set nu:
  880  * EOF
  881  */

No admin address has been configured
ViewVC Help
Powered by ViewVC 1.0.8