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

fifo.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 <cc++/strchar.h>

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

Fifo fifo;

static Trunk *getTrunk(char *str)
{
      if(!str)
            return NULL;

      return driver->getTrunkId(str);
}

bool Fifo::sendEvent(char **argv)
{
        TrunkEvent event;
        Trunk *trunk = getTrunk(argv[1]);
        
        if (!trunk) return(false);
        
        event.id = TRUNK_SEND_MESSAGE;
        event.parm.send.src = NULL;
        if (argv[2]) 
            event.parm.send.msg = argv[2];
        else 
            event.parm.send.msg = "";

        trunk->postEvent(&event);
}


bool Fifo::clearRDGroup(char **argv)
{
      const char *members = argv[3];
      unsigned port;
      Trunk *trunk;
      unsigned dig;

      if(!members)
            return false;

      while(*members)
      {
            if(!isdigit(*members))
            {
                  ++members;
                  continue;
            }
            dig = *(members++) - '0';

            port = driver->getTrunkCount();
            while(port--)
            {
                  trunk = driver->getTrunkPort(port);
                  if(!trunk)
                        continue;

                  trunk->dialgroup[dig] = false;
            }
      }
      return true;
}

bool Fifo::clearRing(char **argv)
{
      Trunk *trunk;
      char *members;
      unsigned dig;

      if(!argv[2])
            return false;

      if(!stricmp(argv[2], "group"))
            return clearRDGroup(argv);

      trunk = driver->getExtNumber(argv[2]);
      if(!trunk)
            return false;

      members = argv[3];
      if(!members)
            members = "0123456789";

      while(*members)
      {
            if(!isdigit(*members))
            {
                  ++members;
                  continue;
            }
            dig = *(members++) - '0';
            trunk->dialgroup[dig] = false;
      }     
}

bool Fifo::clearDial(char **argv)
{
        Trunk *trunk;
        char *members;
        unsigned dig;

        if(!argv[2])
                return false;

        if(!stricmp(argv[2], "group"))
                return clearRDGroup(argv);

        trunk = driver->getTrkNumber(argv[2]);
        if(!trunk)
                return false;

        members = argv[3];
        if(!members)
                members = "0123456789";

        while(*members)
        {
                if(!isdigit(*members))
                {
                        ++members;
                        continue;
                }
                dig = *(members++) - '0';
                trunk->dialgroup[dig] = false;
        }
}

bool Fifo::assignRing(char **argv)
{
        Trunk *trunk;
        char *members;
        unsigned dig;

        if(!argv[2])
                return false;

        trunk = driver->getExtNumber(argv[2]);
        if(!trunk)
                return false;

        members = argv[3];
        if(!members)
                members = "0123456789";

        while(*members)
        {
                if(!isdigit(*members))
                {
                        ++members;
                        continue;
                }
                dig = *(members++) - '0';
                trunk->dialgroup[dig] = true;
        }
}

bool Fifo::assignDial(char **argv)
{
        Trunk *trunk;
        char *members;
        unsigned dig;

        if(!argv[2])
                return false;

        trunk = driver->getTrkNumber(argv[2]);
        if(!trunk)
                return false;

        members = argv[3];
        if(!members)
                members = "0123456789";

        while(*members)
        {
                if(!isdigit(*members))
                {
                        ++members;
                        continue;
                }
                dig = *(members++) - '0';
                trunk->dialgroup[dig] = true;
        }
}

bool Fifo::waitPid(char **argv)
{
      Trunk *trunk = getTrunk(argv[1]);
      if(!trunk)
            return false;

      if(!argv[2])
            return false;

      trunk->tgi.pid = atoi(argv[2]);
      return true;
}

bool Fifo::setSymbol(char **argv)
{
      Script::Symbol *sym;
      Trunk *trunk = getTrunk(argv[1]);
      bool rts;
      if(!trunk)
            return false;

      if(!argv[3] || !argv[2])
            return false;

      trunk->enterMutex();
      rts = trunk->setVariable(argv[2], 0, argv[3]);
      trunk->leaveMutex();
      return rts;
}

