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 <opal/buildopts.h>
00044 #include <opal/rtpconn.h>
00045 #include <sip/sippdu.h>
00046 #include <sip/handlers.h>
00047
00048 #if OPAL_VIDEO
00049 #include <opal/pcss.h>
00050 #include <codec/vidcodec.h>
00051 #endif
00052
00053 #if OPAL_HAS_IM
00054 #include <im/sipim.h>
00055 #include <im/rfc4103.h>
00056 #endif
00057
00058 class OpalCall;
00059 class SIPEndPoint;
00060
00061
00065 #define OPAL_OPT_OFFER_SDP_PTIME "Offer-SDP-PTime"
00066
00070 #define OPAL_OPT_REFER_SUB "Refer-Sub"
00071
00077 #define OPAL_OPT_PRACK_MODE "PRACK-Mode"
00078
00082 #define OPAL_OPT_INITIAL_OFFER "Initial-Offer"
00083
00099 #define OPAL_OPT_SYMMETRIC_HOLD_PRODUCT "Symmetric-Hold-Product"
00100
00111 #define OPAL_OPT_EXTERNAL_SDP "External-SDP"
00112
00113 #define SIP_HEADER_PREFIX "SIP-Header:"
00114 #define SIP_HEADER_REPLACES SIP_HEADER_PREFIX"Replaces"
00115 #define SIP_HEADER_REFERRED_BY SIP_HEADER_PREFIX"Referred-By"
00116 #define SIP_HEADER_CONTACT SIP_HEADER_PREFIX"Contact"
00117
00118 #define OPAL_SIP_REFERRED_CONNECTION "Referred-Connection"
00119
00120
00122
00126 class SIPConnection : public OpalRTPConnection
00127 {
00128 PCLASSINFO(SIPConnection, OpalRTPConnection);
00129 public:
00130
00135 SIPConnection(
00136 OpalCall & call,
00137 SIPEndPoint & endpoint,
00138 const PString & token,
00139 const SIPURL & address,
00140 OpalTransport * transport,
00141 unsigned int options = 0,
00142 OpalConnection::StringOptions * stringOptions = NULL
00143 );
00144
00147 ~SIPConnection();
00149
00160 virtual bool IsNetworkConnection() const { return true; }
00161
00164 virtual PString GetPrefixName() const;
00165
00168 virtual PString GetIdentifier() const;
00169
00171 virtual void OnApplyStringOptions();
00172
00179 virtual PBoolean SetUpConnection();
00180
00187 virtual PString GetDestinationAddress();
00188
00196 virtual PString GetCalledPartyURL();
00197
00211 virtual PString GetAlertingType() const;
00212
00226 virtual bool SetAlertingType(const PString & info);
00227
00235 virtual PString GetCallInfo() const;
00236
00257 virtual bool TransferConnection(
00258 const PString & remoteParty
00259 );
00260
00268 virtual bool Hold(
00269 bool fromRemote,
00270 bool placeOnHold
00271 );
00272
00277 virtual bool IsOnHold(
00278 bool fromRemote
00279 );
00280
00291 virtual PBoolean SetAlerting(
00292 const PString & calleeName,
00293 PBoolean withMedia
00294 );
00295
00300 virtual PBoolean SetConnected();
00301
00304 virtual OpalMediaFormatList GetMediaFormats() const;
00305
00308 virtual OpalMediaStreamPtr OpenMediaStream(
00309 const OpalMediaFormat & mediaFormat,
00310 unsigned sessionID,
00311 bool isSource
00312 );
00313
00318 virtual bool CloseMediaStream(
00319 OpalMediaStream & stream
00320 );
00321
00324 virtual void OnPauseMediaStream(
00325 OpalMediaStream & strm,
00326 bool paused
00327 );
00328
00346 virtual void OnReleased();
00347
00357 virtual PBoolean ForwardCall(
00358 const PString & forwardParty
00359 );
00360
00366 virtual SendUserInputModes GetRealSendUserInputMode() const;
00367
00374 virtual PBoolean SendUserInputString(
00375 const PString & value
00376 );
00377
00394 PBoolean SendUserInputTone(char tone, unsigned duration);
00395
00403 virtual void OnRTPStatistics(
00404 const RTP_Session & session
00405 ) const;
00407
00412 virtual void OnTransactionFailed(
00413 SIPTransaction & transaction
00414 );
00415
00418 virtual void OnReceivedPDU(SIP_PDU & pdu);
00419
00422 virtual void OnReceivedINVITE(SIP_PDU & pdu);
00423
00426 virtual void OnReceivedReINVITE(SIP_PDU & pdu);
00427
00430 virtual void OnReceivedACK(SIP_PDU & pdu);
00431
00434 virtual void OnReceivedOPTIONS(SIP_PDU & pdu);
00435
00438 virtual void OnReceivedNOTIFY(SIP_PDU & pdu);
00439
00443 virtual void OnAllowedEventNotify(
00444 const PString & eventName
00445 );
00446
00449 virtual void OnReceivedREFER(SIP_PDU & pdu);
00450
00453 virtual void OnReceivedINFO(SIP_PDU & pdu);
00454
00457 virtual void OnReceivedPING(SIP_PDU & pdu);
00458
00461 virtual void OnReceivedPRACK(SIP_PDU & pdu);
00462
00465 virtual void OnReceivedBYE(SIP_PDU & pdu);
00466
00469 virtual void OnReceivedCANCEL(SIP_PDU & pdu);
00470
00475 virtual void OnReceivedResponseToINVITE(
00476 SIPTransaction & transaction,
00477 SIP_PDU & response
00478 );
00479
00482 virtual void OnReceivedResponse(
00483 SIPTransaction & transaction,
00484 SIP_PDU & response
00485 );
00486
00489 virtual void OnReceivedTrying(
00490 SIPTransaction & transaction,
00491 SIP_PDU & response
00492 );
00493
00496 virtual void OnReceivedRinging(SIP_PDU & pdu);
00497
00500 virtual void OnReceivedSessionProgress(SIP_PDU & pdu);
00501
00505 virtual PBoolean OnReceivedAuthenticationRequired(
00506 SIPTransaction & transaction,
00507 SIP_PDU & response
00508 );
00509
00512 virtual void OnReceivedRedirection(SIP_PDU & pdu);
00513
00517 virtual void OnReceivedOK(
00518 SIPTransaction & transaction,
00519 SIP_PDU & response
00520 );
00521
00524 virtual void OnCreatingINVITE(SIPInvite & pdu);
00525
00526 enum TypeOfINVITE {
00527 IsNewINVITE,
00528 IsDuplicateINVITE,
00529 IsReINVITE,
00530 IsLoopedINVITE
00531 };
00532
00534 TypeOfINVITE CheckINVITE(
00535 const SIP_PDU & pdu
00536 ) const;
00537
00543 bool SendOPTIONS(
00544 const SIPOptions::Params & params,
00545 SIP_PDU * reply = NULL
00546 );
00547
00553 bool SendINFO(
00554 const SIPInfo::Params & params,
00555 SIP_PDU * reply = NULL
00556 );
00558
00559 OpalTransportAddress GetDefaultSDPConnectAddress(WORD port = 0) const;
00560
00561 OpalTransport & GetTransport() const { return *transport; }
00562 bool SetTransport(const SIPURL & destination);
00563
00564 SIPEndPoint & GetEndPoint() const { return endpoint; }
00565 SIPDialogContext & GetDialog() { return m_dialog; }
00566 const SIPDialogContext & GetDialog() const { return m_dialog; }
00567 SIPAuthentication * GetAuthenticator() const { return m_authentication; }
00568
00570 enum PRACKMode {
00571 e_prackDisabled,
00575 e_prackSupported,
00578 e_prackRequired
00582 };
00585 PRACKMode GetPRACKMode() const { return m_prackMode; }
00586
00589 virtual unsigned GetAllowedMethods() const;
00590
00591 #if OPAL_VIDEO
00592
00597 virtual PBoolean OnMediaControlXML(SIP_PDU & pdu);
00598 #endif
00599
00605 virtual bool OnMediaCommand(
00606 OpalMediaStream & stream,
00607 const OpalMediaCommand & command
00608 );
00609
00610 virtual void OnStartTransaction(SIPTransaction & transaction);
00611
00612 virtual void OnReceivedMESSAGE(SIP_PDU & pdu);
00613
00614 P_REMOVE_VIRTUAL_VOID(OnMessageReceived(const SIPURL & , const SIP_PDU & ));
00615 P_REMOVE_VIRTUAL_VOID(OnMessageReceived(const SIP_PDU & ));
00616
00617 #if 0 // OPAL_HAS_IM
00618 virtual bool TransmitExternalIM(
00619 const OpalMediaFormat & format,
00620 RTP_IMFrame & body
00621 );
00622 #endif
00623
00624 PString GetLocalPartyURL() const;
00625
00626 protected:
00627 virtual bool GarbageCollection();
00628 void OnUserInputInlineRFC2833(OpalRFC2833Info & info, INT type);
00629
00630 PDECLARE_NOTIFIER(PTimer, SIPConnection, OnSessionTimeout);
00631 PDECLARE_NOTIFIER(PTimer, SIPConnection, OnInviteResponseRetry);
00632 PDECLARE_NOTIFIER(PTimer, SIPConnection, OnInviteResponseTimeout);
00633
00634 virtual bool OnSendOfferSDP(
00635 OpalRTPSessionManager & rtpSessions,
00636 SDPSessionDescription & sdpOut,
00637 bool offerCurrentOnly
00638 );
00639 virtual bool OnSendOfferSDPSession(
00640 const OpalMediaType & mediaType,
00641 unsigned sessionID,
00642 OpalRTPSessionManager & rtpSessions,
00643 SDPSessionDescription & sdpOut,
00644 bool offerOpenMediaStreamOnly
00645 );
00646
00647 virtual bool OnSendAnswerSDP(
00648 OpalRTPSessionManager & rtpSessions,
00649 SDPSessionDescription & sdpOut
00650 );
00651 virtual bool OnSendAnswerSDPSession(
00652 const SDPSessionDescription & sdpIn,
00653 unsigned sessionIndex,
00654 SDPSessionDescription & sdpOut
00655 );
00656
00657 virtual void OnReceivedAnswerSDP(
00658 SIP_PDU & pdu
00659 );
00660 virtual bool OnReceivedAnswerSDPSession(
00661 SDPSessionDescription & sdp,
00662 unsigned sessionId,
00663 bool & multipleFormats
00664 );
00665
00666 virtual OpalMediaSession * SetUpMediaSession(
00667 const unsigned rtpSessionId,
00668 const OpalMediaType & mediaType,
00669 const SDPMediaDescription & mediaDescription,
00670 OpalTransportAddress & localAddress,
00671 bool & remoteChanged
00672 );
00673
00674 bool SendReINVITE(PTRACE_PARAM(const char * msg));
00675 bool StartPendingReINVITE();
00676
00677 friend class SIPInvite;
00678 static PBoolean WriteINVITE(OpalTransport & transport, void * param);
00679 bool WriteINVITE();
00680
00681 virtual bool SendInviteOK();
00682 virtual PBoolean SendInviteResponse(
00683 SIP_PDU::StatusCodes code,
00684 const SDPSessionDescription * sdp = NULL
00685 );
00686 virtual void AdjustInviteResponse(
00687 SIP_PDU & response
00688 );
00689
00690 void UpdateRemoteAddresses();
00691
00692 void NotifyDialogState(
00693 SIPDialogNotification::States state,
00694 SIPDialogNotification::Events eventType = SIPDialogNotification::NoEvent,
00695 unsigned eventCode = 0
00696 );
00697
00698
00699
00700 SIPEndPoint & endpoint;
00701 OpalTransport * transport;
00702 bool deleteTransport;
00703 unsigned m_allowedMethods;
00704 PStringList m_allowedEvents;
00705
00706 enum HoldState {
00707 eHoldOff,
00708 eRetrieveInProgress,
00709
00710
00711 eHoldOn,
00712 eHoldInProgress
00713 };
00714 HoldState m_holdToRemote;
00715 bool m_holdFromRemote;
00716 PString m_forwardParty;
00717 SIPURL m_contactAddress;
00718 SIPURL m_ciscoRemotePartyID;
00719
00720 SIP_PDU * originalInvite;
00721 PTime originalInviteTime;
00722 time_t m_sdpSessionId;
00723 unsigned m_sdpVersion;
00724 bool m_needReINVITE;
00725 bool m_handlingINVITE;
00726 bool m_resolveMultipleFormatReINVITE;
00727 bool m_symmetricOpenStream;
00728 SIPDialogContext m_dialog;
00729 OpalGloballyUniqueID m_dialogNotifyId;
00730 int m_appearanceCode;
00731 PString m_alertInfo;
00732 SIPAuthentication * m_authentication;
00733 unsigned m_authenticateErrors;
00734 PTimer sessionTimer;
00735
00736 std::map<SIP_PDU::Methods, unsigned> m_lastRxCSeq;
00737
00738 PRACKMode m_prackMode;
00739 bool m_prackEnabled;
00740 unsigned m_prackSequenceNumber;
00741 queue<SIP_PDU> m_responsePackets;
00742 PTimer m_responseFailTimer;
00743 PTimer m_responseRetryTimer;
00744 unsigned m_responseRetryCount;
00745
00746 bool m_referInProgress;
00747 PSafeList<SIPTransaction> forkedInvitations;
00748 PSafeList<SIPTransaction> pendingInvitations;
00749 PSafeList<SIPTransaction> m_pendingTransactions;
00750
00751 #if OPAL_FAX
00752 bool m_switchedToT38;
00753 #endif
00754
00755 enum {
00756 ReleaseWithBYE,
00757 ReleaseWithCANCEL,
00758 ReleaseWithResponse,
00759 ReleaseWithNothing,
00760 } releaseMethod;
00761
00762 OpalMediaFormatList m_remoteFormatList;
00763 OpalMediaFormatList m_answerFormatList;
00764 bool SetRemoteMediaFormats(SDPSessionDescription * sdp);
00765
00766 std::map<std::string, SIP_PDU *> m_responses;
00767
00768 #if OPAL_HAS_IM
00769 PSafePtr<OpalSIPIMContext> m_imContext;
00770 #endif
00771
00772 enum {
00773 UserInputMethodUnknown,
00774 ReceivedRFC2833,
00775 ReceivedINFO
00776 } m_receivedUserInputMethod;
00777
00778 private:
00779 P_REMOVE_VIRTUAL_VOID(OnCreatingINVITE(SIP_PDU&));
00780 P_REMOVE_VIRTUAL_VOID(OnReceivedTrying(SIP_PDU &));
00781
00782 friend class SIPTransaction;
00783 friend class SIP_RTP_Session;
00784 };
00785
00786
00789 class SIP_RTP_Session : public RTP_UserData
00790 {
00791 PCLASSINFO(SIP_RTP_Session, RTP_UserData);
00792
00797 SIP_RTP_Session(
00798 SIPConnection & connection
00799 );
00801
00810 virtual void OnTxStatistics(
00811 const RTP_Session & session
00812 ) const;
00813
00820 virtual void OnRxStatistics(
00821 const RTP_Session & session
00822 ) const;
00823
00824 #if OPAL_VIDEO
00825
00829 virtual void OnRxIntraFrameRequest(
00830 const RTP_Session & session
00831 ) const;
00832
00836 virtual void OnTxIntraFrameRequest(
00837 const RTP_Session & session
00838 ) const;
00839 #endif
00840
00841
00842 virtual void SessionFailing(RTP_Session & );
00843
00844 protected:
00845 SIPConnection & connection;
00846 };
00847
00848
00849 #endif // OPAL_SIP
00850
00851 #endif // OPAL_SIP_SIPCON_H
00852
00853
00854