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

📄 sipconnection.cpp

📁 基于sipfoundy 公司开发的sipx协议API
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// // // Copyright (C) 2005, 2006 SIPez LLC// Licensed to SIPfoundry under a Contributor Agreement.//// Copyright (C) 2005, 2006 SIPfoundry Inc.// Licensed by SIPfoundry under the LGPL license.// // Copyright (C) 2004, 2005 Pingtel Corp.// Licensed to SIPfoundry under a Contributor Agreement.// // $$//////////////////////////////////////////////////////////////////////////////// Author: Dan Petrie (dpetrie AT SIPez DOT com)// SYSTEM INCLUDES#ifdef __pingtel_on_posix__#include <stdlib.h>#endif// APPLICATION INCLUDES#include <os/OsQueuedEvent.h>#include <os/OsTimer.h>#include <os/OsUtil.h>#include <net/SipMessageEvent.h>#include <net/SipUserAgent.h>#include <net/NameValueTokenizer.h>#include <net/SdpCodecFactory.h>#include <net/Url.h>#include <net/SipSession.h>#include <net/NetBase64Codec.h>#include <cp/SipConnection.h>#include <mi/CpMediaInterface.h>#include <cp/CallManager.h>#include <cp/CpCallManager.h>#include <cp/CpPeerCall.h>#include <cp/CpMultiStringMessage.h>#include <cp/CpIntMessage.h>#if defined(_VXWORKS)#include <inetLib.h>#endif#include "ptapi/PtCall.h"#include <net/TapiMgr.h>// EXTERNAL FUNCTIONS// EXTERNAL VARIABLES// CONSTANTS#define CALL_STATUS_FIELD "status"#ifdef _WIN32#   define CALL_CONTROL_TONES#endif// STATIC VARIABLE INITIALIZATIONS/* //////////////////////////// PUBLIC //////////////////////////////////// *//* ============================ CREATORS ================================== */// ConstructorSipConnection::SipConnection(const char* outboundLineAddress,                             UtlBoolean isEarlyMediaFor180Enabled,                             CpCallManager* callMgr,                             CpCall* call,                             CpMediaInterface* mediaInterface,                             //UiContext* callUiContext,                             SipUserAgent* sipUA,                             int offeringDelayMilliSeconds,                             int sessionReinviteTimer,                             int availableBehavior,                             const char* forwardUnconditionalUrl,                             int busyBehavior,                             const char* forwardOnBusyUrl)                             : Connection(callMgr, call, mediaInterface, offeringDelayMilliSeconds,                             availableBehavior, forwardUnconditionalUrl,                             busyBehavior, forwardOnBusyUrl)                             , inviteFromThisSide(0)                             , mIsEarlyMediaFor180(TRUE)                             , mContactId(0){    sipUserAgent = sipUA;    inviteMsg = NULL;    mReferMessage = NULL;    lastLocalSequenceNumber = 0;    lastRemoteSequenceNumber = -1;    reinviteState = ACCEPT_INVITE;    mIsEarlyMediaFor180 = isEarlyMediaFor180Enabled;    // Build a from tag    int fromTagInt = rand();    char fromTagBuffer[60];    sprintf(fromTagBuffer, "%dc%d", call->getCallIndex(), fromTagInt);    mFromTag = fromTagBuffer;    if(outboundLineAddress)    {        mFromUrl = outboundLineAddress;        // Before adding the from tag, construct the local contact with the        // device's NAT friendly contact information (getContactUri).  The host        // and port from that replaces the public address or record host and        // port.  The UserId and URL parameters should be retained.        UtlString contactHostPort;        UtlString address;        Url tempUrl(mFromUrl);        sipUserAgent->getContactUri(&contactHostPort);        Url hostPort(contactHostPort);        hostPort.getHostAddress(address);        tempUrl.setHostAddress(address);        tempUrl.setHostPort(hostPort.getHostPort());        tempUrl.toString(mLocalContact);        // Set the from tag in case this is an outbound call        // If this is an in bound call, the from URL will get        // over written by the To field from the SIP request        mFromUrl.setFieldParameter("tag", mFromTag);    }    mDefaultSessionReinviteTimer = sessionReinviteTimer;    mSessionReinviteTimer = 0;#ifdef TEST_PRINT    osPrintf("SipConnection::mDefaultSessionReinviteTimer = %d\n",        mDefaultSessionReinviteTimer);#endif    mIsReferSent = FALSE;    mIsAcceptSent = FALSE;    mbCancelling = FALSE;        // this is the flag that indicates CANCEL is sent    // but no response has been received  if set to TRUE    // State variable which indicates an action to    // perform after hold has completed.    mHoldCompleteAction = CpCallManager::CP_UNSPECIFIED;#ifdef TEST_PRINT    UtlString callId;    if (mpCall)      mpCall->getCallId(callId);      if (!callId.isNull())        OsSysLog::add(FAC_CP, PRI_DEBUG, "Leaving SipConnection constructor: %s\n", callId.data());    else        OsSysLog::add(FAC_CP, PRI_DEBUG, "Leaving SipConnection constructor: call is Null\n");#endif}// Copy constructorSipConnection::SipConnection(const SipConnection& rSipConnection){}// DestructorSipConnection::~SipConnection(){    UtlString callId;#ifdef TEST_PRINT    if (mpCall) {        mpCall->getCallId(callId);        OsSysLog::add(FAC_CP, PRI_DEBUG, "Entering SipConnection destructor: %s\n", callId.data());    } else        OsSysLog::add(FAC_CP, PRI_DEBUG, "Entering SipConnection destructor: call is Null\n");#endif    if(inviteMsg)    {        delete inviteMsg;        inviteMsg = NULL;    }    if(mReferMessage)    {        delete mReferMessage;        mReferMessage = NULL;    }#ifdef TEST_PRINT    if (!callId.isNull())        OsSysLog::add(FAC_CP, PRI_DEBUG, "Leaving SipConnection destructor: %s\n", callId.data());    else        OsSysLog::add(FAC_CP, PRI_DEBUG, "Leaving SipConnection destructor: call is Null\n");#endif    if ((mpMediaInterface) && (mConnectionId != -1))    {       mpMediaInterface->deleteConnection( mConnectionId );           }    mConnectionId = -1;}/* ============================ MANIPULATORS ============================== */// Assignment operatorSipConnection&SipConnection::operator=(const SipConnection& rhs){    if (this == &rhs)            // handle the assignment to self case        return *this;    return *this;}UtlBoolean SipConnection::dequeue(UtlBoolean callInFocus){    UtlBoolean connectionDequeued = FALSE;#ifdef TEST_PRINT    osPrintf("Connection::dequeue this: %p inviteMsg: %p\n", this, inviteMsg);#endif    if(getState() == CONNECTION_QUEUED)    {        int tagNum = -1;        proceedToRinging(inviteMsg, sipUserAgent, tagNum, mLineAvailableBehavior);        setState(CONNECTION_ALERTING, CONNECTION_LOCAL);        /** SIPXTAPI: TBD **/        connectionDequeued = TRUE;    }    return(connectionDequeued);}UtlBoolean SipConnection::requestShouldCreateConnection(const SipMessage* sipMsg,                                                        SipUserAgent& sipUa,                                                        SdpCodecFactory* codecFactory){    UtlBoolean createConnection = FALSE;    UtlString method;    sipMsg->getRequestMethod(&method);    UtlString toField;    UtlString address;    UtlString protocol;    int port;    UtlString user;    UtlString userLabel;    UtlString tag;    sipMsg->getToAddress(&address, &port, &protocol, &user, &userLabel, &tag);    // Dangling or delated ACK    if(method.compareTo(SIP_ACK_METHOD) == 0)    {        // Ignore it and do not create a connection        createConnection = FALSE;    }    // INVITE to create a connection    //if to tag is already set then return 481 error    else if(method.compareTo(SIP_INVITE_METHOD) == 0 && tag.isNull())    {        // Assume the best case, as this will be checked        // again before the call is answered        UtlBoolean atLeastOneCodecSupported = TRUE;        if(codecFactory == NULL ||            codecFactory->getCodecCount() == 0)            atLeastOneCodecSupported = TRUE;        // Verify that we have some RTP codecs in common        else        {            // Get the SDP and findout if there are any            // codecs in common            UtlString rtpAddress;            int rtpPort;            int rtcpPort;            int videoRtpPort;            int videoRtcpPort;            const SdpBody* bodyPtr = sipMsg->getSdpBody();            if(bodyPtr)            {                int numMatchingCodecs = 0;                SdpCodec** matchingCodecs = NULL;                bodyPtr->getBestAudioCodecs(*codecFactory,                    numMatchingCodecs,                    matchingCodecs,                    rtpAddress, rtpPort, rtcpPort,                    videoRtpPort, videoRtcpPort);                if(numMatchingCodecs > 0)                {                    // Need to cleanup the codecs                    for(int codecIndex = 0; codecIndex < numMatchingCodecs; codecIndex++)                    {                        delete matchingCodecs[codecIndex];                        matchingCodecs[codecIndex] = NULL;                    }                    delete[] matchingCodecs;                    atLeastOneCodecSupported = TRUE;                }                else                {                    atLeastOneCodecSupported = FALSE;                    // Send back a bad media error                    // There are no codecs in common                    SipMessage badMediaResponse;                    badMediaResponse.setInviteBadCodecs(sipMsg, &sipUa);                    sipUa.send(badMediaResponse);                }            }            // Assume that SDP will be sent in ACK            else                atLeastOneCodecSupported = TRUE;        }        if(atLeastOneCodecSupported)        {            // Create a new connection            createConnection = TRUE;        }        else        {            createConnection = FALSE;#ifdef TEST_PRINT            osPrintf("SipConnection::requestShouldCreateConnection FALSE INVITE with no supported RTP codecs\n");#endif        }    }    // NOTIFY for REFER    // a non-existing transaction.    else if(method.compareTo(SIP_NOTIFY_METHOD) == 0)    {        UtlString eventType;        sipMsg->getEventField(eventType);        eventType.toLower();        int typeIndex = eventType.index(SIP_EVENT_REFER);        if(typeIndex >=0)        {            // Send a bad callId/transaction message            SipMessage badTransactionMessage;            badTransactionMessage.setBadTransactionData(sipMsg);            sipUa.send(badTransactionMessage);        }        // All other NOTIFY events are ignored        createConnection = FALSE;    }    else if(method.compareTo(SIP_REFER_METHOD) == 0)    {        createConnection = TRUE;    }    // All other methods: this is part of    // a non-existing transaction.    else    {        // Send a bad callId/transaction message        SipMessage badTransactionMessage;        badTransactionMessage.setBadTransactionData(sipMsg);        sipUa.send(badTransactionMessage);        createConnection = FALSE;    }    return createConnection;}UtlBoolean SipConnection::shouldCreateConnection(SipUserAgent& sipUa,                                                 OsMsg& eventMessage,                                                 SdpCodecFactory* codecFactory){    UtlBoolean createConnection = FALSE;    int msgType = eventMessage.getMsgType();    int msgSubType = eventMessage.getMsgSubType();    const SipMessage* sipMsg = NULL;    int messageType;    if(msgType == OsMsg::PHONE_APP &&        msgSubType == CallManager::CP_SIP_MESSAGE)    {        sipMsg = ((SipMessageEvent&)eventMessage).getMessage();        messageType = ((SipMessageEvent&)eventMessage).getMessageStatus();#ifdef TEST_PRINT        osPrintf("SipConnection::messageType: %d\n", messageType);#endif        switch(messageType)        {            // This is a request which failed to get sent        case SipMessageEvent::TRANSPORT_ERROR:        case SipMessageEvent::SESSION_REINVITE_TIMER:        case SipMessageEvent::AUTHENTICATION_RETRY:            // Ignore it and do not create a connection            createConnection = FALSE;

⌨️ 快捷键说明

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