bool Fifo::deleteId(char **argv)
{
      size_t pcount = keymemory.getPrefCount();
      char *id;
      Symbol *idx[pcount], *sym;
      char prefix[65];
      char path[65];
      char name[65];
      ScriptSymbol *globals = Trunk::getGlobals();
      unsigned count, offset = 0;

      if(!argv[1])
            return false;

      if(!stricmp(argv[1], "hunt"))
      {
            id = argv[2];
            if(!id)
                  return false;

            snprintf(name, sizeof(name), "hunt.%s.id", id);
            sym = globals->getEntry(name, 0);
            if(!sym)
                  return true;

            sym->flags.initial = false;
            snprintf(name, sizeof(name), "hunting/%s", id);
            remove(name);
            return true;
      }

      if(stricmp(argv[1], "user"))
            return false;

      id = argv[2];
      if(!id)
            return false;

      if(!isUser(id))
            return false;

      if(!stricmp(id, "admin"))
            return false;

        snprintf(path, sizeof(path), "users/%s", id);
        remove(path);

      snprintf(prefix, sizeof(prefix), "%s.password", id);
      sym = globals->getEntry(prefix, 0);
      if(!sym)
            return false;
      
      if(sym->flags.initial)
            return false;

      snprintf(prefix, sizeof(prefix), "%s.", id);
      count = globals->gather(idx, pcount, prefix, NULL);
      if(!count)
            return false;

      while(offset < count)
            idx[offset++]->flags.initial = true;            

      return true;
}

bool Fifo::createId(char **argv)
{
      char *id;
      Symbol *sym, *def;
      char name[65];
      ScriptSymbol *globals = Trunk::getGlobals();

      if(!argv[1])
            return false;

      if(!stricmp(argv[1], "hunt"))
      {
            id = argv[2];
            if(!id)
                  return false;

            if(!stricmp(id, "default"))
                  return true;

            snprintf(name, sizeof(name), "hunt.%s.id", id);
            globals->setConst(name, id);
            sym = globals->getEntry(name, 0);
            if(!sym)
                  return true;

            sym->flags.initial = false;
            Trunk::savePref(id, "hunt", "hunting");
            return true;
      }

      if(stricmp(argv[1], "user"))
            return false;

      id = argv[2];
      if(!id)
            return false;

      if(!isUser(id))
            return false;

      def = globals->getEntry("default.password", 0);
      snprintf(name, sizeof(name), "%s.password", id);
      sym = globals->getEntry(name, def->flags.size);
      if(!sym)
            return false;

      if(!sym->flags.initial)
            return false;

      strcpy(sym->data, def->data);
      sym->flags.initial = false;
      sym->flags.readonly = true;

      Trunk::save(id);
      return true;
}
      
bool Fifo::saveId(char **argv)
{
      char *id;

      if(!argv[1])
            return false;

      if(!stricmp(argv[1], "line"))
      {
            id = argv[2];
            if(!id)
                  return false;

            Trunk::savePref(id, "line", "lines");
            return true;
      }

      if(stricmp(argv[1], "user"))
            return false;

      id = argv[2];
      if(!id)
            return false;

      if(!isUser(id))
            return false;

      Trunk::save(id);
      return true;
}

bool Fifo::reload(char **argv)
{
      Module *mod = Module::cmdFirst;
      int argc = 1;
      bool rts = true;
      const char *id;

      if(!argv[1])
      {
            while(mod)
            {
                  mod->reload();
                  mod = mod->cmdNext;
            }
            return true;
      }

      if(!stricmp(argv[1], "user"))
      {
            id = argv[2];
            if(!id)
                  return false;

            if(!isUser(id))
                  return false;

            Trunk::load(id);
            Trunk::save(id);
            return true;
      }

      if(!stricmp(argv[1], "line"))
      {
            id = argv[2];
            if(!id)
                  return false;

            Trunk::loadPref(id, "line", "lines");
            Trunk::savePref(id, "line", "lines");
            return true;
      }

      if(!stricmp(argv[1], "hunt"))
      {
            id = argv[2];
            if(!id)
                  return false;

            Trunk::loadPref(id, "hunt", "hunting");
            Trunk::savePref(id, "hunt", "hunting");
      }
      
      while(argv[argc])
      {
            mod = getModule(MODULE_FIFO, argv[argc++]);
            if(mod)
                  mod->reload();
            else
                  rts = false;
      }
      return rts;
}

