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

dial.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 "driver.h"

#include <pthread.h>

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

bool VPBTrunk::dialHandler(TrunkEvent *event)
{
      int rtn;
      VPB_CALL cpp;
      VPB_DETECT toned;
      const char *dp;

      switch(event->id)
      {
      case TRUNK_CPA_REORDER:
            endTimer();
            setSymbol(SYM_TONE, "reorder");
            if(!trunkSignal(TRUNK_SIGNAL_CANCEL))
                  if(!trunkSignal(TRUNK_SIGNAL_TONE))
                        trunkSignal(TRUNK_SIGNAL_STEP);
            event->id = TRUNK_TIMER_EXPIRED;
            return false;
      case TRUNK_CPA_NODIALTONE:
      case TRUNK_CPA_FAILURE:
            endTimer();
            setSymbol(SYM_TONE, "fail");
            if(!trunkSignal(TRUNK_SIGNAL_CANCEL))
                  if(!trunkSignal(TRUNK_SIGNAL_TONE))
                        trunkSignal(TRUNK_SIGNAL_STEP);
            event->id = TRUNK_TIMER_EXPIRED;
            return false;
      case TRUNK_CPA_NORINGBACK:
            setSymbol(SYM_TONE, "silence");
            if(!trunkSignal(TRUNK_SIGNAL_SILENCE))
                  trunkSignal(TRUNK_SIGNAL_STEP);
            event->id = TRUNK_TIMER_EXPIRED;
            return false;
      case TRUNK_CPA_NOANSWER:
            endTimer();
            setSymbol(SYM_TONE, "ring");
            if(!trunkSignal(TRUNK_SIGNAL_NOANSWER))
                  trunkSignal(TRUNK_SIGNAL_STEP);
            event->id = TRUNK_TIMER_EXPIRED;
            return false;
      case TRUNK_CPA_BUSYTONE:
            endTimer();
            setSymbol(SYM_TONE, "busy");
            if(!trunkSignal(TRUNK_SIGNAL_BUSY))
                  if(!trunkSignal(TRUNK_SIGNAL_TONE))
                        trunkSignal(TRUNK_SIGNAL_STEP);
            event->id = TRUNK_TIMER_EXPIRED;
            return false;
      case TRUNK_ENTER_STATE:
            enterState("dial");
            status[id] = 'd';
            flags.offhook = true;
            setSymbol(SYM_TONE, "none");

            // DR 3/10/01 switch DTMF detection off while dialing to
            // prevent outbound digits being detected
            vpb_disable_event(handle, VPB_MDTMF);

            if(data.dialxfer.timeout)
            {
                  // reset dialtone detect
                  vpb_gettonedet(handle, VPB_DIAL, &toned);
                      vpb_settonedet(handle, &toned);

                  vpb_get_call(handle, &cpp);
                  dp = group->getLast("noringback");
                  if(dp)
                        cpp.ringback_timeout = getMSTimeout(dp);
                  else
                        cpp.ringback_timeout = 8000;
                  dp = group->getLast("cpringback");
                  if(dp)
                        cpp.inter_ringback_timeout = getMSTimeout(dp);
                  else
                        cpp.inter_ringback_timeout = 4000;
                  cpp.answer_timeout = data.dialxfer.timeout;
                  vpb_set_call(handle, &cpp);
                  rtn = vpb_call_async(handle, data.dialxfer.digits);
            }
            else
                  rtn = vpb_dial_async(handle, data.dialxfer.digits);

            if(rtn)
            {
                  setSymbol(SYM_ERROR, "dial-failed");
                  if(!trunkSignal(TRUNK_SIGNAL_ERROR))
                        trunkSignal(TRUNK_SIGNAL_STEP);                       

                  handler = &VPBTrunk::stepHandler;
            }

            // setTimer(data.dialxfer.timeout);
            // thread = new VPBDialer(this, handle);
            // thread->start();
            return true;

      case TRUNK_EXIT_STATE:
            if(data.dialxfer.timeout)
                  return false;
      case TRUNK_SERVICE_SUCCESS:
            trunkSignal(TRUNK_SIGNAL_STEP);
      case TRUNK_STOP_STATE:
            vpb_enable_event(handle, VPB_MDTMF);
            handler = &VPBTrunk::stepHandler;
            return true;
      case TRUNK_CPA_DIALTONE:
            return true;
      }

      return false;
}

