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

📄 testtransactionfsm.cxx

📁 一个著名的SIP协议栈
💻 CXX
📖 第 1 页 / 共 2 页
字号:
    const char* now;
    bool isWireInject = false;

    if (!strncasecmp(start, "inject_wire", strlen("inject_wire")))
    {
	isWireInject = true;
    }
    else if (!strncasecmp(start, "inject_tu", strlen("inject_tu")))
    {
	isWireInject = false;
    }
    else
    {
	DebugLog(<< "Warning: error parsing test specification.");
	TestSpecParseBuf->skipToChar('}');
	TestSpecParseBuf->skipChar();
	return;
    }

    TestSpecParseBuf->skipToChar('{');
    TestSpecParseBuf->skipChar();
    TestSpecParseBuf->skipWhitespace();

    start = TestSpecParseBuf->position();
    now = TestSpecParseBuf->skipToChar('}');
    *const_cast<char*>(now) = 0;
    DebugLog(<< "Injecting (isWireInject=" << isWireInject << "): " << start);
    TestSpecParseBuf->skipChar();
    if (isWireInject)
    {
	// sendToWire() is a helper function for TestTransport stuff.
	// sendToWire(start);
	SipMessage* message = TestSupport::makeMessage(start, true);
	assert(message);

	TestFSM::addMessage(client,message); //  does a client->mStateMacFifo.add(message);
	
    }
    else
    {
	SipMessage* message = TestSupport::makeMessage(start, false);
	assert(message);
	client->send(*message);
    }
}

void
processExpect()
{
    const char* start = TestSpecParseBuf->position();
    const char* now;
    unsigned int expireTime = 1;
    WaitNode* thisWait = new WaitNode;
    assert(thisWait);
    thisWait->mResponseCode = 0;

    if (!strncasecmp(start, "expect_wire", strlen("expect_wire")))
    {
	thisWait->mIsTransport = true;
    }
    else if (!strncasecmp(start, "expect_tu", strlen("expect_tu")))
    {
	thisWait->mIsTransport = false;
    }
    else
    {
	DebugLog(<< "Warning: error parsing test specification"); 
	TestSpecParseBuf->skipToChar('}');
	TestSpecParseBuf->skipChar();
	delete thisWait;
	return;
    }

    TestSpecParseBuf->skipToChar('{');
    TestSpecParseBuf->skipChar();
    TestSpecParseBuf->skipWhitespace();
    start = TestSpecParseBuf->position();

    // We will want to get two of these in an expect_ clause.
    for (int i = 0; i < 2; i++)
    {
	TestSpecParseBuf->skipToChar('=');
	TestSpecParseBuf->skipChar();
	TestSpecParseBuf->skipWhitespace();
	if (!strncasecmp(start, "method", strlen("method")))
	{
	    start = TestSpecParseBuf->position();
	    now = TestSpecParseBuf->skipToOneOf(ParseBuffer::Whitespace);
	    thisWait->mIsRequest = true;
	    thisWait->mMethod = getMethodType(start, now-start);
	}
	else if (!strncasecmp(start, "status", strlen("status")))
	{
	    TestSpecParseBuf->skipToOneOf("0123456789");
	    thisWait->mIsRequest = false;
	    thisWait->mResponseCode = TestSpecParseBuf->integer();
	}
	else if (!strncasecmp(start, "timeout", strlen("timeout")))
	{
	    TestSpecParseBuf->skipToOneOf("0123456789");
	    expireTime = TestSpecParseBuf->integer();
	}
	else
	{
	    DebugLog(<< "Warning: error parsing test specification"); 
	    TestSpecParseBuf->skipToChar('}');
	    TestSpecParseBuf->skipChar();
	    delete thisWait;
	    return;
	}
	TestSpecParseBuf->skipWhitespace();
	start = TestSpecParseBuf->position();
    }

    assert(thisWait);

    gettimeofday(&thisWait->mExpiry, NULL);
    thisWait->mExpiry.tv_sec += expireTime / 1000;
    thisWait->mExpiry.tv_usec += (expireTime % 1000) * 1000;
    WaitQueue.push_front(thisWait);

    TestSpecParseBuf->skipToChar('}');
    TestSpecParseBuf->skipChar();

    /*
    cerr << "-> Expecting " << endl;
    cerr << "   mIsTransport = " << (thisWait->mIsTransport == true) << endl;
    cerr << "   mIsRequest = " << (thisWait->mIsRequest == true) << endl;
    cerr << "   mResponseCode = " << (thisWait->mResponseCode) << endl;
    cerr << "   mExpiry = " << (thisWait->mExpiry.tv_sec) << endl;
    */
}

