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

bayonne.cpp

// Copyright (C) 2000 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>

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

class BayonneXMLTrunk : public TrunkImage
{
private:
      friend class BayonneXMLModule;

      typedef     enum
      {
            BR_NONE,
            BR_DEBUG,
            BR_LOG,
            BR_SPEAK,
            BR_TEXT
      } br_t;

      bool bufalloc;
      br_t br;

      char *swistack[16];
      unsigned swilevel;

      void startSwitch(const char **attrib);
      void endSwitch(void);
      void startTrap(const char **attrib);
      void endTrap(void);
      void startBlock(const char **attrib);
      void endBlock(void);
      void startDebug(const unsigned char **attrib);
      void endDebug(void);
      void startLog(const unsigned char **attrib);
      void endLog(void);
      void startSpeak(const unsigned char **attrib);
      void endSpeak(void);
      void startText(const unsigned char **attrib);
      void endText(void);
      void doStart(const char **attrib);
      void doSend(const char **attrib);
      void doCase(const char **attrib);
      void doDial(const char **attrib);
      void doOtherwise(void);
      void doBr(void);
      void doRule(const char **attrib);
      void doAssign(const char **attrib);
      void doAnswer(const char **attrib);
      void doAccept(const char **attrib);
      void doReject(const char **attrib);
      void doClear(void);
      void doGoto(const char **attrib);
      void doHangup(void);

      void characters(const unsigned char *text, unsigned len);
      void startElement(const unsigned char *name, const unsigned char **attrib);
      void endElement(const unsigned char *name);
      bool loader(Trunk *trk, trunkdata_t *data);
      const char *mystr(const char *temp);

      BayonneXMLTrunk();
      ~BayonneXMLTrunk();
};

class BayonneXMLModule : protected Module
{
private:
      modtype_t getType(void)
            {return MODULE_XML;};

      char *getName(void)
            {return "bayonnexml";};

      TrunkImage *getXML(void)
            {return (TrunkImage *)new BayonneXMLTrunk;};

      char *dispatch(Trunk *trunk);

public:
      BayonneXMLModule();
} bayonnexml;

BayonneXMLModule::BayonneXMLModule() : Module()
{
      slog(Slog::levelDebug) << "XML: Loading <BayonneXML> interpreter" << endl;
      driver->addModule(this);
}

char *BayonneXMLModule::dispatch(Trunk *trunk)
{
      trunkdata_t *data = getData(trunk);
      const char *key, *url = trunk->getKeyword("url");

      data->load.attach = false;
      data->load.post = false;
      data->load.section = "#";
      key = trunk->getKeyword("maxTime");
      if(!key)
            key = "60s";
      data->load.timeout = getSecTimeout(key);
      data->load.parent = NULL;
      data->load.gosub = false;
      data->load.url = trunk->getValue(url);
      data->load.vars = NULL;
      if(!data->load.url)
            return "no-xml-url";
      data->load.userid[0] = 0;
      return NULL;
}

BayonneXMLTrunk::BayonneXMLTrunk() : TrunkImage()
{
      if(!buffer)
      {
            bufalloc = true;
            buffer = new char[512];
      }
      else
            bufalloc = false;
      swilevel = 0;
      buffer[0] = 0;
      slog(Slog::levelDebug) << "XML: Creating <BayonneXML> instance" << endl;
}

BayonneXMLTrunk::~BayonneXMLTrunk()
{
      if(bufalloc)
            delete[] buffer;
      purge();
      slog(Slog::levelDebug) << "XML: Destroying <BayonneXML> instance" << endl;
}

void BayonneXMLTrunk::characters(const unsigned char *text, unsigned len)
{
      int blen = strlen(buffer);

      if(br == BR_NONE)
            return;

      while(blen < 512 && len--)
            buffer[blen++] = (char)*(text++);
      buffer[blen] = 0;
}