bool VPBTrunk::endDialer(TrunkEvent *event)
{
      switch(event->id)
      {
      case TRUNK_STOP_DISCONNECT:
      case TRUNK_DTMF_KEYUP:
      case TRUNK_CPA_DIALTONE:
            return true;
      case TRUNK_TIMER_EXPIRED:
            handler = &VPBTrunk::stepHandler;
            return true;
      case TRUNK_ENTER_STATE:
            enterState("digend");
            status[id] = 'd';       
            setDTMFDetect();
            setTimer(120);
            return true;
      }
      return false;
}     

bool VPBTrunk::digitDialer(TrunkEvent *event)
{
      unsigned f1, f2;

      VPB_TONE tone;

      switch(event->id)
      {
      case TRUNK_STOP_DISCONNECT:
            return true;
      case TRUNK_EXIT_STATE:
            if(!thread)
                  return true;
            stopServices();
            if(stopped)
            {
                  handler = &VPBTrunk::stepHandler;
                  return true;
            }
      case TRUNK_TIMER_EXPIRED:
            if(flags.offhook == true && data.dialxfer.pulsecount)
            {
                  flags.offhook = false;
                  --data.dialxfer.pulsecount;
                  setTimer(61);
                  vpb_sethook_async(handle, VPB_ONHOOK);
                  return true;
            }
            if(flags.offhook == false)
            {
                  if(data.dialxfer.pulsecount)
                        setTimer(39);
                  else
                        setTimer(data.dialxfer.offhook);
                  flags.offhook = true;
                  vpb_sethook_async(handle, VPB_OFFHOOK);               
                  return true;
            }
            ++data.dialxfer.digit;
      case TRUNK_ENTER_STATE:
            enterState("digdial");
            status[id] = 'd';
            flags.offhook = true;
            setSymbol(SYM_TONE, "none");
            stopped = false;
            endTimer();

            setDTMFDetect(false);
            data.dialxfer.timeout = 20;
            if(!data.dialxfer.offhook)
                  data.dialxfer.onhook = getMSTimeout(group->getLast("flash"));
            if(!data.dialxfer.onhook)
                  data.dialxfer.offhook = getMSTimeout(group->getLast("dialtone"));

            if(!data.dialxfer.offhook)
                  data.dialxfer.offhook = 250;

            if(!data.dialxfer.onhook)
                  data.dialxfer.onhook = 120;

            f1 = f2 = 0;
            data.dialxfer.pulsecount = 0;
      
            switch(*data.dialxfer.digit)
            {
            case 0:
                  stopServices();
                  trunkSignal(TRUNK_SIGNAL_STEP);
                  handler = &VPBTrunk::endDialer;
                  return true;
            case 'f':
            case 'F':
            case '!':
                  flags.offhook = false;
                  vpb_sethook_async(handle, VPB_ONHOOK);
                  data.dialxfer.timeout = data.dialxfer.onhook;
                  break;
            case 't':
            case 'T':
                  data.dialxfer.dialer = DTMF_DIALER;
                  break;
            case 'p':
            case 'P':
                  data.dialxfer.dialer = PULSE_DIALER;
                  break;
            case 'm':
            case 'M':
                  data.dialxfer.dialer = MF_DIALER;
                  break;
            case ',':
            case '.':
                  data.dialxfer.timeout = 2000;
                  break;
            }

            if(data.dialxfer.dialer == PULSE_DIALER)
                  switch(*data.dialxfer.digit)
            {
            case '0':
                  data.dialxfer.pulsecount = 10;
                  break;
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
                  data.dialxfer.pulsecount = *data.dialxfer.digit - '0';
                  break;
            }

            if(data.dialxfer.dialer == MF_DIALER)
            {
                  data.dialxfer.interdigit = 120;
                  data.dialxfer.digittimer = 60;
                  switch(*data.dialxfer.digit)
                  {
                  case '1':
                        f1 = 700; f2 = 900; break;
                  case '2':
                        f1 = 700; f2 = 1100; break;
                  case '3':
                        f1 = 900; f2 = 1100; break;
                  case '4':
                        f1 = 700; f2 = 1300; break;
                  case '5':
                        f1 = 900; f2 = 1300; break;
                  case '6':
                        f1 = 1100; f2 = 1300; break;
                  case '7':
                        f1 = 700; f2 = 1500; break;
                  case '8':
                        f1 = 900; f2 = 1500; break;
                  case '9':
                        f1 = 1100; f2 = 1500; break;
                  case '0':
                        f1 = 1300; f2 = 1500; break;
                  case 'K':
                  case 'k':
                  case '#':
                        data.dialxfer.interdigit = 200;
                        data.dialxfer.digittimer = 100;
                        f1 = 1100; f2 = 17000; break;
                  case 'S':
                  case 's':
                  case '*':
                        f1 = 1500; f2 = 1700; break;
                  case 'B':
                  case 'b':
                        data.dialxfer.interdigit = 1100;
                        data.dialxfer.digittimer = 1000;
                        f1 = 2600; break;
                  }
            }
                  
            if(data.dialxfer.dialer == DTMF_DIALER)
            {
                  data.dialxfer.interdigit = 120;
                  data.dialxfer.digittimer = 60;
                  switch(*data.dialxfer.digit)
                  {
                  case '1':
                        f1 = 697; f2 = 1209; break;
                  case '2':
                        f1 = 697; f2 = 1336; break;
                  case '3':
                        f1 = 697; f2 = 1477; break;
                  case 'a':
                  case 'A':
                        f1 = 697; f2 = 1633; break;
                  case '4':
                        f1 = 770; f2 = 1209; break;
                  case '5':
                        f1 = 770; f2 = 1336; break;
                  case '6':
                        f1 = 770; f2 = 1477; break;
                  case 'b':
                  case 'B':
                        f1 = 770; f2 = 1633; break;
                  case '7':
                        f1 = 852; f2 = 1209; break;
                  case '8':
                        f1 = 852; f2 = 1336; break;
                  case '9':
                        f1 = 852; f2 = 1477; break;
                  case 'c':
                  case 'C':
                        f1 = 852; f2 = 1633; break;
                  case '*':
                        f1 = 941; f2 = 1209; break;
                  case '0':
                        f1 = 941; f2 = 1336; break;
                  case '#':
                        f1 = 941; f2 = 1477; break;
                  case 'd':
                  case 'D':
                        f1 = 941; f2 = 1633; break;
                  }     
            }

            if(f1 || f2)
            {
                  memset(&tone, 0, sizeof(tone));
                  tone.freq1 = f1;
                  tone.freq2 = f2;
                  tone.level1 = -1;
                  tone.level2 = -1;
                  tone.ton = data.dialxfer.digittimer;
                  tone.toff = data.dialxfer.interdigit;

                  if(tonetmp)
                        delete tonetmp;

                  if(!f2)
                        tonetmp = new phTone(NULL, data.dialxfer.digittimer, f1);
                  else
                        tonetmp = new phTone(NULL, data.dialxfer.digittimer, f1, f2);

                  thread = new VPBDigit(this, handle);
                  thread->start();        
                  return true;      
//                vpb_playtone_async(handle, &tone);
            }
            
            if(data.dialxfer.pulsecount)
                  setTimer(100);          
            else
                  setTimer(data.dialxfer.timeout);
            return true;

      case TRUNK_SERVICE_SUCCESS:
      case TRUNK_SERVICE_FAILURE:
            exitThread();
            return true;
      case TRUNK_STOP_STATE:
            if(thread)
            {
                        stopped = true;
                        vpb_play_terminate(handle);
                        return true;
            }
            stopServices();
            endTimer();
            handler = &VPBTrunk::stepHandler;
            return true;
      case TRUNK_CPA_DIALTONE:
            return true;
      }

      return false;
}

VPBDigit::VPBDigit(VPBTrunk *trunk, int h) :
Service((Trunk *)trunk, keythreads.priAudio()), TimerPort()
{
        handle = h;
        reset = false;
        trk = trunk; // DR
}

VPBDigit::~VPBDigit()
{
        // DR - make sure Run() thread has finished before we delete object
        if(reset)
        {
                vpb_play_terminate(handle);
                yield();
        }

        terminate();
}

void VPBDigit::run(void)
{
      char *ptr = (char *)trk->tonetmp->getSamples();
      vpb_play_buf_start(handle, VPB_MULAW);
      vpb_play_buf_sync(handle, ptr, data->dialxfer.digittimer * 8);
      vpb_play_buf_finish(handle);
      reset = false;
      Thread::sleep(data->dialxfer.interdigit - data->dialxfer.digittimer);
      success();
}

#ifdef      CCXX_NAMESPACES
};
#endif







Generated by  Doxygen 1.6.0   Back to index