bool Fifo::submit(char **argv)
{
      Trunk *trunk = getTrunk(argv[1]);
      char buffer[PIPE_BUF / 2];
      TrunkEvent event;
      int argc = 3;
      unsigned seq;
      unsigned len = 0;

      if(!trunk || !argv[2])
            return false;

      seq = atoi(argv[2]);
      while(argv[argc] && len < sizeof(buffer))
      {
            if(argc > 3)
                  buffer[len++] = '&';
            strncpy(buffer + len, argv[argc++], sizeof(buffer) - len);
            buffer[sizeof(buffer) - 1] = 0;
            len = strlen(buffer);
      }
      event.id = TRUNK_SERVICE_LOOKUP;
      event.parm.lookup.seq = seq;
      event.parm.lookup.result = true;
      event.parm.lookup.data = buffer;
      return trunk->postEvent(&event);
}

bool Fifo::setLimit(char **argv)
{
      Mixer *mixer = driver->getMixer(atoi(argv[1]));
      Conference *conf;
      int grp = 0;
      int argc = 2;
      bool rts = true;

      if(!mixer || !argv[2])
            return false;

      while(argv[argc] && rts)
      {
            conf = mixer->getConference(grp++);
            if(!conf)
                  return false;
            rts = conf->setConference(atoi(argv[argc++]));
      }
      return rts;
}

bool Fifo::setMixer(char **argv)
{
      Mixer *mixer = driver->getMixer(atoi(argv[1]));
      if(!mixer || !argv[2] || !argv[3])
            return false;

      return mixer->setMixer(atoi(argv[2]), atoi(argv[3]));
}

bool Fifo::testScript(char **argv)
{
      char *pass[2];
      Trunk *trunk;
      TrunkEvent event;

      if(!argv[1])
            return false;

      snprintf(service, sizeof(service), "test::%s", argv[1]);

      pass[0] = service;
      pass[1] = NULL;
      argv += 2;

      while(*argv)
      {
            trunk = driver->getTrkNumber(*argv);
            if(!trunk)
                  continue;

            event.id = TRUNK_RING_START;
            event.parm.argv = pass;
            trunk->postEvent(&event);
            ++argv;
      }
      return true;
}

bool Fifo::ringScript(char **argv)
{
      Trunk *trunk = getTrunk(argv[1]);
      TrunkEvent event;

//    if(!trunk || !argv[2])
//          return false;

      event.id = TRUNK_RING_START;
      event.parm.argv = &argv[2];

      return trunk->postEvent(&event);
}

bool Fifo::redirectScript(char **argv)
{
      Trunk *trunk = getTrunk(argv[1]);
      TrunkEvent event;

      if(!trunk || !argv[2])
            return false;

      event.id = TRUNK_RING_REDIRECT;
      event.parm.argv = &argv[2];

      return trunk->postEvent(&event);
}

bool Fifo::reqScript(char **argv)
{
      TrunkGroup *grp;
      char *exp = argv[1];
      
      if(!exp || !argv[2])
            return false;

      grp = getGroup(argv[2]);
      if(!grp || !argv[3])
            return false;

      request(grp, &argv[3], atoi(exp));
      return true;
}