void BayonneXMLTrunk::startElement(const unsigned char *name, const unsigned char **attrib)
{

      if(!stricmp((const char *)name, "bayonnexml"))
      {
            br = BR_NONE;
            getCompile("#");
            return;
      }

      if(!stricmp((const char *)name, "log"))
            startLog(attrib);
      else if(!stricmp((const char *)name, "select"))
            startSwitch((const char **)attrib);
      else if(!stricmp((const char *)name, "goto"))
            doGoto((const char **)attrib);
      else if(!stricmp((const char *)name, "assign"))
            doAssign((const char **)attrib);
      else if(!stricmp((const char *)name, "case"))
            doCase((const char **)attrib);
      else if(!stricmp((const char *)name, "start"))
            doStart((const char **)attrib);
      else if(!stricmp((const char *)name, "send"))
            doSend((const char **)attrib);
      else if(!stricmp((const char *)name, "dial"))
            doDial((const char **)attrib);
      else if(!stricmp((const char *)name, "call"))
            doDial((const char **)attrib);
      else if(!stricmp((const char *)name, "otherwise"))
            doOtherwise();
      else if(!stricmp((const char *)name, "answer"))
            doAnswer((const char **)attrib);
      else if(!stricmp((const char *)name, "accept"))
            doAccept((const char **)attrib);
      else if(!stricmp((const char *)name, "reject"))
            doReject((const char **)attrib);
      else if(!stricmp((const char *)name, "clear"))
            doAssign((const char **)attrib);
      else if(!stricmp((const char *)name, "text"))
            startText(attrib);
      else if(!stricmp((const char *)name, "debug"))
            startDebug(attrib);
      else if(!stricmp((const char *)name, "speak"))
            startSpeak(attrib);
      else if(!stricmp((const char *)name, "rule"))
            doRule((const char **)attrib);
      else if(!stricmp((const char *)name, "phrasebook"))
            doRule((const char **)attrib);
      else if(!stricmp((const char *)name, "block"))
            startBlock((const char **)attrib);
      else if(!stricmp((const char *)name, "trap"))
            startTrap((const char **)attrib);
}

void BayonneXMLTrunk::endElement(const unsigned char *name)
{
      if(!stricmp((const char *)name, "bayonnexml"))
      {
            doBr();
            putCompile(main);
            return;
      }

      if(!stricmp((const char *)name, "log"))
            endLog();
      else if(!stricmp((const char *)name, "select"))
            endSwitch();
      else if(!stricmp((const char *)name, "br"))
            doBr();
      else if(!stricmp((const char *)name, "cleardigits"))
            doClear();
      else if(!stricmp((const char *)name, "text"))
            endText();
      else if(!stricmp((const char *)name, "debug"))
            endDebug();
      else if(!stricmp((const char *)name, "speak"))
            endSpeak();
      else if(!stricmp((const char *)name, "block"))
            endBlock();
      else if(!stricmp((const char *)name, "trap"))
            endTrap();
      else if(!stricmp((const char *)name, "hangup"))
            doHangup();
      else if(!stricmp((const char *)name, "disconnect"))
            doHangup();
}

void BayonneXMLTrunk::startSwitch(const char **attrib)
{
      const char *name = "";

      if(attrib)
      {
            while(*attrib)
            {
                  if(!stricmp(*attrib, "name"))
                        name = *(++attrib);
                  else
                        ++attrib;
                  ++attrib;
            }
      }

      swistack[swilevel] = new char[strlen(name) + 2];
      *swistack[swilevel] = '%';
      strcpy(swistack[swilevel++] + 1, name);
      addCompile(0, "do", NULL);
}

void BayonneXMLTrunk::endSwitch(void)
{
      if(!swilevel)
            return;

      delete[] swistack[--swilevel];
      addCompile(0, "break", NULL);
      addCompile(0, "loop", NULL);
}
      