void
processDelays()
{
    TestSpecParseBuf->skipToChar('{');
    TestSpecParseBuf->skipChar();
    TestSpecParseBuf->skipWhitespace();

    TestSpecParseBuf->skipToOneOf("0123456789");
    int sleepLength = TestSpecParseBuf->integer();

    DebugLog( << "Pausing for " << sleepLength << " ms");

    // We sleep this way to avoid conflict with SIGALRM from alarm().
    struct timespec ts, remainder;
    ts.tv_sec = sleepLength / 1000;
    ts.tv_nsec = (sleepLength % 1000) * 1000000;
    while (nanosleep(&ts, &remainder) < 0)
    {
	ts = remainder;
    }

    TestSpecParseBuf->skipToChar('}');
    TestSpecParseBuf->skipChar();
}

bool
processClause()
{
    TestSpecParseBuf->skipWhitespace();

    // Look for 'i'/'e'/'d' for inject... or expect... or delay respectively.
    const char* now = TestSpecParseBuf->skipToOneOf("ied#");
    switch (*now)
    {
    case 'i':
	processInject();
	break;
    case 'e':
	processExpect();
	break;
    case 'd':
	processDelays();
	break;
    case '#':
	TestSpecParseBuf->skipToChar('\n');
	TestSpecParseBuf->skipChar();
	break;
    default:
	DebugLog(<< "Warning: error parsing test specification");
	TestSpecParseBuf->skipToChar('}');
	TestSpecParseBuf->skipChar();
    }

    TestSpecParseBuf->skipWhitespace();
    return !TestSpecParseBuf->eof();
}

int
main(int argc, char *argv[])
{
    ProgramName = argv[0];

    if (NULL == argv[1]) {
	exitusage();
    }

    struct stat buf;
    if (stat(argv[1], &buf) < 0)
    {
	cerr << "Error: " << strerror(errno) << endl;
	exitusage();
    }

    ifstream testSpec;
    testSpec.open(argv[1], ifstream::in);
    if (!testSpec.is_open())
    {
	cerr << "Error: could not open "<< argv[1] << endl;
	exitusage();
    }

    TestSpecBuf = new char[buf.st_size+1];
    assert(TestSpecBuf);
    testSpec.read(TestSpecBuf, buf.st_size);
    TestSpecParseBuf = new ParseBuffer(TestSpecBuf, buf.st_size);
    assert(TestSpecParseBuf);

    int clientFd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
    clientSa.sin_family = PF_INET;
    clientSa.sin_addr.s_addr = inet_addr("127.0.0.1");
    clientSa.sin_port = htons(PORT);
    int clientFdFlags = fcntl(clientFd, F_GETFL, 0);
    fcntl(clientFd, F_SETFL, clientFdFlags | O_NONBLOCK);

    client = new SipStack();
    assert(client);
    client->addTransport(UDP, PORT);

    signal(SIGALRM, processTimeouts);

    // Cause a signal to be generated with setitimer for its resolution
    struct itimerval timer;
    timer.it_value.tv_sec = 0;
    timer.it_value.tv_usec = 100000; // 100 ms resolution
    timer.it_interval.tv_sec = 0;
    timer.it_interval.tv_usec = 100000; // 100 ms resolution
    setitimer(ITIMER_REAL, &timer, NULL);

    while (processClause())
    {
    }

    // Catch any remaining events.
    processTimeouts(0);
    if (!WaitQueue.empty())
    {
	DebugLog( << "Warning: ending with expect clauses outstanding"); 
	++errorCount;
    }

    if (errorCount > 0)
    {
	cerr << "FAIL" << endl;
    }
    else
    {
	cerr << "PASS" << endl;
    }

    return errorCount;
}
#else
#include <iostream>
int
main(int argc, char *argv[])
{
  std::cout << argv[0] << ": Sorry. This test driver hasn't been ported "
                          "to Windows yet." << std::endl;
  return -1;
}
#endif
/* ====================================================================
 * 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/>.
 *
 */

⌨️ 快捷键说明

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