bool Fifo::startScript(char **argv)
{
      Trunk *trunk = getTrunk(argv[1]);
      TrunkGroup *group = getGroup(argv[1]);    
      TrunkEvent event;
      int port = driver->getTrunkCount();
      
      if((!trunk && !group) || !argv[2])
            return false;

      if(trunk && !group)
      {
            event.id = TRUNK_START_SCRIPT;
            event.parm.argv = &argv[2];
            return trunk->postEvent(&event);
      }
      if(!group)
            return false;

      while(port--)
      {
            if(driver->getTrunkGroup(port) != group)
                  continue;

            trunk = driver->getTrunkPort(port);
            if(!trunk)
                  continue;

            event.id = TRUNK_START_SCRIPT;
            event.parm.argv = &argv[2];
            if(trunk->postEvent(&event))
                  return true;
      }
      return false;
}

bool Fifo::postKey(char **argv)
{
      Trunk *trunk = getTrunk(argv[1]);
      char *digits = argv[2];
      TrunkEvent event;
      bool rtn = true;

      if(!trunk || !argv[2])
            return false;

      while(digits && rtn)
      {
            event.id = TRUNK_DTMF_KEYUP;
            event.parm.dtmf.duration = 40;
            event.parm.dtmf.e1 = event.parm.dtmf.e2 = 0;
            switch(*digits)
            {
            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
                  event.parm.dtmf.digit = *digits - '0';
                  rtn = trunk->postEvent(&event);
                  break;
            case '*':
                  event.parm.dtmf.digit = 10;
                  rtn = trunk->postEvent(&event);
                  break;
            case '#':
                  event.parm.dtmf.digit = 11;
                  rtn = trunk->postEvent(&event);
                  break; 
            default:
                  rtn = false;
            }
            if(*(++digits))
                  Thread::sleep(60);
      }
      return rtn;
}

bool Fifo::exitPid(char **argv)
{
      Trunk *trunk = getTrunk(argv[1]);
      TrunkEvent event;

      if(!trunk)
            return false;

      event.id = TRUNK_EXIT_SHELL;
      if(argv[2])
            event.parm.status = atoi(argv[2]);
      else
            event.parm.status = 0;

      return trunk->postEvent(&event);
}

bool Fifo::hangupLine(char **argv)
{
      TrunkGroup *group = getGroup(argv[1]);
      Trunk *trunk = getTrunk(argv[1]);
      TrunkEvent event;
      int port;

      if(trunk && !group)
      {
            event.id = TRUNK_STOP_DISCONNECT;
            return trunk->postEvent(&event);
      }

      if(!group)
            return false;

      for(port = 0; port < driver->getTrunkCount(); ++port)
      {
            if(driver->getTrunkGroup(port) != group)
                  continue;

            trunk = driver->getTrunkPort(port);
            if(!trunk)
                  continue;

            event.id = TRUNK_STOP_DISCONNECT;
            trunk->postEvent(&event);
      }
      return true;
}

bool Fifo::busyLine(char **argv)
{
      TrunkGroup *group = getGroup(argv[1]);
      Trunk *trunk = getTrunk(argv[1]);
      TrunkEvent event;
      int port;

      if(trunk && !group)
      {
            event.id = TRUNK_MAKE_BUSY;
            return trunk->postEvent(&event);
      }
      if(!group)
            return false;

      for(port = 0; port < driver->getTrunkCount(); ++port)
      {
            if(driver->getTrunkGroup(port) != group)
                  continue;

            trunk = driver->getTrunkPort(port);
            if(!trunk)
                  continue;

            event.id = TRUNK_MAKE_BUSY;
            trunk->postEvent(&event);
      }
      return true;
}

bool Fifo::setSpan(char **argv)
{
      TrunkEvent event;
      unsigned span;

      const char *cspan = argv[1];
      const char *mode = argv[2];

      if(!cspan || !mode)
            return false;

      span = atoi(cspan);
      if(!stricmp(mode, "busy"))
            event.id = TRUNK_MAKE_BUSY;
      else if(!stricmp(mode, "idle") || !stricmp(mode, "up"))
            event.id = TRUNK_MAKE_IDLE;
      else if(!stricmp(mode, "stop") || !stricmp(mode, "down"))
            event.id = TRUNK_MAKE_STANDBY;
      else
            return false;

      return driver->spanEvent(span, &event);
}