void BayonneXMLTrunk::startBlock(const char **attrib)
{
      const char *name = "#";
      const char *repeat = "";
      const char *args[3];

      if(attrib)
      {
            while(*attrib)
            {
                  if(!stricmp(*attrib, "label"))
                        name = *(++attrib);
                  else if(!stricmp(*attrib, "name"))
                        name = *(++attrib);
                  else if(!stricmp(*attrib, "repeat"))
                        repeat = *(++attrib);
                  else
                        ++attrib;
                  ++attrib;
            }
      }

      doBr();

      br = BR_NONE;
      name = mystr(name);
      repeat = mystr(repeat);
      if(strcmp(name, "#"))
            getCompile(name);
      else
            setCompile(0);
      
      if(*repeat && !current->last)
      {
            args[0] = repeat;
            args[1] = NULL;
            addCompile(0, "repeat", args);
      }
}

void BayonneXMLTrunk::endBlock(void)
{
      doBr();

      if(main == current)
            return;

      putCompile(current);
      current = main;
}

void BayonneXMLTrunk::startTrap(const char **attrib)
{
      const char *id = "error";
      unsigned trap = 0;

      if(**attrib)
      {
            while(*attrib)
            {
                  if(!stricmp(*attrib, "id"))
                        id = *(++attrib);
                  else
                        ++attrib;
                  ++attrib;
            }
      }

      if(!stricmp(id, "hangup"))
            trap = TRUNK_SIGNAL_HANGUP;
      else if(!stricmp(id, "error"))
            trap = TRUNK_SIGNAL_ERROR;
      else if(!stricmp(id, "timeout"))
            trap = TRUNK_SIGNAL_TIMEOUT;
      else if(!stricmp(id, "dtmf"))
            trap = TRUNK_SIGNAL_DTMF;
      else if(!stricmp(id, "0"))
            trap = 5;
      else if(!stricmp(id, "1"))
            trap = 6;
      else if(!stricmp(id, "2"))
            trap = 7;
      else if(!stricmp(id, "3"))
            trap = 8;
      else if(!stricmp(id, "4"))
            trap = 9;
      else if(!stricmp(id, "5"))
            trap = 10;
      else if(!stricmp(id, "6"))
            trap = 11;
      else if(!stricmp(id, "7"))
            trap = 12;
      else if(!stricmp(id, "8"))
            trap = 13;
      else if(!stricmp(id, "9"))
            trap = 14;
      else if(!stricmp(id, "star"))
            trap = 15;
      else if(!stricmp(id, "pound"))
            trap = 16;
      else if(!stricmp(id, "event"))
            trap = TRUNK_SIGNAL_EVENT;
      else if(!stricmp(id, "tone"))
            trap = TRUNK_SIGNAL_TONE;
      else if(!stricmp(id, "busy"))
            trap = TRUNK_SIGNAL_BUSY;
      else if(!stricmp(id, "fail"))
            trap = TRUNK_SIGNAL_FAIL;
      
      if(!trap)
            return;

      current->script->mask |= (1<<(trap - 1));
      if(trap > 4 && trap < 21)
            current->script->mask |= 8;
      setCompile(trap);
}

void BayonneXMLTrunk::endTrap(void)
{
      doBr();
      setCompile(0);
}

void BayonneXMLTrunk::doOtherwise(void)
{
      if(swilevel)
            addCompile(0, "otherwise", NULL);
}

void BayonneXMLTrunk::doBr(void)
{
      br_t mbr = br;

      if(!buffer[0])
            return;

      switch(br)
      {
      case BR_LOG:
            endLog();
            break;
      case BR_TEXT:
            endText();
            break;
      case BR_DEBUG:
            endDebug();
            break;
      case BR_SPEAK:
            endSpeak();
      }
      buffer[0] = 0;
      br = mbr;
}

void BayonneXMLTrunk::doClear(void)
{
      doBr();
      addCompile(0, "cleardigits", NULL);
}     

void BayonneXMLTrunk::doHangup(void)
{
      doBr();
      addCompile(0, "hangup", NULL);
}

