"Fossies" - the Fresh Open Source Software Archive

Member "bayonne-1.2.16/drivers/dummy/driver.cpp" (15 Feb 2003, 8766 Bytes) of package /linux/misc/old/bayonne-1.2.16.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "driver.cpp" see the Fossies "Dox" file reference documentation.

    1 // Copyright (C) 2000 Open Source Telecom Corporation.
    2 //  
    3 // This program is free software; you can redistribute it and/or modify
    4 // it under the terms of the GNU General Public License as published by
    5 // the Free Software Foundation; either version 2 of the License, or
    6 // (at your option) any later version.
    7 // 
    8 // This program is distributed in the hope that it will be useful,
    9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
   10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   11 // GNU General Public License for more details.
   12 // 
   13 // You should have received a copy of the GNU General Public License
   14 // along with this program; if not, write to the Free Software 
   15 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
   16 
   17 #include "driver.h"
   18 
   19 #ifdef  CCXX_NAMESPACES
   20 namespace ost {
   21 using namespace std;
   22 #endif
   23 
   24 DummyConfig::DummyConfig() :
   25 Keydata("/bayonne/soundcard")
   26 {
   27     static Keydata::Define defkeys[] = {
   28     {"device", "/dev/dsp"},
   29     {"count", "1"},
   30     {"buffers", "8"},
   31     {"stack", "64"},
   32     {NULL, NULL}};
   33 
   34     if(isFHS())
   35         load("/drivers/soundcard");
   36 
   37     load(defkeys);
   38 }
   39 
   40 size_t DummyConfig::getStack(void)
   41 {
   42         const char *cp = getLast("stack");
   43 
   44         if(!cp)
   45                 return keythreads.getStack();
   46 
   47         return atoi(cp) * 1024;
   48 }
   49 
   50 const char *DummyConfig::getDevice(int ts)
   51 {
   52     char devname[16];
   53     const char *cp;
   54 
   55     snprintf(devname, 16, "device%d", ts);
   56     cp = getLast(devname);
   57     if(!cp)
   58         cp = getLast("device");
   59     return cp;
   60 }
   61 
   62 DummyDriver::DummyDriver() :
   63 Driver(), DummyConfig(), Thread(keythreads.priService(), dummyivr.getStack())
   64 {
   65     port_count = getDeviceCount();
   66 
   67     ports = new DummyTrunk *[port_count];
   68     groups = new TrunkGroup *[port_count];
   69 
   70     status = DummyTrunk::status;
   71     memset(status, '-', sizeof(DummyTrunk::status));
   72 
   73     if(ports)
   74         memset(ports, 0, sizeof(DummyTrunk *) * port_count);
   75 
   76     if(groups)
   77         memset(groups, 0, sizeof(TrunkGroup *) * port_count);
   78 
   79     slog(Slog::levelInfo) << "Generic Test (dummy) driver loaded; capacity=" << port_count << endl;
   80 }
   81 
   82 DummyDriver::~DummyDriver()
   83 {
   84     if(active)
   85         stop();
   86 
   87     if(ports)
   88         delete ports;
   89 
   90     if(groups)
   91         delete groups;
   92 }
   93 
   94 int DummyDriver::start(void)
   95 {
   96     int count = 0;
   97 
   98     if(active)
   99     {
  100         slog(Slog::levelError) << "driver already started" << endl;
  101         return 0;
  102     }
  103 
  104 
  105     for(count = 0; count < getDeviceCount(); ++count)
  106             ports[count] = new DummyTrunk(count);
  107 
  108     tcgetattr(0, &t);
  109     slog(Slog::levelInfo) << "driver starting..." << endl;
  110     Thread::start();
  111 
  112     active = true;
  113     return count;
  114 }
  115 
  116 void DummyDriver::stop(void)
  117 {
  118     unsigned count;
  119     DummyTrunk *trk;
  120     if(!active)
  121         return;
  122 
  123     terminate();
  124         tcsetattr(0, TCSANOW, &t);
  125 
  126     if(ports)
  127     {
  128         for(count = 0; count < (unsigned)getDeviceCount(); ++count)
  129         {
  130             trk = ports[count];
  131             if(trk)
  132                 delete trk;
  133         }
  134         memset(ports, 0, sizeof(DummyTrunk *) * port_count);
  135     }
  136 
  137     active = false;
  138     slog(Slog::levelInfo) << "driver stopping..." << endl;
  139 }
  140 
  141 void DummyDriver::run(void)
  142 {
  143     TrunkEvent event;
  144     timeout_t timeout;
  145     pollfd pfd[1];
  146     char ch;
  147     struct termios n;
  148     DummyTrunk *trunk;
  149     int port = 0;
  150     char name[16];
  151 
  152     setCancel(cancelImmediate);
  153     slog(Slog::levelNotice) << "dummy: start thread" << endl;\
  154 
  155     pfd[0].fd = 0;
  156     
  157         tcgetattr(0, &t);
  158         tcgetattr(0, &n);
  159         n.c_lflag &= ~(ECHO|ICANON);
  160         tcsetattr(0, TCSANOW, &n);
  161 
  162     for(;;)
  163     {
  164         Thread::yield();
  165         trunk = ports[port];
  166         if(!trunk)
  167         {
  168             slog(Slog::levelError) << "dummy: missing trunk" << endl;
  169             sleep(1000);
  170             continue;
  171         }
  172 
  173         snprintf(name, sizeof(name), "dummy%d", port);
  174         
  175         trunk->enterMutex();
  176         timeout = trunk->getTimer();
  177         if(!timeout)
  178         {
  179             trunk->endTimer();
  180             event.id = TRUNK_TIMER_EXPIRED;
  181             trunk->postEvent(&event);
  182         }
  183         trunk->leaveMutex();
  184 
  185         if(timeout > 500)
  186             timeout = 500;
  187 
  188                 pfd[0].events = POLLIN | POLLRDNORM;
  189                 pfd[0].revents = 0;
  190 
  191                 if(poll(pfd, 1, timeout) > 0)
  192         {
  193             ::read(0, &ch, 1);
  194                         switch(ch)
  195                         {
  196                         case '#':
  197                                 slog(Slog::levelDebug) << name
  198                                         << ": digit #..." << endl;
  199                                 event.id = TRUNK_DTMF_KEYUP;
  200                                 event.parm.dtmf.digit = 11;
  201                                 event.parm.dtmf.duration = 60;
  202                                 trunk->postEvent(&event);
  203                                 sleep(10);
  204                                 break;
  205                         case '*':
  206                                 slog(Slog::levelDebug) << name
  207                                         << ": digit *..." << endl;
  208                                 event.id = TRUNK_DTMF_KEYUP;
  209                                 event.parm.dtmf.digit = 10;
  210                                 event.parm.dtmf.duration = 60;
  211                                 trunk->postEvent(&event);
  212                                 sleep(10);
  213                                 break;
  214                         case '0':
  215                         case '1':
  216                         case '2':
  217                         case '3':
  218                         case '4':
  219                         case '5':
  220                         case '6':
  221                         case '7':
  222                         case '8':
  223                         case '9':
  224                                 slog(Slog::levelDebug) << name
  225                                         << ": digit " << ch << "..." << endl;
  226                                 event.id = TRUNK_DTMF_KEYUP;
  227                                 event.parm.dtmf.digit = ch - '0';
  228                                 event.parm.dtmf.duration = 60;
  229                                 trunk->postEvent(&event);
  230                                 sleep(10);
  231                                 break;
  232                         case 'r':
  233                         case 'R':
  234                                 slog(Slog::levelDebug) << name
  235                                         << ": ringing..." << endl;
  236                                 event.id = TRUNK_RINGING_ON;
  237                                 event.parm.ring.digit = 0;
  238                                 event.parm.ring.duration = 50;
  239                                 trunk->postEvent(&event);
  240                                 sleep(100);
  241                                 event.id = TRUNK_RINGING_OFF;
  242                                 trunk->postEvent(&event);
  243                                 break;
  244             case 'n':
  245             case 'N':
  246                 if(++port >= getTrunkCount())
  247                     port = 0;
  248                 break;
  249                         case 'D':
  250                         case 'd':
  251                                 slog(Slog::levelDebug) << name
  252                                         << ": dialtone..." << endl;
  253                                 event.id = TRUNK_CPA_DIALTONE;
  254                                 trunk->postEvent(&event);
  255                                 break;
  256                         case 'B':
  257                         case 'b':
  258                                 slog(Slog::levelDebug) << name
  259                                         << ": busytone..." << endl;
  260                                 event.id = TRUNK_CPA_BUSYTONE;
  261                                 trunk->postEvent(&event);
  262                                 break;
  263                         case ' ':
  264                                 slog(Slog::levelDebug) << name
  265                                         << ": step/start..." << endl;
  266                                 event.id = TRUNK_NULL_EVENT;
  267                                 trunk->postEvent(&event);
  268                                 break;
  269                         case 'H':
  270                         case 'h':
  271                                 slog(Slog::levelDebug) << name
  272                                         << ": hangup..." << endl;
  273                                 event.id = TRUNK_STOP_DISCONNECT;
  274                                 trunk->postEvent(&event);
  275                                 break;
  276                         case 'i':
  277                         case 'I':
  278                                 slog(Slog::levelDebug) << name
  279                                         << ": idle..." << endl;
  280                                 event.id = TRUNK_MAKE_IDLE;
  281                                 trunk->postEvent(&event);
  282                                 break;
  283                         case 'X':
  284                         case 'x':
  285                         case 3:
  286                                 slog(Slog::levelDebug) << name
  287                                         << ": exiting..." << endl;
  288                                 raise(SIGINT);
  289             }
  290         }
  291     }
  292 }
  293     
  294 Trunk *DummyDriver::getTrunkPort(int id)
  295 {
  296     if(id < 0 || id >= port_count)
  297         return NULL;
  298 
  299     if(!ports)
  300         return NULL;
  301 
  302     return (Trunk *)ports[id];
  303 }
  304 
  305 DummyDriver dummyivr;
  306 
  307 #ifdef  CCXX_NAMESPACES
  308 };
  309 #endif