bool Fifo::setCard(char **argv)
{
        TrunkEvent event;
        unsigned card;

        const char *ccard = argv[1];
        const char *mode = argv[2];

        if(!ccard || !mode)
                return false;

        card = atoi(ccard);
        if(!stricmp(mode, "busy"))
                event.id = TRUNK_MAKE_BUSY;
        else if(!stricmp(mode, "idle") || !stricmp(mode, "up"))
                event.id = TRUNK_MAKE_IDLE;
        else if(!stricmp(mode, "stop") || !stricmp(mode, "down"))
                event.id = TRUNK_MAKE_STANDBY;
        else
                return false;

        return driver->cardEvent(card, &event);
}

bool Fifo::idleLine(char **argv)
{
      TrunkGroup *group = getGroup(argv[1]);
      Trunk *trunk = getTrunk(argv[1]);
      TrunkEvent event;
      int port;

      if(trunk && !group)
      {
            event.id = TRUNK_MAKE_IDLE;
            return trunk->postEvent(&event);
      }

      if(!group)
            return false;

      for(port = 0; port < driver->getTrunkCount(); ++port)
      {
            if(driver->getTrunkGroup(port) != group)
                  continue;

            trunk = driver->getTrunkPort(port);
            if(!trunk)
                  continue;

            event.id = TRUNK_MAKE_IDLE;
            trunk->postEvent(&event);
      }
      return true;
}

bool Fifo::setSchedule(char **argv)
{
      if(argv[1])
      {
            strcpy(schedule, argv[1]);
            if(!stricmp(schedule, "*"))
                  scheduler.altSchedule(NULL);
            else
                  scheduler.altSchedule(schedule);
      }
      else
            scheduler.altSchedule(NULL);
      return true;
}
            