void BayonneXMLTrunk::doDial(const char **attrib)
{
      const char *args[9];
      int argc = 0;
      const char *value = NULL, *maxtime = NULL, *origin = NULL;

      if(!attrib)
            return;

      while(*attrib)
      {
            if(!stricmp(*attrib, "value"))
                  value = *(++attrib);
            else if(!stricmp(*attrib, "maxTime"))
                  maxtime = *(++attrib);
            else if(!stricmp(*attrib, "callerID"))
                  origin = *(++attrib);
            else
                  ++attrib;
            ++attrib;
      }

      if(!value)
            return;

      if(!strnicmp(value, "tel:", 4))
            value += 4;
      else if(!strnicmp(value, "pstn:", 5))
            value += 5;

      args[argc++] = mystr(value);
      if(maxtime)
      {
            args[argc++] = "=maxTime";
            args[argc++] = mystr(maxtime);
      }

      if(origin)
      {
            if(!strnicmp(origin, "tel:", 4))
                  origin += 4;
            else if(!strnicmp(origin, "pstn:", 5))
                  origin += 5;

            args[argc++] = "=origin";
            args[argc++] = mystr(origin);
      }
      args[argc] = NULL;

      addCompile(0, "dial", args);
}

void BayonneXMLTrunk::doSend(const char **attrib)
{
      const char *id = "%session.parent";
      const char *msg = NULL;
      const char *argv[5];

      if(!attrib)
            return;

      while(*attrib)
      {
            if(!stricmp(*attrib, "id"))
                  id = *(++attrib);
            else if(!stricmp(*attrib, "message"))
                  msg = *(++attrib);
            else
                  ++attrib;
            ++attrib;
      }

      if(!msg)
            return;

      argv[0] = "=id";
      argv[1] = mystr(id);
      argv[2] = "=message";
      argv[3] = mystr(msg);
      argv[4] = NULL;

      addCompile(0, "send", argv);
}

void BayonneXMLTrunk::doStart(const char **attrib)
{
      const char *var = NULL, *script = NULL, *maxtime = NULL, *group = NULL;
      const char *submit = NULL;
      const char *argv[16];
      int argc = 0;

      if(!attrib)
            return;

      while(*attrib)
      {
            if(!stricmp(*attrib, "value"))
                  script = *(++attrib);
            else if(!stricmp(*attrib, "script"))
                  script = *(++attrib);
            else if(!stricmp(*attrib, "maxTime"))
                  maxtime = *(++attrib);
            else if(!stricmp(*attrib, "group"))
                  group = *(++attrib);
            else if(!stricmp(*attrib, "var"))
                  var = *(++attrib);
            else if(!stricmp(*attrib, "submit"))
                  submit = *(++attrib);
            else
                  ++attrib;
            ++attrib;
      }

      if(!group)
            group = "*";

      if(!script)
            return;

      argv[argc++] = mystr(script);
      if(maxtime)
      {
            argv[argc++] = "=maxTime";
            argv[argc++] = mystr(maxtime);
      }

      if(var)
      {
            argv[argc++] = "=var";
            if(*var == '%')
                  ++var;
            argv[argc++] = mystr(var);
      }

      if(submit)
      {
            argv[argc++] = "=submit";
            argv[argc++] = mystr(submit);
      }     

      argv[argc++] = "=group";
      argv[argc++] = mystr(group);
      
      addCompile(0, "start.group", argv);
}

void BayonneXMLTrunk::doCase(const char **attrib)
{
      const char *args[6];
      const char *value = NULL;

      if(!swilevel)
            return;

      if(attrib)
      {
            while(*attrib)
            {
                  if(!stricmp(*attrib, "value"))
                        value = *(++attrib);
                  else
                        ++attrib;
                  ++attrib;
            }
      }
      if(!value)
      {
            doOtherwise();
            return;
      }
      args[0] = mystr(swistack[swilevel - 1]);
      args[1] = "-eq";
      args[2] = mystr(value);
      args[3] = NULL;
      addCompile(0, "case", args);
}

