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/rfc4103.h>
00055 #endif
00056
00057 class OpalCall;
00058 class SIPEndPoint;
00059
00060
00064 #define OPAL_OPT_OFFER_SDP_PTIME "Offer-SDP-PTime"
00065
00069 #define OPAL_OPT_REFER_SUB "Refer-Sub"
00070
00074 #define OPAL_OPT_INITIAL_OFFER "Initial-Offer"
00075
00086 #define OPAL_OPT_EXTERNAL_SDP "External-SDP"
00087
00088 #define SIP_HEADER_PREFIX "SIP-Header:"
00089 #define SIP_HEADER_REPLACES SIP_HEADER_PREFIX"Replaces"
00090 #define SIP_HEADER_REFERRED_BY SIP_HEADER_PREFIX"Referred-By"
00091 #define SIP_HEADER_CONTACT SIP_HEADER_PREFIX"Contact"
00092
00093 #define OPAL_SIP_REFERRED_CONNECTION "Referred-Connection"
00094
00095
00097
00101 class SIPConnection : public OpalRTPConnection
00102 {
00103 PCLASSINFO(SIPConnection, OpalRTPConnection);
00104 public:
00105
00110 SIPConnection(
00111 OpalCall & call,
00112 SIPEndPoint & endpoint,
00113 const PString & token,
00114 const SIPURL & address,
00115 OpalTransport * transport,
00116 unsigned int options = 0,
00117 OpalConnection::StringOptions * stringOptions = NULL
00118 );
00119
00122 ~SIPConnection();
00124
00135 virtual bool IsNetworkConnection() const { return true; }
00136
00139 virtual PString GetPrefixName() const;
00140
00143 virtual PString GetIdentifier() const;
00144
00151 virtual PBoolean SetUpConnection();
00152
00159 virtual PString GetDestinationAddress();
00160
00168 virtual PString GetCalledPartyURL();
00169
00183 virtual PString GetAlertingType() const;
00184
00198 virtual bool SetAlertingType(const PString & info);
00199
00207 virtual PString GetCallInfo() const;
00208
00215 virtual bool TransferConnection(
00216 const PString & remoteParty
00217 );
00218
00226 virtual bool Hold(
00227 bool fromRemote,
00228 bool placeOnHold
00229 );
00230
00235 virtual bool IsOnHold(
00236 bool fromRemote
00237 );
00238
00249 virtual PBoolean SetAlerting(
00250 const PString & calleeName,
00251 PBoolean withMedia
00252 );
00253
00258 virtual PBoolean SetConnected();
00259
00262 virtual OpalMediaFormatList GetMediaFormats() const;
00263
00266 virtual OpalMediaStreamPtr OpenMediaStream(
00267 const OpalMediaFormat & mediaFormat,
00268 unsigned sessionID,
00269 bool isSource
00270 );
00271
00276 virtual bool CloseMediaStream(
00277 OpalMediaStream & stream
00278 );
00279
00282 virtual void OnPauseMediaStream(
00283 OpalMediaStream & strm,
00284 bool paused
00285 );
00286
00304 virtual void OnReleased();
00305
00315 virtual PBoolean ForwardCall(
00316 const PString & forwardParty
00317 );
00318
00324 virtual SendUserInputModes GetRealSendUserInputMode() const;
00325
00342 PBoolean SendUserInputTone(char tone, unsigned duration);
00343
00351 virtual void OnRTPStatistics(
00352 const RTP_Session & session
00353 ) const;
00355
00360 virtual void OnTransactionFailed(
00361 SIPTransaction & transaction
00362 );
00363
00366 virtual void OnReceivedPDU(SIP_PDU & pdu);
00367
00370 virtual void OnReceivedINVITE(SIP_PDU & pdu);
00371
00374 virtual void OnReceivedReINVITE(SIP_PDU & pdu);
00375
00378 virtual void OnReceivedACK(SIP_PDU & pdu);
00379
00382 virtual void OnReceivedOPTIONS(SIP_PDU & pdu);
00383
00386 virtual void OnReceivedNOTIFY(SIP_PDU & pdu);
00387
00391 virtual void OnAllowedEventNotify(
00392 const PString & eventName
00393 );
00394
00397 virtual void OnReceivedREFER(SIP_PDU & pdu);
00398
00401 virtual void OnReceivedINFO(SIP_PDU & pdu);
00402
00405 virtual void OnReceivedPING(SIP_PDU & pdu);
00406
00409 virtual void OnReceivedPRACK(SIP_PDU & pdu);
00410
00413 virtual void OnReceivedBYE(SIP_PDU & pdu);
00414
00417 virtual void OnReceivedCANCEL(SIP_PDU & pdu);
00418
00423 virtual void OnReceivedResponseToINVITE(
00424 SIPTransaction & transaction,
00425 SIP_PDU & response
00426 );
00427
00430 virtual void OnReceivedResponse(
00431 SIPTransaction & transaction,
00432 SIP_PDU & response
00433 );
00434
00437 virtual void OnReceivedTrying(
00438 SIPTransaction & transaction,
00439 SIP_PDU & response
00440 );
00441
00444 virtual void OnReceivedRinging(SIP_PDU & pdu);
00445
00448 virtual void OnReceivedSessionProgress(SIP_PDU & pdu);
00449
00453 virtual PBoolean OnReceivedAuthenticationRequired(
00454 SIPTransaction & transaction,
00455 SIP_PDU & response
00456 );
00457
00460 virtual void OnReceivedRedirection(SIP_PDU & pdu);
00461
00465 virtual void OnReceivedOK(
00466 SIPTransaction & transaction,
00467 SIP_PDU & response
00468 );
00469
00472 virtual void OnCreatingINVITE(SIPInvite & pdu);
00473
00474 enum TypeOfINVITE {
00475 IsNewINVITE,
00476 IsDuplicateINVITE,
00477 IsReINVITE,
00478 IsLoopedINVITE
00479 };
00480
00482 TypeOfINVITE CheckINVITE(
00483 const SIP_PDU & pdu
00484 ) const;
00485
00491 bool SendOPTIONS(
00492 const SIPOptions::Params & params,
00493 SIP_PDU * reply = NULL
00494 );
00495
00501 bool SendINFO(
00502 const SIPInfo::Params & params,
00503 SIP_PDU * reply = NULL
00504 );
00506
00507 OpalTransportAddress GetDefaultSDPConnectAddress(WORD port = 0) const;
00508
00509 OpalTransport & GetTransport() const { return *transport; }
00510 bool SetTransport(const SIPURL & destination);
00511
00512 SIPEndPoint & GetEndPoint() const { return endpoint; }
00513 SIPDialogContext & GetDialog() { return m_dialog; }
00514 const SIPDialogContext & GetDialog() const { return m_dialog; }
00515 SIPAuthentication * GetAuthenticator() const { return m_authentication; }
00516
00517 enum PRACKMode {
00518 e_prackDisabled,
00522 e_prackSupported,
00525 e_prackRequired
00529 };
00532 PRACKMode GetPRACKMode() const { return m_prackMode; }
00533
00534 #if OPAL_VIDEO
00535
00540 virtual PBoolean OnMediaControlXML(SIP_PDU & pdu);
00541 #endif
00542
00543 virtual void OnMediaCommand(OpalMediaCommand & note, INT extra);
00544
00545 virtual void OnStartTransaction(SIPTransaction & transaction);
00546
00547 virtual void OnReceivedMESSAGE(SIP_PDU & pdu);
00548
00549 P_REMOVE_VIRTUAL_VOID(OnMessageReceived(const SIPURL & , const SIP_PDU & ));
00550 P_REMOVE_VIRTUAL_VOID(OnMessageReceived(const SIP_PDU & ));
00551
00552 #if OPAL_HAS_IM
00553 virtual bool TransmitExternalIM(
00554 const OpalMediaFormat & format,
00555 RTP_IMFrame & body
00556 );
00557 #endif
00558
00559 PString GetLocalPartyURL() const;
00560
00561 protected:
00562 virtual bool GarbageCollection();
00563 PDECLARE_NOTIFIER(PTimer, SIPConnection, OnSessionTimeout);
00564 PDECLARE_NOTIFIER(PTimer, SIPConnection, OnInviteResponseRetry);
00565 PDECLARE_NOTIFIER(PTimer, SIPConnection, OnInviteResponseTimeout);
00566
00567 virtual bool OnSendOfferSDP(
00568 OpalRTPSessionManager & rtpSessions,
00569 SDPSessionDescription & sdpOut
00570 );
00571 virtual bool OnSendOfferSDPSession(
00572 const OpalMediaType & mediaType,
00573 unsigned sessionID,
00574 OpalRTPSessionManager & rtpSessions,
00575 SDPSessionDescription & sdpOut,
00576 const OpalMediaFormatList & localMediaFormats,
00577 bool offerOpenMediaStreamOnly
00578 );
00579 virtual bool OnSendAnswerSDP(
00580 OpalRTPSessionManager & rtpSessions,
00581 SDPSessionDescription & sdpOut
00582 );
00583 virtual bool OnSendAnswerSDPSession(
00584 const SDPSessionDescription & sdpIn,
00585 const OpalMediaFormatList & localMediaFormats,
00586 unsigned sessionIndex,
00587 SDPSessionDescription & sdpOut
00588 );
00589
00590 virtual void OnReceivedAnswerSDP(
00591 SIP_PDU & pdu
00592 );
00593 virtual bool OnReceivedAnswerSDPSession(
00594 SDPSessionDescription & sdp,
00595 unsigned sessionId,
00596 const OpalMediaFormatList & localMediaFormats
00597 );
00598
00599 virtual OpalMediaSession * SetUpMediaSession(
00600 const unsigned rtpSessionId,
00601 const OpalMediaType & mediaType,
00602 const SDPMediaDescription & mediaDescription,
00603 OpalTransportAddress & localAddress,
00604 bool & remoteChanged
00605 );
00606
00607 bool SendReINVITE(PTRACE_PARAM(const char * msg));
00608 void StartPendingReINVITE();
00609
00610 friend class SIPInvite;
00611 static PBoolean WriteINVITE(OpalTransport & transport, void * param);
00612 bool WriteINVITE();
00613
00614 virtual bool SendInviteOK();
00615 virtual PBoolean SendInviteResponse(
00616 SIP_PDU::StatusCodes code,
00617 const char * contact = NULL,
00618 const char * extra = NULL,
00619 const SDPSessionDescription * sdp = NULL,
00620 const char * body = NULL
00621 );
00622
00623 void UpdateRemoteAddresses();
00624
00625 void NotifyDialogState(
00626 SIPDialogNotification::States state,
00627 SIPDialogNotification::Events eventType = SIPDialogNotification::NoEvent,
00628 unsigned eventCode = 0
00629 );
00630
00631
00632
00633 SIPEndPoint & endpoint;
00634 OpalTransport * transport;
00635 bool deleteTransport;
00636 unsigned m_allowedMethods;
00637 PStringList m_allowedEvents;
00638
00639 enum HoldState {
00640 eHoldOff,
00641 eRetrieveInProgress,
00642
00643
00644 eHoldOn,
00645 eHoldInProgress
00646 };
00647 HoldState m_holdToRemote;
00648 bool m_holdFromRemote;
00649 PString forwardParty;
00650 SIPURL m_ciscoRemotePartyID;
00651
00652 SIP_PDU * originalInvite;
00653 PTime originalInviteTime;
00654 time_t m_sdpSessionId;
00655 unsigned m_sdpVersion;
00656 bool m_needReINVITE;
00657 bool m_handlingINVITE;
00658 bool m_symmetricOpenStream;
00659 SIPDialogContext m_dialog;
00660 OpalGloballyUniqueID m_dialogNotifyId;
00661 int m_appearanceCode;
00662 PString m_alertInfo;
00663 SIPAuthentication * m_authentication;
00664 unsigned m_authenticatedCseq;
00665 PTimer sessionTimer;
00666
00667 std::map<SIP_PDU::Methods, unsigned> m_lastRxCSeq;
00668
00669 PRACKMode m_prackMode;
00670 bool m_prackEnabled;
00671 unsigned m_prackSequenceNumber;
00672 queue<SIP_PDU> m_responsePackets;
00673 PTimer m_responseFailTimer;
00674 PTimer m_responseRetryTimer;
00675 unsigned m_responseRetryCount;
00676
00677 bool m_referInProgress;
00678 PSafeList<SIPTransaction> forkedInvitations;
00679 PSafeList<SIPTransaction> pendingInvitations;
00680 PSafeList<SIPTransaction> m_pendingTransactions;
00681
00682 #if OPAL_FAX
00683 bool m_switchedToFaxMode;
00684 #endif
00685
00686 enum {
00687 ReleaseWithBYE,
00688 ReleaseWithCANCEL,
00689 ReleaseWithResponse,
00690 ReleaseWithNothing,
00691 } releaseMethod;
00692
00693 OpalMediaFormatList m_remoteFormatList;
00694 OpalMediaFormatList m_answerFormatList;
00695 bool SetRemoteMediaFormats(SDPSessionDescription * sdp);
00696
00697 std::map<std::string, SIP_PDU *> m_responses;
00698
00699 private:
00700 P_REMOVE_VIRTUAL_VOID(OnCreatingINVITE(SIP_PDU&));
00701 P_REMOVE_VIRTUAL_VOID(OnReceivedTrying(SIP_PDU &));
00702
00703 friend class SIPTransaction;
00704 friend class SIP_RTP_Session;
00705 };
00706
00707
00710 class SIP_RTP_Session : public RTP_UserData
00711 {
00712 PCLASSINFO(SIP_RTP_Session, RTP_UserData);
00713
00718 SIP_RTP_Session(
00719 SIPConnection & connection
00720 );
00722
00731 virtual void OnTxStatistics(
00732 const RTP_Session & session
00733 ) const;
00734
00741 virtual void OnRxStatistics(
00742 const RTP_Session & session
00743 ) const;
00744
00745 #if OPAL_VIDEO
00746
00750 virtual void OnRxIntraFrameRequest(
00751 const RTP_Session & session
00752 ) const;
00753
00757 virtual void OnTxIntraFrameRequest(
00758 const RTP_Session & session
00759 ) const;
00760 #endif
00761
00762
00763 virtual void SessionFailing(RTP_Session & );
00764
00765 protected:
00766 SIPConnection & connection;
00767 };
00768
00769
00770 #endif // OPAL_SIP
00771
00772 #endif // OPAL_SIP_SIPCON_H
00773
00774
00775