Logo Search packages:      
Sourcecode: bayonne version File versions  Download package

dso.cpp

// Copyright (C) 2000-2001 Open Source Telecom Corporation.
//  
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software 
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

#include "server.h"
#include "ivrconfig.h"

#ifdef      CCXX_NAMESPACES
namespace ost {
using namespace std;
#endif

Server *Server::first = NULL;
Audit *Audit::first = NULL;
Auditdata Audit::keys;
Translator *Translator::first = NULL;
TGI *TGI::first = NULL;
Module *Module::modFirst = NULL;
Module *Module::sesFirst = NULL;
Module *Module::cmdFirst = NULL;
Module *Module::urlFirst = NULL;
Module *Module::reqFirst = NULL;
Module *Module::netFirst = NULL;
Module *Module::symFirst = NULL;
Module *Module::modImport = NULL;
Sync *Sync::first = NULL;

Auditdata::Auditdata()
{
      load("/bayonne/audit");
      load("~bayonne/audit");
}

00046 Audit::Audit() :
Mutex()
{
      next = first;
      first = this;
}

TTS::TTS()
{
      tts = this;
}

00058 Driver::Driver() :
aaScript()
{
      active = false;
      if(driver)
            throw(this);

      groups = NULL;
      driver = this;
      status = NULL;

      portCount = downCount = idleCount = 0;
      extCount = trkCount = tieCount = 0;
      numCount = 0;

      extIndex = NULL;

      memset(spans, 0, sizeof(spans));
      memset(cards, 0, sizeof(cards));
      memset(stacards, 0, sizeof(cards));
}

00080 bool Driver::setExtNumbering(unsigned count)
{
      unsigned port;
      Trunk *trk;
      if(extIndex)
      {
            for(port = 0; port < (unsigned)getTrunkCount(); ++port)
            {
                  trk = getTrunkPort(port);
                  if(trk)
                        trk->extNumber[0] = 0;
            }

            delete extIndex;
      }

      extIndex = NULL;
      numCount = 0;

      if(!extCount)
            return false;

      switch(count)
      {
      case 0:
            slog(Slog::levelInfo) << "server: clearing station dialing" << endl;
            getImage();
            return true;
      case 1:
            numCount = 1;
            count = 8;
            break;
      case 2:
            numCount = 2;
            count = 60;
            break;
      case 3:
            numCount = 3;
            count = 600;
            break;
      default:
            slog(Slog::levelError) << "server: invalid station dialing plan" << endl;
            numCount = 0;
            return false;
      }

      slog(Slog::levelInfo) << "server: setting " << numCount << " digit station dialing" << endl;

      extIndex = new Trunk *[count];
      memset(extIndex, 0, sizeof(Trunk *) * count);
      getImage();
      return true;
}

00134 Trunk **Driver::getExtIndex(const char *num)
{
      unsigned ext = atoi(num);

      if(!numCount)
            return NULL;

      if(strlen(num) != numCount)
            return NULL;

      switch(numCount)
      {
      case 1:
            if(ext > 9 && ext < 18)
                  ext -= 10;

            if(ext > 7)
                  return NULL;

            break;
      case 2:
            if(!ext)
                  ext = 10;
            if(ext < 10 || ext > 69)
                  return NULL;
            ext -= 10;
            break;
      case 3:
            if(!ext)
                  ext = 100;
            if(ext < 100 || ext > 699)
                  return NULL;
            ext -= 100;
            break;
      }
      return extIndex + ext;
}

00172 Trunk *Driver::getExtNumber(const char *num)
{
      Trunk *trunk;
      Trunk **idx;
      const char *cp;
      
      if(!num)
            return NULL;

      cp = strchr(num, '-');
      if(cp)
      {
            trunk = driver->getTrunkPort(atoi(++cp));
            if(!trunk)
                  return NULL;

            if(!trunk->extNumber[0])
                  return NULL;

            num = trunk->extNumber;       
      }

      idx = getExtIndex(num);

      if(!idx)
            return NULL;

      return *idx;
}

00202 bool Driver::clrExtNumber(const char *num)
{
      char namebuf[16];
      Trunk **idx = getExtIndex(num);
      Script::Symbol *sym;
      ScriptSymbol *globals = Trunk::getGlobals();

      if(!idx)
            return false;

      if(*idx)
      {
            (*idx)->getName(namebuf);
            slog(Slog::levelDebug) << namebuf << ": clearing from extension " << num << endl;
            if(!stricmp( (*idx)->extNumber, num))
                  (*idx)->extNumber[0] = 0;
            snprintf(namebuf, sizeof(namebuf), "%s.type", num);
            sym = globals->getEntry(namebuf, 0);
            if(sym)
                  snprintf(sym->data, sym->flags.size + 1, "user");
            snprintf(namebuf, sizeof(namebuf), "%s.port", num);
            sym = globals->getEntry(namebuf, 0);
            if(sym)
                  sym->data[0] = 0;
      }

      *idx = NULL;
      return true;
}

00232 bool Driver::setExtNumber(unsigned id, const char *ext)
{
      char namebuf[24];
      Trunk **idx = getExtIndex(ext);
      Trunk *trk = getTrunkPort(id);
      ScriptSymbol *globals = Trunk::getGlobals();
      Script::Symbol *def, *sym;

      if(!idx || ! trk || !(trk->getCapabilities() & TRUNK_CAP_STATION))
      {
            snprintf(namebuf, sizeof(namebuf), "%s.type", ext);
            sym = globals->getEntry(namebuf, 0);
            if(sym)
                  snprintf(sym->data, sym->flags.size + 1, "user");
            snprintf(namebuf, sizeof(namebuf), "%s.port", ext);
            sym = globals->getEntry(namebuf, 0);
            if(sym)
                  sym->data[0] = 0;
            return false;
      }

      if(*idx == trk)         // already is set to us, set type
      {

            if(!stricmp(trk->extNumber, ext))
                  return true;      // already station type

            snprintf(namebuf, sizeof(namebuf), "%s.type", trk->extNumber);
            sym = globals->getEntry(namebuf, 0);
            if(sym)
                  snprintf(sym->data, sym->flags.size + 1, "virtual");

            snprintf(namebuf, sizeof(namebuf), "%s.type", ext);
            sym = globals->getEntry(namebuf, 0);
            if(sym)
                  snprintf(sym->data, sym->flags.size + 1, "station");
            strcpy(trk->extNumber, ext);
            return true;
      }

      clrExtNumber(ext);

      trk->getName(namebuf);
      slog(Slog::levelDebug) << namebuf << ": assigning to extension " << ext << endl;
      strcpy(trk->extNumber, ext);
      snprintf(namebuf, sizeof(namebuf), "%s.password", ext);
      *idx = trk;

      def = globals->getEntry("default.password", 0);
      if(!def)
            return true;

      sym = globals->getEntry(namebuf, def->flags.size);
      if(!sym)
            return true;

      if(!sym->flags.readonly)
            strcpy(sym->data, "new");
      sym->flags.initial = false;
      sym->flags.readonly = true;

      def = globals->getEntry("default.type", 8);
      if(!def)
            return true;

      if(def->flags.initial)
            def->flags.initial = false;

      snprintf(namebuf, sizeof(namebuf), "%s.type", ext);
      sym = globals->getEntry(namebuf, def->flags.size);
      if(!sym)
            return true;

      snprintf(sym->data, sym->flags.size + 1, "%s", "station");
      sym->flags.initial = false;
      sym->flags.readonly = true;

      def = globals->getEntry("default.port", 3);
      if(!def)
            return true;

      if(def->flags.initial)
            def->flags.initial = false;

      snprintf(namebuf, sizeof(namebuf), "%s.port", ext);
      sym = globals->getEntry(namebuf, def->flags.size);
      if(!sym)
            return true;

      snprintf(sym->data, sym->flags.size + 1, "%d", id);
      sym->flags.initial = false;
      sym->flags.readonly = true;

      return true;
}

00328 bool Driver::setExtVirtual(unsigned id, const char *ext)
{
      char namebuf[24];
      Trunk **idx = getExtIndex(ext);
      Trunk *trk = getTrunkPort(id);
      ScriptSymbol *globals = Trunk::getGlobals();
      Script::Symbol *def, *sym;

      if(!idx || !trk)
      {
            snprintf(namebuf, sizeof(namebuf), "%s.type", ext);
            sym = globals->getEntry(namebuf, 0);
            if(sym)
                  snprintf(sym->data, sym->flags.size + 1, "user");
            snprintf(namebuf, sizeof(namebuf), "%s.port", ext);
            sym = globals->getEntry(namebuf, 0);
            if(sym)
                  sym->data[0] = 0;
            return false;
      }

      if(*idx == trk)         // already is set to us, set type
      {
            if(stricmp(trk->extNumber, ext))
                  return true;      // already virtual type

            trk->extNumber[0] = 0;
            snprintf(namebuf, sizeof(namebuf), "%s.type", ext);
            sym = globals->getEntry(namebuf, 0);
            if(sym)
                  snprintf(sym->data, sym->flags.size + 1, "virtual");
            return true;
      }

      clrExtNumber(ext);

      trk->getName(namebuf);
      slog(Slog::levelDebug) << namebuf << ": assigning virtual " << ext << endl;
      snprintf(namebuf, sizeof(namebuf), "%s.password", ext);
      *idx = trk;

      def = globals->getEntry("default.password", 0);
      if(!def)
            return true;

      sym = globals->getEntry(namebuf, def->flags.size);
      if(!sym)
            return true;

      if(!sym->flags.readonly)
            strcpy(sym->data, "new");

      sym->flags.initial = false;
      sym->flags.readonly = true;

      def = globals->getEntry("default.type", 8);
      if(!def)
            return true;

      if(def->flags.initial)
            def->flags.initial = false;

      snprintf(namebuf, sizeof(namebuf), "%s.type", ext);
      sym = globals->getEntry(namebuf, def->flags.size);
      if(!sym)
            return true;

      snprintf(sym->data, sym->flags.size + 1, "virtual");
      sym->flags.initial = false;
      sym->flags.readonly = true;

      def = globals->getEntry("default.port", 3);
      if(!def)
            return true;

      if(def->flags.initial)
            def->flags.initial = false;

      snprintf(namebuf, sizeof(namebuf), "%s.port", ext);
      sym = globals->getEntry(namebuf, def->flags.size);
      if(!sym)
            return true;

      snprintf(sym->data, sym->flags.size + 1, "%d", id);
      sym->flags.initial = false;
      sym->flags.readonly = true;

      return true;
}

00418 bool Driver::isIdle(void)
{
      if(portCount - idleCount)
            return false;

      return true;
}

00426 bool Driver::isDown(void)
{
      if(portCount - downCount)
            return false;

      return true;
}

00434 bool Driver::spanEvent(unsigned span, TrunkEvent *evt)
{
      unsigned port;
      unsigned rtn = false;
      Trunk *trunk;

      if(!span)
            return false;

      for(port = 0; port < (unsigned)getTrunkCount(); ++port)
      {
            TrunkEvent ev = *evt;
            trunk = getTrunkPort(port);
            if(!trunk)
                  continue;

            if(trunk->span != span)
                  continue;

            rtn = true;
            trunk->postEvent(&ev);
      }
      return rtn;
}
      
00459 aaImage *Driver::getImage(void)
{
      return new aaImage((aaScript *)this);
}

00464 Trunk *Driver::getTrunkId(const char *id)
{
      Trunk *trk, *ret;
      char *cp;

      if(!id)
            return NULL;

      cp = strchr(id, '-');
      if(!cp)
            return getTrunkPort(atoi(id));

      trk = ret = getTrunkPort(atoi(++cp));
      if(!trk)
            return NULL;

      trk->enterMutex();
      cp = trk->getSymbol(SYM_GID);
      if(!cp)
            cp = "";

      if(*id == '-')
            cp = strchr(cp, '-');
      if(!cp)
            cp = "";

      if(strcmp(cp, id))      
            ret = NULL;

      trk->leaveMutex();
      return ret;
}

00497 void Driver::secTick(void)
{
      unsigned id, max = getTrunkCount();
      Trunk *trunk;
      TrunkEvent event;
      time_t now;

      time(&now);

      for(id = 0; id < max; ++ id)
      {
            trunk = getTrunkPort(id);
            if(!trunk)
                  continue;

            if(!trunk->exittimer && !trunk->synctimer)
                  continue;

            if(now >= trunk->exittimer)
            {
                  event.id = TRUNK_TIMER_EXIT;
                  trunk->postEvent(&event);
                  trunk->exittimer = 0;
            }

            if(now >= trunk->synctimer)
            {
                  event.id = TRUNK_TIMER_SYNC;
                  trunk->postEvent(&event);
                  trunk->synctimer = 0;
            }
      }
}

00531 void Driver::setTrunkGroup(int id, int card, int span)
{
      if(id < 0 || id > getTrunkCount())
            slog(Slog::levelError) << "server: setTrumkGroup; invalid" << endl;

      TrunkGroup *grp = getTrunkGroup(id);
      if(grp != getGroup(NULL))
            return;

      if(!grp)
            return;

      if(spans[span])
            grp = spans[span];
      else if(cards[card])
            grp = cards[card];

      groups[id] = grp;
}

00551 int Driver::getTrunkMember(TrunkGroup *group, unsigned member)
{
      int id, count = getTrunkCount();
      Trunk *trunk;

      for(id = 0; id < count; ++id)
      {
            if(groups[id] != group)
                  continue;

            trunk = getTrunkPort(id);
            if(trunk->getMemberId() == member)
                  return id;
      }
      return -1;
}

00568 void Driver::getStatus(char *buffer)
{
      if(!status) {
            buffer[0] = 0;
            return;
      }
      memcpy(buffer, status, getTrunkCount());
}

void alog(Trunk *trunk, char *detail)
{
      Audit *au = Audit::first;

      while(au)
      {
            au->reportAudit(trunk, detail);
            au = au->next;
      }
}

void audit(Trunk *trunk, char *detail)
{
      Audit *au = Audit::first;

      while(au)
      {
            au->reportCDR(trunk, detail);
            au = au->next;
      }
}

00599 Debug::Debug() :
Mutex()
{
      if(debug)
            throw this;

      debug = this;
}

00608 Monitor::Monitor() :
Mutex()
{
      if(monitor)
            throw this;

      monitor = this;
}

Translator::Translator(const char *conf) :
Keydata(conf)
{
      char keypath[33];

      next = first;
      first = this;

      strcpy(keypath, conf);
      *keypath = '~';
      load(keypath);
}

00630 char *Translator::getPlayBuffer(Trunk *trunk)
{
      char *pbuf;
      
      pbuf = trunk->data.play.list;
      trunk->data.play.name = pbuf;
      trunk->data.play.limit = trunk->data.play.offset = 0;
      *pbuf = 0;
      return pbuf;
}

Translator *getTranslator(const char *name)
{
      Translator *trans = Translator::first;

      while(trans)
      {
            if(!stricmp(name, trans->getName()))
                  return trans;
            trans = trans->next;
      }
      return NULL;
}

00654 Sync::Sync()
{
      next = first;
      first = this;
      time(&runtime);
}

Server::Server(int pri) :
#ifdef      COMMON_OST_NAMESPACE
Thread(pri, keythreads.getStack())
#else
Thread(NULL, pri, keythreads.getStack())
#endif
{
      next = first;
      first = this;
}

void startServers(void)
{
      Server *server = Server::first;

      while(server)
      {
            server->start();
            server = server->next;
      }
}

void stopServers(void)
{
      Server *server = Server::first;

      while(server)
      {
            server->stop();
            server = server->next;
      }
}

TGI::TGI()
{
      next = first;
      first = this;
}

TGI *getInterp(char *cmd)
{
      TGI *tgi = TGI::first;
      char *ext;
      char buffer[512];
      strcpy(buffer, cmd);
      cmd = strtok_r(buffer, " \t\n", &ext);
      ext = strrchr(cmd, '.');
      
      while(tgi)
      {
            if(tgi->getExtension(ext))
                  return tgi;
            tgi = tgi->next;
      }
      return NULL;
}

void getInterp(char *cmd, char **args)
{
      TGI *tgi = TGI::first;

      while(tgi)
      {
            tgi->script(cmd, args);
            tgi = tgi->next;
      }
}

Module::Module()
{
      modNext = modFirst;
      modFirst = this;
      prior = NULL;
}

00736 void Module::addSymbols(void)
{
      symNext = symFirst;
      symFirst = this;
}

00742 void Module::addSession(void)
{
      sesNext = sesFirst;
      sesFirst = this;
}

00748 void Module::addNetwork(void)
{
      netNext = netFirst;
      netFirst = this;
}

00754 void Module::addRequest(void)
{
      reqNext = reqFirst;
      reqFirst = this;
}

00760 void Module::setThread(Trunk *trunk, Service *svc)
{
      if(trunk->thread)
            trunk->stopServices();
      trunk->thread = svc;
}

00767 void Module::addCommand(void)
{
      cmdNext = cmdFirst;
      cmdFirst = this;
}

00773 void Module::addPrompts(void)
{
      urlNext = urlFirst;
      urlFirst = this;
}

void detachModules(Trunk *trunk)
{
      Module *mod = Module::sesFirst;

      while(mod)
      {
            mod->detach(trunk);
            mod = mod->sesNext;
      }
}

void attachModules(Trunk *trunk)
{

      Module *mod = Module::sesFirst;

      while(mod)
      {
            mod->attach(trunk);
            mod = mod->sesNext;
      }
}

Module *getModule(modtype_t mtype, const char *name)
{
      Module *mod = Module::modFirst;

      while(mod)
      {
            if(mod->getType() == mtype || mtype == MODULE_ANY)
            {
                  if(!name)
                        return mod;

                  if(!stricmp(name, mod->getName()))
                        return mod;
            }
            mod = mod->modNext;
      }
      return NULL;
}

#ifdef  HAVE_EXECINFO_H

#include <execinfo.h>

void    Debug::stackTrace(int signo)
{
        const int maxTrace = 1000;
        void* buffer[maxTrace];
        int nTrace = backtrace ( buffer, maxTrace );
        char** trace = backtrace_symbols ( buffer, nTrace );

        slog(Slog::levelDebug) << "trace: pid=" << pthread_self()
                << " reason=" << signo << endl;


        if ( trace ) {
                for ( int i = 0; i < nTrace; ++i ) {
                slog(Slog::levelDebug) << "trace(" << i << "): "
                        << trace[i] << endl;
                }
        }
        // free memory
        free( trace );
}

#else
00847 void    Debug::stackTrace(int signo) {}
#endif


Debug *debug = NULL;
Monitor *monitor = NULL;
Driver *driver = NULL;
TTS *tts = NULL;

#ifdef      CCXX_NAMESPACES
};
#endif

Generated by  Doxygen 1.6.0   Back to index