Parent Directory
|
Revision Log
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 |