00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef OPAL_SIP_SIPCON_H
00033 #define OPAL_SIP_SIPCON_H
00034
00035 #ifdef P_USE_PRAGMA
00036 #pragma interface
00037 #endif
00038
00039 #include <opal/buildopts.h>
00040
00041 #if OPAL_SIP
00042
00043 #include <rtp/rtpconn.h>
00044 #include <sip/sippdu.h>
00045 #include <sip/handlers.h>
00046
00047
00048 class OpalSIPIMContext;
00049
00050
00055 #define OPAL_OPT_FORWARD_REFER "Forward-Refer"
00056
00060 #define OPAL_OPT_REFER_SUB "Refer-Sub"
00061
00067 #define OPAL_OPT_PRACK_MODE "PRACK-Mode"
00068
00072 #define OPAL_OPT_INITIAL_OFFER "Initial-Offer"
00073
00089 #define OPAL_OPT_SYMMETRIC_HOLD_PRODUCT "Symmetric-Hold-Product"
00090
00101 #define OPAL_OPT_ALLOW_EARLY_REPLACE "Allow-Early-Replace"
00102
00113 #define OPAL_OPT_EXTERNAL_SDP "External-SDP"
00114
00115 #define SIP_HEADER_PREFIX "SIP-Header:"
00116 #define SIP_HEADER_REPLACES SIP_HEADER_PREFIX"Replaces"
00117 #define SIP_HEADER_REFERRED_BY SIP_HEADER_PREFIX"Referred-By"
00118 #define SIP_HEADER_CONTACT SIP_HEADER_PREFIX"Contact"
00119
00120 #define OPAL_SIP_REFERRED_CONNECTION "Referred-Connection"
00121
00122
00124
00128 class SIPConnection : public OpalRTPConnection, public SIPTransactionOwner
00129 {
00130 PCLASSINFO(SIPConnection, OpalRTPConnection);
00131 public:
00132
00135 struct Init {
00136 Init(OpalCall & call, SIPEndPoint & endpoint)
00137 : m_call(call)
00138 , m_endpoint(endpoint)
00139 , m_userData(NULL)
00140 , m_invite(NULL)
00141 , m_options(0)
00142 , m_stringOptions(NULL)
00143 { }
00144
00145 OpalCall & m_call;
00146 SIPEndPoint & m_endpoint;
00147 PString m_token;
00148 SIPURL m_address;
00149 void * m_userData;
00150 SIP_PDU * m_invite;
00151 unsigned m_options;
00152 OpalConnection::StringOptions * m_stringOptions;
00153 };
00154
00157 SIPConnection(
00158 const Init & init
00159 );
00160
00163 ~SIPConnection();
00165
00176 virtual bool IsNetworkConnection() const { return true; }
00177
00180 virtual PString GetPrefixName() const;
00181
00184 virtual PString GetIdentifier() const;
00185
00187 virtual void OnApplyStringOptions();
00188
00195 virtual PBoolean SetUpConnection();
00196
00199 virtual OpalTransportAddress GetRemoteAddress() const { return m_remoteAddress; }
00200
00207 virtual PString GetDestinationAddress();
00208
00216 virtual PString GetCalledPartyURL();
00217
00231 virtual PString GetAlertingType() const;
00232
00246 virtual bool SetAlertingType(const PString & info);
00247
00255 virtual PString GetCallInfo() const;
00256
00277 virtual bool TransferConnection(
00278 const PString & remoteParty
00279 );
00280
00288 virtual bool Hold(
00289 bool fromRemote,
00290 bool placeOnHold
00291 );
00292
00297 virtual bool IsOnHold(
00298 bool fromRemote
00299 );
00300
00311 virtual PBoolean SetAlerting(
00312 const PString & calleeName,
00313 PBoolean withMedia
00314 );
00315
00320 virtual PBoolean SetConnected();
00321
00324 virtual OpalMediaFormatList GetMediaFormats() const;
00325
00329 virtual bool RequireSymmetricMediaStreams() const;
00330
00331 #if OPAL_T38_CAPABILITY
00332
00334 virtual bool SwitchFaxMediaStreams(
00335 bool toT38
00336 );
00337 #endif
00338
00341 virtual OpalMediaStream * CreateMediaStream(
00342 const OpalMediaFormat & mediaFormat,
00343 unsigned sessionID,
00344 PBoolean isSource
00345 );
00346
00349 virtual OpalMediaStreamPtr OpenMediaStream(
00350 const OpalMediaFormat & mediaFormat,
00351 unsigned sessionID,
00352 bool isSource
00353 );
00354
00359 virtual void OnClosedMediaStream(
00360 const OpalMediaStream & stream
00361 );
00362
00372 virtual bool GetMediaTransportAddresses(
00373 const OpalMediaType & mediaType,
00374 OpalTransportAddressArray & transports
00375 ) const;
00376
00385 virtual void OnPatchMediaStream(
00386 PBoolean isSource,
00387 OpalMediaPatch & patch
00388 );
00389
00392 virtual void OnPauseMediaStream(
00393 OpalMediaStream & strm,
00394 bool paused
00395 );
00396
00414 virtual void OnReleased();
00415
00425 virtual PBoolean ForwardCall(
00426 const PString & forwardParty
00427 );
00428
00434 virtual SendUserInputModes GetRealSendUserInputMode() const;
00435
00442 virtual PBoolean SendUserInputString(
00443 const PString & value
00444 );
00445
00462 PBoolean SendUserInputTone(char tone, unsigned duration);
00464
00469 virtual void OnTransactionFailed(
00470 SIPTransaction & transaction
00471 );
00472
00475 virtual void OnReceivedPDU(SIP_PDU & pdu);
00476
00479 virtual void OnReceivedINVITE(SIP_PDU & pdu);
00480
00483 virtual void OnReceivedReINVITE(SIP_PDU & pdu);
00484
00487 virtual void OnReceivedACK(SIP_PDU & pdu);
00488
00491 virtual void OnReceivedOPTIONS(SIP_PDU & pdu);
00492
00495 virtual void OnReceivedNOTIFY(SIP_PDU & pdu);
00496
00500 virtual void OnAllowedEventNotify(
00501 const PString & eventName
00502 );
00503
00506 virtual void OnReceivedREFER(SIP_PDU & pdu);
00507
00510 virtual void OnReceivedINFO(SIP_PDU & pdu);
00511
00514 virtual void OnReceivedPING(SIP_PDU & pdu);
00515
00518 virtual void OnReceivedPRACK(SIP_PDU & pdu);
00519
00522 virtual void OnReceivedBYE(SIP_PDU & pdu);
00523
00526 virtual void OnReceivedCANCEL(SIP_PDU & pdu);
00527
00532 virtual bool OnReceivedResponseToINVITE(
00533 SIPTransaction & transaction,
00534 SIP_PDU & response
00535 );
00536
00539 virtual void OnReceivedResponse(
00540 SIPTransaction & transaction,
00541 SIP_PDU & response
00542 );
00543
00546 virtual void OnReceivedTrying(
00547 SIPTransaction & transaction,
00548 SIP_PDU & response
00549 );
00550
00553 virtual void OnReceivedRinging(SIPTransaction & transaction, SIP_PDU & pdu);
00554
00557 virtual void OnReceivedSessionProgress(SIPTransaction & transaction, SIP_PDU & pdu);
00558
00562 virtual PBoolean OnReceivedAuthenticationRequired(
00563 SIPTransaction & transaction,
00564 SIP_PDU & response
00565 );
00566
00569 virtual void OnReceivedRedirection(SIP_PDU & pdu);
00570
00574 virtual void OnReceivedOK(
00575 SIPTransaction & transaction,
00576 SIP_PDU & response
00577 );
00578
00581 virtual void OnCreatingINVITE(SIPInvite & pdu);
00582
00583 enum TypeOfINVITE {
00584 IsNewINVITE,
00585 IsDuplicateINVITE,
00586 IsReINVITE,
00587 IsLoopedINVITE
00588 };
00589
00591 TypeOfINVITE CheckINVITE(
00592 const SIP_PDU & pdu
00593 ) const;
00594
00600 bool SendOPTIONS(
00601 const SIPOptions::Params & params,
00602 SIP_PDU * reply = NULL
00603 );
00604
00610 bool SendINFO(
00611 const SIPInfo::Params & params,
00612 SIP_PDU * reply = NULL
00613 );
00615
00616 OpalTransportAddress GetDefaultSDPConnectAddress(WORD port = 0) const;
00617
00618 SIPEndPoint & GetEndPoint() const { return SIPTransactionOwner::m_endpoint; }
00619 SIPAuthentication * GetAuthenticator() const { return m_authentication; }
00620
00622 enum PRACKMode {
00623 e_prackDisabled,
00627 e_prackSupported,
00630 e_prackRequired
00634 };
00637 PRACKMode GetPRACKMode() const { return m_prackMode; }
00638
00641 virtual unsigned GetAllowedMethods() const;
00642
00645 bool DoesRemoteAllowMethod(SIP_PDU::Methods method) const { return (m_allowedMethods&(1<<method)) != 0; }
00646
00647 #if OPAL_VIDEO
00648
00653 virtual PBoolean OnMediaControlXML(SIP_PDU & pdu);
00654 #endif
00655
00661 virtual bool OnMediaCommand(
00662 OpalMediaStream & stream,
00663 const OpalMediaCommand & command
00664 );
00665
00666
00667 virtual PString GetAuthID() const;
00668
00669
00670 virtual void OnStartTransaction(SIPTransaction & transaction);
00671 virtual void OnReceivedMESSAGE(SIP_PDU & pdu);
00672 virtual void OnReceivedSUBSCRIBE(SIP_PDU & pdu);
00673
00674 PString GetLocalPartyURL() const;
00675
00676 virtual void PrintOn(ostream & strm) const { OpalRTPConnection::PrintOn(strm); }
00677
00678 protected:
00679 virtual bool GarbageCollection();
00680 typedef SIPPoolTimer<SIPConnection> PoolTimer;
00681 void OnSessionTimeout();
00682 void OnInviteResponseRetry();
00683 void OnInviteResponseTimeout();
00684 void OnInviteCollision();
00685
00686 virtual bool OnSendOfferSDP(
00687 SDPSessionDescription & sdpOut,
00688 bool offerCurrentOnly
00689 );
00690 virtual bool OnSendOfferSDPSession(
00691 unsigned sessionID,
00692 SDPSessionDescription & sdpOut,
00693 bool offerOpenMediaStreamOnly
00694 );
00695
00696 virtual bool OnSendAnswerSDP(
00697 SDPSessionDescription & sdpOut
00698 );
00699 virtual bool OnSendAnswerSDP(
00700 const SDPSessionDescription & sdpOffer,
00701 SDPSessionDescription & sdpAnswer
00702 );
00703 virtual bool OnSendAnswerSDPSession(
00704 const SDPSessionDescription & sdpIn,
00705 unsigned sessionIndex,
00706 SDPSessionDescription & sdpOut
00707 );
00708
00709 virtual void OnReceivedAnswerSDP(
00710 SIP_PDU & response,
00711 SIPTransaction * transaction
00712 );
00713 virtual bool OnReceivedAnswerSDPSession(
00714 SDPSessionDescription & sdp,
00715 unsigned sessionId,
00716 bool & multipleFormats
00717 );
00718
00719 virtual OpalMediaSession * SetUpMediaSession(
00720 const unsigned rtpSessionId,
00721 const OpalMediaType & mediaType,
00722 const SDPMediaDescription & mediaDescription,
00723 OpalTransportAddress & localAddress,
00724 bool & remoteChanged
00725 );
00726
00727 bool SendReINVITE(PTRACE_PARAM(const char * msg));
00728 bool StartPendingReINVITE();
00729
00730 friend class SIPInvite;
00731 PDECLARE_WriteConnectCallback(SIPConnection, WriteINVITE);
00732
00733 virtual void SendDelayedACK(bool force);
00734 void OnDelayedAckTimeout();
00735
00736 virtual bool SendInviteOK();
00737 virtual PBoolean SendInviteResponse(
00738 SIP_PDU::StatusCodes code,
00739 const SDPSessionDescription * sdp = NULL
00740 );
00741 virtual void AdjustInviteResponse(
00742 SIP_PDU & response
00743 );
00744
00745 void UpdateRemoteAddresses();
00746 #if OPAL_SRTP
00747 virtual bool CanDoSRTP() const { return m_dialog.GetRemoteTransportAddress(m_dnsEntry).GetProtoPrefix() == OpalTransportAddress::TlsPrefix(); }
00748 #endif
00749
00750 void NotifyDialogState(
00751 SIPDialogNotification::States state,
00752 SIPDialogNotification::Events eventType = SIPDialogNotification::NoEvent,
00753 unsigned eventCode = 0
00754 );
00755
00756 virtual bool InviteConferenceParticipant(const PString & conf, const PString & dest);
00757
00758
00759 unsigned m_allowedMethods;
00760 PStringSet m_allowedEvents;
00761
00762 enum HoldState {
00763 eHoldOff,
00764 eRetrieveInProgress,
00765
00766
00767 eHoldOn,
00768 eHoldInProgress
00769 };
00770 HoldState m_holdToRemote;
00771 bool m_holdFromRemote;
00772 PString m_forwardParty;
00773 OpalTransportAddress m_remoteAddress;
00774 SIPURL m_contactAddress;
00775 SIPURL m_ciscoRemotePartyID;
00776
00777 SIP_PDU * m_lastReceivedINVITE;
00778 SIP_PDU * m_delayedAckInviteResponse;
00779 PoolTimer m_delayedAckTimer;
00780 PTimeInterval m_delayedAckTimeout;
00781 SIP_PDU * m_lastSentAck;
00782 time_t m_sdpSessionId;
00783 unsigned m_sdpVersion;
00784 bool m_needReINVITE;
00785 bool m_handlingINVITE;
00786 bool m_resolveMultipleFormatReINVITE;
00787 bool m_symmetricOpenStream;
00788 OpalGloballyUniqueID m_dialogNotifyId;
00789 int m_appearanceCode;
00790 PString m_alertInfo;
00791 PoolTimer m_sessionTimer;
00792
00793 std::map<SIP_PDU::Methods, unsigned> m_lastRxCSeq;
00794
00795 PRACKMode m_prackMode;
00796 bool m_prackEnabled;
00797 unsigned m_prackSequenceNumber;
00798 std::queue<SIP_PDU> m_responsePackets;
00799 PoolTimer m_responseFailTimer;
00800 PoolTimer m_responseRetryTimer;
00801 unsigned m_responseRetryCount;
00802 PoolTimer m_inviteCollisionTimer;
00803
00804 bool m_referInProgress;
00805 PSafeList<SIPTransaction> m_forkedInvitations;
00806 PSafeList<SIPTransaction> m_pendingInvitations;
00807
00808 enum {
00809 ReleaseWithBYE,
00810 ReleaseWithCANCEL,
00811 ReleaseWithResponse,
00812 ReleaseWithNothing,
00813 } releaseMethod;
00814
00815 OpalMediaFormatList m_remoteFormatList;
00816 OpalMediaFormatList m_answerFormatList;
00817 bool SetRemoteMediaFormats(SIP_PDU * pdu);
00818
00819 std::map<std::string, SIP_PDU *> m_responses;
00820
00821 #if OPAL_HAS_SIPIM
00822 PSafePtr<OpalSIPIMContext> m_imContext;
00823 #endif
00824
00825 #if OPAL_VIDEO
00826 PSimpleTimer m_infoPictureFastUpdateTimer;
00827 #endif
00828
00829 enum {
00830 UserInputMethodUnknown,
00831 ReceivedRFC2833,
00832 ReceivedINFO
00833 } m_receivedUserInputMethod;
00834 void OnUserInputInlineRFC2833(OpalRFC2833Info & info, INT type);
00835
00836
00837 private:
00838 P_REMOVE_VIRTUAL_VOID(OnCreatingINVITE(SIP_PDU&));
00839 P_REMOVE_VIRTUAL_VOID(OnReceivedTrying(SIP_PDU &));
00840 P_REMOVE_VIRTUAL_VOID(OnMessageReceived(const SIPURL & , const SIP_PDU & ));
00841 P_REMOVE_VIRTUAL_VOID(OnMessageReceived(const SIP_PDU & ));
00842
00843 friend class SIPTransaction;
00844 friend class SIP_RTP_Session;
00845 };
00846
00847
00848 #endif // OPAL_SIP
00849
00850 #endif // OPAL_SIP_SIPCON_H
00851
00852
00853