⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dupcarddevice.cxx

📁 SIP(Session Initiation Protocol)是由IETF定义
💻 CXX
📖 第 1 页 / 共 3 页
字号:
/* ==================================================================== * The Vovida Software License, Version 1.0  *  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved. *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: *  * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. *  * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in *    the documentation and/or other materials provided with the *    distribution. *  * 3. The names "VOCAL", "Vovida Open Communication Application Library", *    and "Vovida Open Communication Application Library (VOCAL)" must *    not be used to endorse or promote products derived from this *    software without prior written permission. For written *    permission, please contact vocal@vovida.org. * * 4. Products derived from this software may not be called "VOCAL", nor *    may "VOCAL" appear in their name, without prior written *    permission of Vovida Networks, Inc. *  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. *  * ==================================================================== *  * This software consists of voluntary contributions made by Vovida * Networks, Inc. and many individuals on behalf of Vovida Networks, * Inc.  For more information on Vovida Networks, Inc., please see * <http://www.vovida.org/>. * */#include "global.h"/* stdlib */#include <iostream>#include <fstream>#include <cstdio>#include <unistd.h>#include <sys/ioctl.h>#include <csignal>#ifdef WIN32#include <io.h>#endif/* sockets */#include <sys/types.h>#include <sys/socket.h>#include <fcntl.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#ifndef WIN32#include <sys/soundcard.h>#endif#include "VTime.hxx"#include "Rtp.hxx"#include "codec/g711.h"#include "VCondition.h"#include "DupCardDevice.hxx"#include "UaDeviceEvent.hxx"#include "UaConfiguration.hxx"#ifdef HAS_SPHINX#include "SpeechHandler.hxx"#endifusing namespace Vocal;#ifdef HAS_SPHINX SpeechHandler speechHandler;#define DATADIR  "/usr/local/share/sphinx2/model/"#define MODEL_NAME  "turtle"#endif#define RESID_RTP_RATE 160      // 320 byte packet size#define NETWORK_RTP_RATE 160    // 160 byte packet size#define FLASH_TIMEOUT 1000000extern "C"{    unsigned char linear2ulaw( int pcm_val );    int ulaw2linear( unsigned char u_val );}//***************************************************************************// DupCardDevice::DupCardDevice// description:  Constructor.  opens the PhoneCARD device.  initialize the//               hookstate.  resets the device to get it ready.//***************************************************************************void DupCardDevice::testSoundFile(){    cpLog(LOG_ERR,"Start test");    int cc = 0;    int len;    int inFile_fd;    unsigned char audio_buffer[480];    inFile_fd = open( "ULAW", O_RDONLY, 0 );    mySoundCard.reopen();    while( ( len = read( inFile_fd, audio_buffer, 160 ) ) != -1 )    {        cc += len;        if( cc > 20000 ) break;        write( myFD, (char*)audio_buffer, 160 );    }#ifndef WIN32    if( ioctl( myFD, SNDCTL_DSP_SYNC, 0 ) == -1 )    {        perror("SNDCTL_DSP_SYNC");    }#endif    cpLog(LOG_ERR,"Stop test");}DupCardDevice::DupCardDevice( const char* deviceName,                                  Sptr < Fifo < Sptr<SipProxyEvent> > > inputQ,                                  Sptr < Fifo < Sptr<SipProxyEvent> > > outputQ )    : ResGwDevice( deviceName, inputQ, outputQ ),      audioStack( 0 ),      ringbackFd( -1 ),      mySoundCard(deviceName){#ifdef HAS_SPHINX    speechHandler.initialize(Data(DATADIR), Data(MODEL_NAME));#endif    // initialize queues    sessionQ = outputQ;    myQ = inputQ;    // initialize states    hookStateOffhook = false;    playDialTone = false;    sendRingback = false;    // open audio hardware device    if( mySoundCard.open() == -1 )    {        cpLog( LOG_ERR, "Failed to open %s", deviceName );        exit( -1 );    }    // set audio API type    if(mySoundCard.getFormat() == NewSoundCardSigned16LE)    {        apiCodec = rtpPayloadL16_mono;    }    else if (mySoundCard.getFormat() == NewSoundCardUlaw)    {        apiCodec = rtpPayloadPCMU;    }    else     {        cpLog(LOG_ERR, "could not get valid sound card encoding");        exit ( -1 );    }    // store the device name//    myDeviceName = deviceName;#ifndef WIN32    // enable single keypresses without pressing <enter> in terminal    stdinFD = fileno( stdin );    tcgetattr( stdinFD, &initialTerm );    struct termios newTerm = initialTerm;    newTerm.c_lflag &= ~ICANON;    newTerm.c_cc[VMIN] = 0;    newTerm.c_cc[VTIME] = 0;    if( tcsetattr( stdinFD, TCSANOW, &newTerm ) != 0 )    {        cpLog( LOG_ERR, "Unable to set new terminal mode" );        exit( -1 );    }#endif} // end DupCardDevice::DupCardDevice()//***************************************************************************// DupCardDevice::~DupCardDevice// description:  Destructor//***************************************************************************DupCardDevice::~DupCardDevice(){    mySoundCard.close();#ifndef WIN32    tcsetattr( stdinFD, TCSANOW, &initialTerm );#endif} // end DupCardDevice::~DupCardDevice()//***************************************************************************// DupCardDevice::openAudioHardware// description:  open audio hardware device//***************************************************************************//***************************************************************************// DupCardDevice::closeAudioHardware// description://***************************************************************************//***************************************************************************// DupCardDevice::mySoundCard.reopen// description://***************************************************************************//***************************************************************************// DupCardDevice::writeToSoundCard// description://***************************************************************************//***************************************************************************// DupCardDevice::hardwareMain// description:  main processing loop of the hardware//***************************************************************************void*DupCardDevice::hardwareMain( void* parms ){#ifndef WIN32    // process forever on behalf of DupCardDevice hardware    fd_set readfds;    struct timeval tv;    int retval;    int maxFd = 128;  // should be 0 then increment as needed when addToFdSet    // reset file descriptor    FD_ZERO( &readfds );    addToFdSet( &readfds );    // block on select for asyncronous events, but poll to process    // audio and signal requests from endpoints in message queue    tv.tv_sec = 0;    tv.tv_usec = 300;    if( ( retval = select( maxFd, &readfds, 0, 0, &tv ) ) < 0 )    {        cpLog( LOG_ERR, "select() returned error %d", retval );    }    else    {        if( process( &readfds ) < 0 )        {            cpLog( LOG_ERR, "Hardware encountered an error" );            assert( 0 );        }    }#else    HANDLE handles [1];    handles[0] = GetStdHandle(STD_INPUT_HANDLE);    DWORD dwd = WaitForMultipleObjects(1, handles, false, 300);     fd_set* ptr = NULL;    if (dwd == WAIT_OBJECT_0)    {        ptr = (fd_set*)&dwd;    }            if (process(ptr) < 0)    {        cerr << "Hardware encountered an error\n";        assert(0);    }#endif    // check for signal requests from the session    if( myQ->size() > 0 )    {        processSessionMsg( myQ->getNext() );    }    return 0;} // end DupCardDevice::hardwareMain()//***************************************************************************// DupCardDevice::process//// description:  process any events detected on the hardware as well as//               simulated device events triggered by keyboard input.//               report these events back to the session via the fifo queue.//***************************************************************************intDupCardDevice::process( fd_set* fd ){    if (!fd)    {        return 0;    }    deviceMutex.lock();    // check for events coming from the keyboard    // initialize the event we will send    Sptr<UaDeviceEvent> event = new UaDeviceEvent( sessionQ );    assert( event != 0 );    event->type = DeviceEventUndefined;#ifndef WIN32    char keystroke = '\0';    if( read( stdinFD, &keystroke, 1 ) < 1 )    {        // didn't get any keystrokes        deviceMutex.unlock();        return 0;    }#else    char keystroke = '\n'; // ignore    INPUT_RECORD ir;    unsigned long cNumRead;    if (fd)     {        HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);        ReadConsoleInput( hStdin, &ir, 1, &cNumRead);                if (!ir.Event.KeyEvent.bKeyDown            || ir.Event.KeyEvent.uChar.AsciiChar == 23 /* 0x17 */             || ir.Event.KeyEvent.uChar.AsciiChar == '\n'            || ir.Event.KeyEvent.uChar.AsciiChar == 0x0a            || ir.Event.KeyEvent.uChar.AsciiChar == 0)         {            deviceMutex.unlock();            return 0;        }        keystroke = ir.Event.KeyEvent.uChar.AsciiChar;    }#endif    if(myEntryState == EntryStateEnterUrl)    {        // the user is entering a URL, so do something else        switch( keystroke )        {        case '\x08':        case '\x7F':  // Backspace (\b) or Delete (DEL)        {            if( myTextEntry.length() > 0 )            {                // xxx this is lame                cout << "\b \b\b \b\b \b";                cout.flush();                myTextEntry.setchar(myTextEntry.length() - 1, ' ');                myTextEntry.removeSpaces();            }            else            {                cout << "\b \b\b \b";                cout.flush();            }            break;        }        case '\x0A':  // Line Feed (\n) -> done        {            cpLog( LOG_DEBUG, "URL is %s", myTextEntry.logData() );            event->type = DeviceEventCallUrl;            event->text = myTextEntry;            myTextEntry = "";            myEntryState = EntryStateTelephoneUI;            break;        }        default:        {            if( keystroke >= '\x20' && keystroke <= '\x7E' )            {                // Append a character between ' ' and '~'                myTextEntry.setchar(myTextEntry.length(), keystroke);            }            else            {                // Treat everything else as abort                // e.g. '\1B':  // Esc -> abort                myTextEntry = "";                myEntryState = EntryStateTelephoneUI;                cout << endl;                cpLog( LOG_DEBUG, "Abort URL input" );                // Emulate a 'z' in TelephoneUI                hookStateOffhook = false;                event->type = DeviceEventHookDown;            }            break;        }        }    }    else    {        // process keystroke        if( keystroke != '\n' )        {            cpLog( LOG_DEBUG, "Keystroke read: '%c'(%x)",                   ( keystroke >= ' ' && keystroke <= '~' ) ? keystroke : '.',                   keystroke );        }                switch( keystroke )        {        case 'q':  // shutdown            event->type = DeviceEventShutdown;            cpLog( LOG_NOTICE , "User requested shutdown" );            break;                    case 'a':  // offhook            hookStateOffhook = true;            playDialTone = true;            event->type = DeviceEventHookUp;            break;        case 'z':  // onhook            if ( hookStateOffhook )            {                hookStateOffhook = false;                event->type = DeviceEventHookDown;            }            break;        case 'f':  // flash            event->type = DeviceEventFlash;            break;        case '*':            event->type = DeviceEventDtmfStar;            break;        case '#':            event->type = DeviceEventDtmfHash;            break;        case '0':            event->type = DeviceEventDtmf0;            break;        case '1':            event->type = DeviceEventDtmf1;            break;        case '2':            event->type = DeviceEventDtmf2;            break;        case '3':            event->type = DeviceEventDtmf3;            break;        case '4':            event->type = DeviceEventDtmf4;            break;        case '5':            event->type = DeviceEventDtmf5;            break;        case '6':            event->type = DeviceEventDtmf6;            break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -