📄 gateway.cxx
字号:
/* ==================================================================== * 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 gateway_cxx_Version = "$Id: gateway.cxx,v 1.24 2001/01/17 01:52:24 liuhong Exp $";#include <signal.h>#include "VTime.hxx"#include <sys/types.h>#include <unistd.h>#include <queue>#include <typeinfo>#include <map>#include "MgAgent.hxx"#include "SdpSession.hxx"#include "NullHardware.h"#include "TpjackHardware.h"#include "VThread.h"// response codes, should be defined somewhere else#define RSP_CODE_NORMAL ReasonTransactionExecuted/********************************************************************** Data structures **********************************************************************/class StateMachine;class StateEvent;// state handler and transition functionstypedef void (*StateHandler) (StateEvent* event, StateMachine* state);void stateUninitialized (StateEvent* event, StateMachine* state);void stateIdle (StateEvent* event, StateMachine* state);void stateRingingIn (StateEvent* event, StateMachine* state);void stateRingingOut (StateEvent* event, StateMachine* state);void stateHalfOpenIn (StateEvent* event, StateMachine* state);void stateHalfOpen (StateEvent* event, StateMachine* state);void stateActiveNoNotifications (StateEvent* event, StateMachine* state);void stateActive (StateEvent* event, StateMachine* state);void stateWaitForClose (StateEvent* event, StateMachine* state);void stateWaitOnHook (StateEvent* event, StateMachine* state);// hardware events handled by state machineenum StateEventStimulus{ StimulusNULL, StimulusNewMessage, StimulusResponse, StimulusOffHook, StimulusOnHook, StimulusDigit0, StimulusDigit1, StimulusDigit2, StimulusDigit3, StimulusDigit4, StimulusDigit5, StimulusDigit6, StimulusDigit7, StimulusDigit8, StimulusDigit9, StimulusDigitStar, StimulusDigitHash};/********************************************************************** Class: State MachineDescription: A single endpoint, single connection, residential gateway. **********************************************************************/class StateMachine{ public: StateMachine () {} ; MgAgent* callAgent; Hardware* hardware; StateHandler currentState; SdpSession localSD; SdpSession remoteSD; string endpointId; string currentRequestId; string callId; string connectionId; string connectionMode; void setState (StateHandler current) { char* string = ""; if (current == stateUninitialized) string = "stateUninitialized"; else if (current == stateIdle) string = "stateIdle"; else if (current == stateRingingIn) string = "stateRingingIn"; else if (current == stateRingingOut) string = "stateRingingOut"; else if (current == stateHalfOpen) string = "stateHalfOpen"; else if (current == stateActiveNoNotifications) string = "stateActiveNoNotifications"; else if (current == stateActive) string = "stateActive"; cout << "State changed to: " << string << "\n"; currentState = current; };};/********************************************************************** Class: State EventDescription: An incoming event into the residnetial gateway, may be an MGCP message from the call agent or an asynchronous input from the endpoint hardware.**********************************************************************/class StateEvent{ public: StateEvent() : stimulus(StimulusNULL) {} StateEventStimulus getStimulus () { return stimulus; } void setStimulus (StateEventStimulus stim) { stimulus = stim; } Sptr < MgCommand > getMessage () { return newMsg; } void setMessage (Sptr < MgCommand > msg) { newMsg = msg; stimulus = StimulusNewMessage; } private: StateEventStimulus stimulus; Sptr < MgCommand > newMsg;};/********************************************************************* Utility Functions *********************************************************************/char* getHost(){ static char buf[256];#ifndef __vxworks gethostname(buf, 256);#else strcpy(buf, "vovida.com");#endif return buf;}void wrongMessage(){ cerr << "received invalid message\n";#if 0 int parentpid = getpid(); kill(parentpid, SIGSTOP);#endif exit(1);}void fatalError(char* errorMsg){ cerr << errorMsg << "\n"; exit(1);}/********************************************************************* State Handler Functions *********************************************************************/void stateUninitialized (StateEvent* event, StateMachine* state){ if (event->getStimulus() == StimulusNewMessage) { Sptr < MgCommand > msgPtr = event->getMessage(); Sptr < MgNotificationRequest > rqntPtr; switch (msgPtr->getType()) { case MgNotificationRequestType: // state 3 -- receive notification request rqntPtr.dynamicCast(msgPtr); if (rqntPtr == NULL) wrongMessage(); // store required paramters state->endpointId = rqntPtr->getEndpointId(); state->currentRequestId = rqntPtr->getRequestIdentifier(); // ignore all optional paramters // reply with successful response code and string, // transaction id handled by mgcp stack rqntPtr->setResponseCode(RSP_CODE_NORMAL); rqntPtr->setResponseString("OK"); state->callAgent->reply(rqntPtr); state->setState(stateIdle); break; default: // ignore other messages cout << "received message for which no handling exists\n"; break; } // end switch } else cout << "received hardware input for which no handling exists\n";}void stateIdle (StateEvent* event, StateMachine* state){ if (event->getStimulus() == StimulusOffHook) { // create and send a Notify msg regarding the offHook event MgNotify ntfy(state->endpointId, state->currentRequestId,#ifndef NCS_PROFILE (MgLinePackage::notifyOffHookTransition())#else // NCS_PROFILE (MgNCSLinePackage::notifyOffHookTransition())#endif ); state->callAgent->send(ntfy); // set hardware state->hardware->sendSignal(SignalLocalRingbackStart); state->setState(stateRingingOut); } else if (event->getStimulus() == StimulusNewMessage) { Sptr < MgCommand > msgPtr = event->getMessage(); Sptr < MgNotificationRequest > rqntPtr; switch (msgPtr->getType()) { case MgNotificationRequestType: // state 3 -- receive notification request rqntPtr.dynamicCast(msgPtr); if (rqntPtr == NULL) wrongMessage(); // store required paramters state->endpointId = rqntPtr->getEndpointId(); state->currentRequestId = rqntPtr->getRequestIdentifier(); // ignore all optional parameters // set hardware state->hardware->sendSignal(SignalRingStart); // reply with successful response code and string, // transaction id handled by mgcp stack rqntPtr->setResponseCode(RSP_CODE_NORMAL); rqntPtr->setResponseString("OK"); state->callAgent->reply(rqntPtr); state->setState(stateRingingIn); break; default: // ignore other messages cout << "received message for which no handling exists\n"; break; } // end switch } else cout << "received hardware input for which no handling exists\n";}// the set is ringing and you may get the message offhook/onhookvoid stateRingingIn(StateEvent* event, StateMachine* state){ if (event->getStimulus() == StimulusOffHook) { // stop ringing state->hardware->sendSignal(SignalRingStop); // create and send a Notify msg regarding the offHook event MgNotify notifyMsg(state->endpointId, state->currentRequestId,#ifndef NCS_PROFILE (MgLinePackage::notifyOffHookTransition())#else // NCS_PROFILE (MgNCSLinePackage::notifyOffHookTransition())#endif ); state->callAgent->send(notifyMsg); // wait for the create connection state->setState(stateHalfOpenIn); } else cout << "received message or hardware input for which no handling exists\n";}void stateRingingOut(StateEvent* event, StateMachine* state){ if (event->getStimulus() == StimulusNewMessage) { Sptr < MgCommand > msgPtr = event->getMessage(); Sptr < MgCreateConnection > crcxPtr; switch (msgPtr->getType()) { case MgCreateConnectionType: { // state 5 -- receive create connection crcxPtr.dynamicCast (msgPtr); if (crcxPtr == NULL) wrongMessage(); // store required paramters state->endpointId = crcxPtr->getEndpointId(); state->currentRequestId = crcxPtr->getRequestIdentifier(); state->callId = crcxPtr->getCallId(); state->connectionMode = crcxPtr->getConnectionMode(); if (state->connectionMode != "sendrecv") wrongMessage(); // ignore all optional parameters // setup local session descriptor state->localSD.setSessionName("test session"); state->localSD.setUserName("testID"); state->localSD.setAddress(getHost()); state->localSD.setSessionId(128538); state->localSD.setVersion(0); SdpConnection* sessionConnection = new SdpConnection; sessionConnection->setUnicast ((state->localSD.getAddress()).c_str()); state->localSD.setConnection (*sessionConnection); SdpMedia* media = new SdpMedia; media->setMediaType (MediaTypeAudio); media->setTransportType (TransportTypeRTP); media->setPort (6050); state->localSD.addMedia (media); // send a reply with connection id and local connection // description information; connection id is bogus (= callId) // and session descriptor is hardcoded state->connectionId = state->callId; crcxPtr->setConnectionId(state->connectionId); crcxPtr->setLocalConnectionDescriptor(state->localSD); // reply with successful response code and string, // transaction id handled by mgcp stack crcxPtr->setResponseCode(RSP_CODE_NORMAL); crcxPtr->setResponseString("OK"); state->callAgent->reply(crcxPtr); state->setState(stateHalfOpen); break; } default: // ignore other messages cout << "received message for which no handling exists\n"; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -