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

idle.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.
//
// 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 Dialogic runtime libraries to produce a executable image
// without requiring Dialogic's sources to be supplied so long as each
// each source file so linked contains this exclusion.
//
// 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
namespace ost {
using namespace std;
#endif

void DialogicTrunk::initSyms(void)
{
      switch(interface)
      {
      case ANALOG:
            setConst(SYM_INTERFACE, "analog");
            break;
      case ISDN:
            setConst(SYM_INTERFACE, "isdn");
            break;
      case E1ORT1:
            if(dialogicivr.getSpanPorts() == 30)
                  setConst(SYM_INTERFACE, "e1");
            else
                  setConst(SYM_INTERFACE, "t1");
            break;
      case SS7:
            setConst(SYM_INTERFACE, "ss7");
            break;
      case IP:
            setConst(SYM_INTERFACE, "ip");
            break;
      default:
            setConst(SYM_INTERFACE, "unknown");
            break;
      }
      setConst(SYM_NETWORK, "tdm");
}

bool DialogicTrunk::resetHandler(TrunkEvent *event)
{
      switch(event->id)
      {
      case TRUNK_ENTER_STATE:
            enterState("reset");
            status[id] = '@';
            resetChannel();
            TimerPort::setTimer(60000);
            return true;
      case TRUNK_TIMER_EXPIRED:
            slog(Slog::levelError) << "reset timeout failure" << endl;
      case TRUNK_CALL_RESTART:
            TimerPort::endTimer();
            crn = -1;
            if(!event->parm.ok)
                  slog(Slog::levelError) << "reset failed" << endl;
            handler = &DialogicTrunk::idleHandler;
            return true;
      }
      return true;
}

bool DialogicTrunk::releaseHandler(TrunkEvent *event)
{
      switch(event->id)
      {
      case TRUNK_ENTER_STATE:
            enterState("release");
            status[id] = '#';
            releaseCall();
            TimerPort::setTimer(60000);
            return true;
      case TRUNK_TIMER_EXPIRED:
            slog(Slog::levelError) << "release timeout failure" << endl;
      case TRUNK_CALL_RELEASE:
            TimerPort::endTimer();
            crn = -1;
            handler = &DialogicTrunk::idleHandler;
            return true;
      }
      return true;
}

bool DialogicTrunk::idleHandler(TrunkEvent *event)
{
      char script[256];
      int argc = 0;
      const char *start = NULL;
      const char *data, *value;
      TrunkGroup *grp = NULL;
      char *sp;
      unsigned char cid[CC_ADDRSIZE];
      CRN lcrn;
      int ctrl;
      unsigned chk = 0;
      char **argv;
      Request *req;

      switch(event->id)
      {
      case TRUNK_CALL_RESTART:
      case TRUNK_ENTER_STATE:

                ////////////////////////////////////////////////////////////////////////////////////
                //  Patch for multiple simultanious CRN's on one Line Device
                //  While entering the "idle" state we verify that there is not a call waiting
                //  that could have been receive during the "release" state of the last call.
                //  Julien Chavanton - August 25 2005 - jchavanton@gmail.com
                ////////////////////////////////////////////////////////////////////////////////////

                ////////////////////////////////////////////////////////////////////////////////////
                // 1- Verify if call as been offered during the "release" state and jump to ring
                ////////////////////////////////////////////////////////////////////////////////////
                if(crn != -1)
                {
                 int call_state;
                 if(gc_GetCallState( crn, &call_state) != GC_SUCCESS) {
                  slog(Slog::levelDebug) << "dx(" << id << "): " <<"gc_GetCallState("<<crn<<") == FAILURE"<<endl;
                 }
                 else if(call_state != GCST_OFFERED){
                  releaseCall();
                 }
                 else{
                  if(!group->getAnswer())
                   return true;
                  rings = group->getAnswer();
                  Trunk::flags.trunk = TRUNK_MODE_INCOMING;
                  group->incIncoming();
                  Trunk::flags.ready = false;
                  TimerPort::endTimer();
                  handler = &DialogicTrunk::ringHandler;
                  return true;
                 }
                }
                ////////////////////////////////////////////////////////////////////////////////////
                // 2- Verify if there was call offered during the "release" state before the release was complete, in this case 2                   // crn are active simlutaniously, we can now retreive the second  crn and jump to "ring" state
                ////////////////////////////////////////////////////////////////////////////////////
                if(crn_hold != -1)
                {
                 crn = crn_hold;
                 crn_hold = -1;
                 slog(Slog::levelDebug) <<buffer<<": IDLE TRUNK_ENTER_STATE: call waiting HDL:"<<linedev<<" CRN:"<< crn<< endl;
                 if(!group->getAnswer())
                 return true;
                 rings = group->getAnswer();
                 Trunk::flags.trunk = TRUNK_MODE_INCOMING;
                 group->incIncoming();
                 Trunk::flags.ready = false;
                 TimerPort::endTimer();
                 handler = &DialogicTrunk::ringHandler;
                 return true;
                }
                slog(Slog::levelDebug) <<buffer<<": IDLE TRUNK_ENTER_STATE HDL:"<<linedev<<" CRN:"<< crn<< endl;
                /////////////////////////////////////////////////////
                // End of patch, entering normal bayonne "idle" state
                /////////////////////////////////////////////////////

            synctimer = exittimer = 0;
            if(crn != -1)
                  releaseCall();
            else if(Trunk::flags.trunk == TRUNK_MODE_OUTGOING) releaseCall();
            callstate = GCST_NULL;
            enterState("idle");
            Part();
            ScriptSymbol::purge();
            Trunk::flags.dsp = DSP_MODE_INACTIVE;
            tgi.pid = 0;
            digits = 0;
            switch(Trunk::flags.trunk)
            {
            case TRUNK_MODE_OUTGOING:
                  group->decOutgoing();
                  break;
            case TRUNK_MODE_INCOMING:
                  group->decIncoming();
            }
            Trunk::flags.trunk = TRUNK_MODE_INACTIVE;
            Trunk::flags.ready = true;
            Trunk::flags.offhook = false;
            status[id] = '-';
            time(&idletime);
            rings = 0;
            Trunk::detach();
            TimerPort::endTimer();
            value = group->chkRequest();
            if(value)
                  chk = atoi(value);
            if(!chk && stricmp(value, "hangup"))
                  return true;
            if(chk < group->getReady())
                  chk = group->getReady();
            TimerPort::setTimer(chk);
            waitCall();

            // TEMP KILL
            TimerPort::endTimer();

            _disconnecting = _accepted = false;

            return true;
      case TRUNK_LINE_WINK:
      case TRUNK_CPA_DIALTONE:
      case TRUNK_STOP_DISCONNECT:
            return true;
      case TRUNK_TIMER_EXPIRED:
            Trunk::flags.ready = true;
            req = group->getRequest();
            if(req)
            {
                  setConst(SYM_PARENT, req->getParent());
                  argv = req->getList();
                  start = *(argv++);
                  if(attach(start))
                  {
                        Trunk::flags.trunk = TRUNK_MODE_OUTGOING;
                        setList(argv);
                        TimerPort::endTimer();
                        Trunk::flags.ready = false;
//                      handler = &DialogicTrunk::seizeHandler;
                        handler = &DialogicTrunk::stepHandler;
                        group->incOutgoing();
                        delete req;
                        return true;
                  }
                  ScriptSymbol::purge();
                  delete req;
            }
            chk = atoi(group->chkRequest());
            if(chk)
                  TimerPort::setTimer(chk);
            return true;
      case TRUNK_START_SCRIPT:
            Trunk::flags.trunk = TRUNK_MODE_OUTGOING;
      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;
                  TimerPort::endTimer();
                  if(Trunk::flags.trunk == TRUNK_MODE_OUTGOING)
                  {
                        handler = &DialogicTrunk::stepHandler;
                        // handler = &DialogicTrunk::seizeHandler;
                        group->incOutgoing();
                  }
                  else
                  {
                        handler = &DialogicTrunk::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;
                  TimerPort::endTimer();
                  handler = &DialogicTrunk::stepHandler;
                  group->incIncoming();         
                  return true;
            }
            ScriptInterp::purge();
            getName(script);
            slog(Slog::levelError) << script << ": " << event->parm.argv[0] << ": unable to redirect" << endl;
            return true;
      case TRUNK_RINGING_ON:
      case TRUNK_CALL_OFFER:
            if(!group->getAnswer())
                  return true;
            rings = group->getAnswer();
            Trunk::flags.trunk = TRUNK_MODE_INCOMING;
            group->incIncoming();
            Trunk::flags.ready = false;
            TimerPort::endTimer();
            handler = &DialogicTrunk::ringHandler;
            return true;
      case TRUNK_MAKE_BUSY:
      case TRUNK_MAKE_STANDBY:
            handler = &DialogicTrunk::busyHandler;
            return true;
      case TRUNK_MAKE_IDLE:
            return true;
      case TRUNK_DEVICE_BLOCKED:
            return true;
      case TRUNK_DEVICE_UNBLOCKED:
            return waitCall();
      }
      return false;
}

#ifdef CCXX_NAMESPACES
};
#endif


Generated by  Doxygen 1.6.0   Back to index