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

idle.cpp

// Copyright (C) 2002 David Kerry.
//
// 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.
//
// As a special exception to the GNU General Public License, permission is
// granted for additional uses of the text contained in its release
// of Bayonne as noted here.
//
// This exception is that permission is hereby granted to link Bayonne
// with the Aculab telephony libraries to produce a executable image
// without requiring Aculab's libraries to be supplied in a free software
// license as long as each source file so linked contains this exclusion
// and the unalrtered Aculab source files are made available.
//
// This exception does not however invalidate any other reasons why
// the resulting executable file might be covered by the GNU General
// public license or invalidate the licensing requirements of any
// other component or library.
//
// This exception applies only to the code released by OST under the
// name Bayonne.  If you copy code from other releases into a copy of
// Bayonne, as the General Public License permits, the exception does not
// apply to the code that you add in this way.  To avoid misleading
// anyone as to the status of such modified files, you must delete
// this exception notice from them.
//
// If you write modifications of your own to Bayonne, it is your choice
// whether to permit this exception to apply to your modifications.
// If you do not wish that, delete this exception notice, at which
// point the terms of your modification would be covered under the GPL
// as explicitly stated in "COPYING".


#include "driver.h"

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


void AculabTrunk::initSyms(void)
{
      setConst(SYM_INTERFACE, "isdn");
      setConst(SYM_NETWORK, "tdm");
}

bool AculabTrunk::idleHandler(TrunkEvent *event)
{
      char script[256];
      int argc = 0;
      const char *start = NULL;
      unsigned chk;
      char **argv;
      const char *value;
      Request *req;
      struct cause_xparms cause;

      slog(Slog::levelDebug) <<name<<": idleHandler event "<<event->id<<endl;

      switch(event->id)
      {
      case TRUNK_ENTER_STATE:
            if (Trunk::flags.offhook) {
                  slog(Slog::levelDebug) <<name<<": not on-hook yet!"<<endl;
            }

            enterState("idle");
            setIdle(true);

            Part();
            ScriptSymbol::purge();

                Trunk::flags.dsp = DSP_MODE_INACTIVE;
                Trunk::flags.offhook = false;
                switch(Trunk::flags.trunk)
                {
                case TRUNK_MODE_OUTGOING:
                        group->decOutgoing();
                        break;
                case TRUNK_MODE_INCOMING:
                        group->decIncoming();
                  break;
                }

                Trunk::flags.trunk = TRUNK_MODE_INACTIVE;

            status[id] = '-';
            time(&idletime);
            rings = 0;
            exittimer=0;
            endTimer();
            value = group->chkRequest();
            chk = atoi(value);
            if(!chk && stricmp(value, "hangup"))
                  return true;
            if(chk < group->getReady())
                  chk = group->getReady();
            setTimer(chk);

            // TEMP KILL
            endTimer();
            return true;
      case TRUNK_LINE_WINK:
      case TRUNK_MAKE_IDLE:
      case TRUNK_CPA_DIALTONE:
      case TRUNK_STOP_DISCONNECT:
            return true;
      case TRUNK_TIMER_EXPIRED:
            Trunk::flags.ready = true;
            req = group->getRequest();
            if(req)
            {
                  setConst(req->getParent());
                  argv = req->getList();
                  start = *(argv++);
                  if(attach(start))
                  {
                        Trunk::flags.trunk = TRUNK_MODE_OUTGOING;
                        setList(argv);
                        endTimer();
                        Trunk::flags.ready = false;
                        handler = &AculabTrunk::stepHandler;
                        group->incOutgoing();
                        delete req;
                        return true;
                  }
                  ScriptSymbol::purge();
                  delete req;
            }
            chk = atoi(group->chkRequest());
            if(chk)
                  setTimer(chk);
            return true;
      case TRUNK_START_SCRIPT:
            Trunk::flags.trunk = TRUNK_MODE_OUTGOING;
            /*
             * Release incoming call handle
             */
            cause.handle = handle;
            cause.cause  = 0;
            cause.raw    = 0;
            if (call_release(&cause)) {
                  slog(Slog::levelError) <<name<<": call release FAILED"<<endl;
                  return false;
            }

      case TRUNK_RING_START:
            start = event->parm.argv[0];
            if(start)
            {
                  if(strchr(start, '='))
                        start = group->getSchedule(script);
                  else
                        ++argc;
            }
            if(Trunk::flags.trunk == TRUNK_MODE_INACTIVE)
                  Trunk::flags.trunk = TRUNK_MODE_INCOMING;

            rings = 0;
            if(!start)
                  start = group->getSchedule(script);
            if(attach(start))
            {
                  setList(&event->parm.argv[argc]);
                  Trunk::flags.ready = false;
                  endTimer();
                  if(Trunk::flags.trunk == TRUNK_MODE_OUTGOING) {
                        handler = &AculabTrunk::stepHandler;
                        group->incOutgoing();
                  }
                  else {
                        handler = &AculabTrunk::stepHandler;
                        group->incIncoming();
                  }

                  return true;
            }
            ScriptSymbol::purge();
            Trunk::flags.trunk = TRUNK_MODE_INACTIVE;
            getName(script);
            slog(Slog::levelError) << script << ": " << start << ": cannot start" << endl;
            return true;
      case TRUNK_RING_REDIRECT:
            start = group->getRedirect(event->parm.argv[0], script);
            rings = 0;
            if(attach(start))
            {
                  setConst(SYM_REDIRECT, event->parm.argv[0]);
                  setList(&event->parm.argv[1]);
                  Trunk::flags.ready = false;
                  Trunk::flags.trunk = TRUNK_MODE_INCOMING;
                  endTimer();
                  handler = &AculabTrunk::stepHandler;
                  group->incIncoming();         
                  return true;
            }
            ScriptInterp::purge();
            strcpy(script,name);

            slog(Slog::levelError) << script << ": " << event->parm.argv[0] << ": unable to redirect" << endl;
            return true;
      case TRUNK_CALL_DETECT:
      case TRUNK_RINGING_ON:
            if(!group->getAnswer()) {
                  slog(Slog::levelError) <<name<<": rejecting incoming call"<<endl;
                  cause.handle=handle;
                  cause.cause=0;
                  cause.raw=0;
                  call_disconnect(&cause);
                  handler=&AculabTrunk::idleHandler;
                  return true;
            }
            rings = group->getAnswer();
            Trunk::flags.trunk = TRUNK_MODE_INCOMING;
            group->incIncoming();
            Trunk::flags.ready = false;
            endTimer();
            _call_setup=true;
            handler = &AculabTrunk::ringHandler;
            return true;
      case TRUNK_CALL_RELEASE:
            /*
             * When restarting the driver, it's possible to get spurious
             * EV_IDLE events from old connections (queued up maybe?).
             * Even though we have not accepted any calls, we have to deal
             * with this by basically ignoring it.
             */
            slog(Slog::levelWarning)<<name<<": ignoring spurious IDLE/CALL_RELEASE event from driver"<<endl;
            return true;
      }
      return false;
}

#ifdef    CCXX_NAMESPACES
};
#endif

Generated by  Doxygen 1.6.0   Back to index