bool Fifo::command(const char *cmd, ostream *fd)
{
      Module *next;
      char buffer[PIPE_BUF / 2];
      bool rts = false;
      char *args[65];
      int argc = 0;
      char **argv = args;
      char *arg;
      char *sp;
      char *ptr;
      const char *token = keyserver.getToken();
      int tlen = strlen(token);

      if(!fd)
            fd = &slog;

      strncpy(buffer, cmd, sizeof(buffer) - 1);
      buffer[sizeof(buffer) - 1] = 0;

      enterMutex();
      slog(Slog::levelDebug) << "fifo: cmd=" << buffer << endl;
      if(strstr(buffer, token))
      {
            ptr = buffer;
            while(isspace(*ptr))
                  ++ptr;
      
            ptr = strtok_r(ptr, "\n", &sp);     
            while(NULL != (sp = strstr(ptr, token)))
            {
                  argv[argc++] = ptr;
                  *sp = 0;
                  ptr = sp + tlen;
            }
            while(isspace(*ptr))
                  ++ptr;
            if(*ptr)
                  argv[argc++] = ptr;
      }
      else
      {
            argv[argc++] = strtok_r(buffer, " \t\n\r", &sp);
            while(argc < 64)
            {
                  arg = strtok_r(NULL, " \t\n\r", &sp);
                  if(!arg)
                        break;
                  argv[argc++] = arg;
            }
      }
      argv[argc] = NULL;

      if(!argv[0])
      {
            leaveMutex();
            return false;
      }

      if(!*argv[0])
      {
            leaveMutex();
            return false;
      }

      next = Module::cmdFirst;

      while(next && !rts)
      {
            rts = next->command(argv, fd);
            next = next->cmdNext;
      }

      if(!stricmp(argv[0], "service"))
      {
            if(!argv[1])
            {
                  argv[0] = "-";
                  rts = false;
            }
            else if(!stricmp(argv[1], "up"))
                  argv[0] = "up";
      }

      if(!stricmp(argv[0], "down") || !stricmp(argv[0], "service"))
      {
            if(argv[1])
                  snprintf(service, sizeof(service), "down::%s", argv[1]);
            else
                  raise(SIGINT);
            rts = true;
      }
      else if(!stricmp(argv[0], "test"))
            rts = testScript(argv);
      else if(!stricmp(argv[0], "up"))
            service[0] = 0;
      else if(!stricmp(argv[0], "restart"))
      {
            restart_server = true;
            raise(SIGINT);
            rts = true;
      }
      else if(!stricmp(argv[0], "compile"))
      {
            driver->getImage();
            rts = true;
      }           
      else if(!stricmp(argv[0], "wait"))
            rts = waitPid(argv);
      else if(!stricmp(argv[0], "exit"))
            rts = exitPid(argv);
      else if(!stricmp(argv[0], "set"))
            rts = setSymbol(argv);
      else if(!stricmp(argv[0], "submit"))
            rts = submit(argv);
      else if(!stricmp(argv[0], "debug"))
            rts = debug->debugFifo(argv);
      else if(!stricmp(argv[0], "ring"))
            rts = ringScript(argv);
      else if(!stricmp(argv[0], "redirect"))
            rts = redirectScript(argv);
      else if(!stricmp(argv[0], "busy"))
            rts = busyLine(argv);
      else if(!stricmp(argv[0], "idle"))
            rts = idleLine(argv);
      else if(!stricmp(argv[0], "span"))
            rts = setSpan(argv);
      else if(!stricmp(argv[0], "card"))
            rts = setCard(argv);
      else if(!stricmp(argv[0], "start"))
            rts = startScript(argv);      
      else if(!stricmp(argv[0], "request"))
            rts = reqScript(argv);
      else if(!stricmp(argv[0], "disconnect") || !stricmp(argv[0], "hangup"))
            rts = hangupLine(argv);
      else if(!stricmp(argv[0], "post") || !stricmp(argv[0], "key"))
            rts = postKey(argv);
      else if(!stricmp(argv[0], "schedule"))
            rts = setSchedule(argv);
      else if(!stricmp(argv[0], "mixer"))
            rts = setMixer(argv);
      else if(!stricmp(argv[0], "limit"))
            rts = setLimit(argv);
      else if(!stricmp(argv[0], "reload"))
            rts = reload(argv);
      else if(!stricmp(argv[0], "save"))
            rts = saveId(argv);
      else if(!stricmp(argv[0], "create"))
            rts = createId(argv);
      else if(!stricmp(argv[0], "delete"))
            rts = deleteId(argv);
      else if(!stricmp(argv[0], "send"))
            rts = sendEvent(argv);
      else if(driver->getCaps() & Driver::capSwitch)
      {
            if(!stricmp(argv[0], "assign") && argv[1])
            {
                  if(argv[2])
                  {     
                        if(!stricmp(argv[1], "numbering"))
                              rts = driver->setExtNumbering(atoi(argv[2]));
                        else if(!stricmp(argv[1], "extension") && argv[3])
                              rts = driver->setExtNumber(atoi(argv[2]), argv[3]);
                        else if(!stricmp(argv[1], "virtual") && argv[3])
                              rts = driver->setExtVirtual(atoi(argv[2]), argv[3]);
                        else if(!stricmp(argv[1], "ring"))
                              rts = assignRing(argv);
                        else if(!stricmp(argv[1], "dial"))
                              rts = assignDial(argv);
                  }
            }
            else if(!stricmp(argv[0], "clear") && argv[1])
            {
                  if(argv[2] && !stricmp(argv[1], "extension"))
                        rts = driver->clrExtNumber(argv[2]);
                  else if(!stricmp(argv[1], "ring"))
                        rts = clearRing(argv);
                  else if(!stricmp(argv[2], "dial"))
                        rts = clearDial(argv);
            }
      }
      leaveMutex();
      return rts;
}


#ifdef      CCXX_NAMESPACES
};
#endif

Generated by  Doxygen 1.6.0   Back to index