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

📄 nullhwdevice.cxx

📁 Vovida 社区开源的 SIP 协议源码
💻 CXX
📖 第 1 页 / 共 2 页
字号:
/* ==================================================================== * 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/>. * */static const char* const NullHwDevice_cxx_Version =    "$Id: NullHwDevice.cxx,v 1.32 2002/04/24 01:58:35 bko Exp $";#include "global.h"#include <cassert>/* stdlib */#include <iostream>#include <cstdio>#include <unistd.h>#include <sys/ioctl.h>#include <csignal>#include <termios.h>/* sockets */#include <sys/types.h>#include <sys/socket.h>#include <fcntl.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>/* error handling */#include <cerrno>#include "VTime.hxx"#include "VCondition.h"#include "NullHwDevice.hxx"#include "UaDeviceEvent.hxx"#include "UaConfiguration.hxx"#define ULAW_PAYLOAD 240#define ULAW_SAMPLE_RATE 240#define RESID_RTP_RATE 240#define NETWORK_RTP_RATE 160using namespace Vocal;//***************************************************************************// NullHwDevice::NullHwDevice// description:  Constructor.//***************************************************************************NullHwDevice::NullHwDevice( char* deviceName,                            Sptr < Fifo < Sptr < SipProxyEvent > > > inputQ,                            Sptr < Fifo < Sptr < SipProxyEvent > > > outputQ )        : ResGwDevice( deviceName, inputQ, outputQ ),        audioActive( false ),        hasPlayed( false ){    // initialize queues    sessionQ = outputQ;    myQ = inputQ;    // store the device name.    myDeviceName = deviceName;#ifndef WIN32    stdinFD = fileno( stdin );    tcgetattr( stdinFD, &initialTerm );    struct termios termAttr = initialTerm;    termAttr.c_lflag &= ~ICANON;    termAttr.c_cc[VMIN] = 1;    termAttr.c_cc[VTIME] = 0;    if ( tcsetattr( stdinFD, TCSANOW, &termAttr ) != 0 )    {        cerr << "Unable to set new terminal mode."  << endl;        exit( -1 );    }#endif}  // end NullHwDevice::NullHwDevice()//***************************************************************************// QuickNetDevice::~QuickNetDevice// description:  Destructor//***************************************************************************NullHwDevice::~NullHwDevice(){#ifndef WIN32    close(myFD);    tcsetattr( stdinFD, TCSANOW, &initialTerm );#endif} // end NullHwDevice::~NullHwDevice()//***************************************************************************// NullHwDevice::hardwareMain// description:  main processing loop of the hardware//***************************************************************************void*NullHwDevice::hardwareMain (void* parms){#if !defined(WIN32)    // process forever on behalf of NullHwDevice hardware    fd_set readfds;    struct timeval tv;    int retval;    // fd_set isn't implemented quite right!    int maxFd = 8;  // should be 0 then increment as needed when addToFdSet    // reset file descriptor    FD_ZERO(&readfds);    addToFdSet( &readfds );    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 (retval > 0)    {        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 NullHwDevice::hardwareMain()//***************************************************************************// NullHwDevice::process//// description:  process any events detected on the hardware (dtmf digit//               press, onhook & offhook, etc.) and reports the events back//               to the session via the fifo queue.//***************************************************************************intNullHwDevice::process (fd_set* fd){    vusleep(0);  // needed to stabilize hookstate readings    Sptr < UaDeviceEvent > event = new UaDeviceEvent( sessionQ ) ;    assert( event != 0 );#if !defined(WIN32)    char keystroke = '\0';    read( stdinFD, &keystroke, 1 );#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.EventType != KEY_EVENT )	{	    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;                event->type = DeviceEventHookUp;            }            break;            case 'z':  // onhook            {                if( hookStateOffhook )                {                    hookStateOffhook = false;                    event->type = DeviceEventHookDown;                }            }            break;            case 'f':            {                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;

⌨️ 快捷键说明

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