void BayonneXMLTrunk::doGoto(const char **attrib)
{
      const char *args[129];
      const char *value = "";
      const char *maxtime = "";
      const char *method = "get";
      const char *var = "";
      const char *token;
      int argc = 0;

      doBr();

      if(attrib)
      {
            while(*attrib)
            {
                  if(!stricmp(*attrib, "name"))
                        value = *(++attrib);
                  else if(!stricmp(*attrib, "label"))
                        value = *(++attrib);
                  else if(!stricmp(*attrib, "value"))
                        value = *(++attrib);
                  else if(!stricmp(*attrib, "maxtime"))
                        maxtime = *(++attrib);
                  else if(!stricmp(*attrib, "method"))
                        method = *(++attrib);
                  else if(!stricmp(*attrib, "var"))
                        var = *(++attrib);
                  else if(!stricmp(*attrib, "submit"))
                        var = *(++attrib);
                  else
                        ++attrib;
                  ++attrib;
            }
      }
      if(!value)
            return;

      if((!var && *value == '#') || !strchr(value, '/'))
      {
            args[0] = mystr(value);
            args[1] = NULL;
            addCompile(0, "goto", args);
      }

      if(maxtime)
      {
            args[0] = "=maxtime";
            args[1] = mystr(maxtime);
            argc += 2;
      }

      if(!stricmp(method, "post"))
            method = "load.post";
      else
            method = "load";

      strcpy(buffer, var);
      bp = buffer;
      args[argc++] = mystr(value);
      while(argc < 128 && NULL != (token = getToken()))
            args[argc++] = token;

      args[argc] = NULL;
      addCompile(0, method, args);
      buffer[0] = 0;
}

void BayonneXMLTrunk::doRule(const char **attrib)
{
      const char *rule = NULL;
      if(br != BR_SPEAK || !attrib)
            return;

      while(*attrib)
      {
            if(!stricmp(*attrib, "rule"))
                  rule = *(++attrib);
            else if(!stricmp(*attrib, "name"))
                  rule = *(++attrib);
            else
                  ++attrib;
            ++attrib;
      }
      if(!rule)
            return;

      strcat(buffer, " &");
      strcat(buffer, rule);
      strcat(buffer, " ");
}

void BayonneXMLTrunk::doAccept(const char **attrib)
{
      addCompile(0, "accept", NULL);
}

void BayonneXMLTrunk::doReject(const char **attrib)
{
      addCompile(0, "reject", NULL);
}

void BayonneXMLTrunk::doAnswer(const char **attrib)
{
      const char *maxtime = "0";
      const char *maxring = "0";
      const char *args[5];

      doBr();
      if(attrib)
      {
            while(*attrib)
            {
                  if(!stricmp(*attrib, "maxtime"))
                        maxtime = mystr(*(++attrib));
                  else if(!stricmp(*attrib, "maxring"))
                        maxring = mystr(*(++attrib));
                  else
                        ++attrib;
                  ++attrib;
            }
      }
      args[0] = "=maxring";
      args[1] = maxring;
      args[2] = "=maxtime";
      args[3] = maxtime;
      args[4] = NULL;
      addCompile(0, "answer", args);
}           
       
void BayonneXMLTrunk::doAssign(const char **attrib)
{
      const char *size = "0";
      const char *var = "";
      const char *value = "";
      unsigned sz;

      char szbuf[5];
      const char *args[7];

      doBr();
      if(attrib)
      {
            while(*attrib)
            {
                  if(!stricmp(*attrib, "size"))
                        size = *(++attrib);
                  else if(!stricmp(*attrib, "var"))
                        var = *(++attrib);
                  else if(!stricmp(*attrib, "name"))
                        var = *(++attrib);
                  else if(!stricmp(*attrib, "value"))
                        value = *(++attrib);
                  else
                        ++attrib;
                  ++attrib;
            }
      }
      if(!stricmp(size, "char"))
            sz = 1;
      else if(!stricmp(size, "time"))
            sz = 6;
      else if(!stricmp(size, "date"))
            sz = 8;
      else if(!stricmp(size, "timestamp"))
            sz = 11;
      else if(!stricmp(size, "number"))
            sz = 11;
      else
            sz = atoi(size);

      if(!*var)
            return;

      var = mystr(var);
      value = mystr(value);
      args[0] = "=var";
      args[1] = var;
      args[2] = "=value";
      args[3] = value;
            
      if(sz)
      {
            sprintf(szbuf, "%d", sz);
            args[4] = "=size";
            args[5] = mystr(szbuf);
            args[6] = NULL;
      }
      else
            args[4] = NULL;
      addCompile(0, "assign", args);
}           

void BayonneXMLTrunk::startDebug(const unsigned char **a)
{
      setToken(a);
      br = BR_DEBUG;
}

void BayonneXMLTrunk::startText(const unsigned char **a)
{
      setToken(a);
      br = BR_TEXT;
}

void BayonneXMLTrunk::startSpeak(const unsigned char **a)
{
      setToken(a);
      br = BR_SPEAK;
}

void BayonneXMLTrunk::startLog(const unsigned char **a)
{
      setToken(a);
      br = BR_LOG;
}

void BayonneXMLTrunk::endText(void)
{
      const char *token;
      const char *args[129];
      int argc = 0;

      bp = buffer;
      while(NULL != (token = getToken()) && argc < 128)
            args[argc++] = token;

      args[argc] = NULL;
      addCompile(0, "say", args);
      buffer[0] = 0;
      br = BR_NONE;
}

void BayonneXMLTrunk::endSpeak(void)
{
      const char *token;
      const char *args[129];
      int argc = 0;

      bp = buffer;
      while(NULL != (token = getToken()) && argc < 128)
            args[argc++] = token;

      args[argc] = NULL;
      addCompile(0, "speak", args);
      buffer[0] = 0;
      br = BR_NONE;
}

void BayonneXMLTrunk::endDebug(void)
{
      const char *token;
      const char *args[129];
      int argc = 0;

      bp = buffer;
      while(NULL != (token = getToken()) && argc < 128)
      {
            args[argc++] = token;
            args[argc++] = " ";
      }

      args[argc] = NULL;
      addCompile(0, "debug", args);
      buffer[0] = 0;
      br = BR_NONE;
}

void BayonneXMLTrunk::endLog(void)
{
      char cmdbuf[32];
      const char *args[129];
      int argc = 0;
      const char *token;

      bp = buffer;
      while(NULL != (token = getToken()) && argc < 128)
      {
            args[argc++] = token;
            args[argc++] = " ";
      }

      args[argc] = NULL;
      token = getAttribute("level");
      if(token)
            sprintf(cmdbuf, "slog.%s", token);
      else
            strcpy(cmdbuf, "slog");
      addCompile(0, mystr(cmdbuf), args);
      buffer[0] = 0;
      br = BR_NONE;
}

bool BayonneXMLTrunk::loader(Trunk *trk, trunkdata_t *data)
{
      URLStream::Error error;
      const char *url = data->load.url;
      const char **vars = (const char **)data->load.vars;


      if(!strnicmp(url, "http:", 5) && vars && vars[0])
      {
            if(data->load.post)
                  error = post(url, vars);
            else
                  error = submit(url, vars);
      }
      else
            error = get(url);
      if(error)
      {
            slog(Slog::levelDebug) << "XML: Loading " << url << "; error=" << error << endl;
            return false;
      }

      if(!parse())
      {
            slog(Slog::levelError) << "XML: Parsing " << url << " - not well formed" << endl;
            return false;
      }

      return true;
}

const char *BayonneXMLTrunk::mystr(const char *temp)
{
      char *nt = (char *)alloc(strlen(temp) + 1);
      strcpy(nt, temp);
      return (const char *)nt;
}

#ifdef      CCXX_NAMESPACES
};
#endif

Generated by  Doxygen 1.6.0   Back to index