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 #if OPAL_VIDEO
00048 #include <opal/pcss.h>                  
00049 #include <codec/vidcodec.h>             
00050 #endif
00051 
00052 class OpalCall;
00053 class SIPEndPoint;
00054 
00055 #define SIP_HEADER_PREFIX   "SIP-Header:"
00056 #define SIP_HEADER_REPLACES SIP_HEADER_PREFIX"Replaces"
00057 
00058 
00060 
00063 
00064 class SIPConnection : public OpalRTPConnection
00065 {
00066   PCLASSINFO(SIPConnection, OpalRTPConnection);
00067   public:
00068 
00073     SIPConnection(
00074       OpalCall & call,                          
00075       SIPEndPoint & endpoint,                   
00076       const PString & token,                    
00077       const SIPURL & address,                   
00078       OpalTransport * transport,                
00079       unsigned int options = 0,                 
00080       OpalConnection::StringOptions * stringOptions = NULL  
00081     );
00082 
00085     ~SIPConnection();
00087 
00098     virtual bool IsNetworkConnection() const { return true; }
00099 
00102     virtual PString GetPrefixName() const;
00103 
00106     virtual PString GetIdentifier() const;
00107 
00114     virtual PString GetRemotePartyURL() const;
00115 
00122     virtual PBoolean SetUpConnection();
00123 
00130     virtual PString GetDestinationAddress();
00131 
00139     virtual PString GetCalledPartyURL();
00140 
00154     virtual PString GetAlertingType() const;
00155 
00169     virtual bool SetAlertingType(const PString & info);
00170 
00177     virtual bool TransferConnection(
00178       const PString & remoteParty   
00179     );
00180 
00183     virtual bool HoldConnection();
00184 
00188     virtual bool RetrieveConnection();
00189 
00192     virtual PBoolean IsConnectionOnHold();
00193 
00204     virtual PBoolean SetAlerting(
00205       const PString & calleeName,   
00206       PBoolean withMedia
00207     );
00208 
00213     virtual PBoolean SetConnected();
00214 
00217     virtual OpalMediaFormatList GetMediaFormats() const;
00218     
00221     virtual OpalMediaStreamPtr OpenMediaStream(
00222       const OpalMediaFormat & mediaFormat, 
00223       unsigned sessionID,                  
00224       bool isSource                        
00225     );
00226 
00231     virtual bool CloseMediaStream(
00232       OpalMediaStream & stream  
00233     );
00234 
00252     virtual void OnReleased();
00253 
00263     virtual PBoolean ForwardCall(
00264       const PString & forwardParty   
00265     );
00266 
00272     virtual SendUserInputModes GetRealSendUserInputMode() const;
00273 
00290     PBoolean SendUserInputTone(char tone, unsigned duration);
00291 
00299     virtual void OnRTPStatistics(
00300       const RTP_Session & session         
00301     ) const;
00303 
00308     virtual void OnTransactionFailed(
00309       SIPTransaction & transaction
00310     );
00311 
00314     virtual void OnReceivedPDU(SIP_PDU & pdu);
00315 
00318     virtual void OnReceivedINVITE(SIP_PDU & pdu);
00319 
00322     virtual void OnReceivedReINVITE(SIP_PDU & pdu);
00323 
00326     virtual void OnReceivedACK(SIP_PDU & pdu);
00327   
00330     virtual void OnReceivedOPTIONS(SIP_PDU & pdu);
00331 
00334     virtual void OnReceivedNOTIFY(SIP_PDU & pdu);
00335 
00338     virtual void OnReceivedREFER(SIP_PDU & pdu);
00339   
00342     virtual void OnReceivedINFO(SIP_PDU & pdu);
00343 
00346     virtual void OnReceivedPING(SIP_PDU & pdu);
00347 
00350     virtual void OnReceivedBYE(SIP_PDU & pdu);
00351   
00354     virtual void OnReceivedCANCEL(SIP_PDU & pdu);
00355   
00360     virtual void OnReceivedResponseToINVITE(
00361       SIPTransaction & transaction,
00362       SIP_PDU & response
00363     );
00364 
00367     virtual void OnReceivedResponse(
00368       SIPTransaction & transaction,
00369       SIP_PDU & response
00370     );
00371 
00374     virtual void OnReceivedTrying(
00375       SIPTransaction & transaction,
00376       SIP_PDU & response
00377     );
00378   
00381     virtual void OnReceivedRinging(SIP_PDU & pdu);
00382   
00385     virtual void OnReceivedSessionProgress(SIP_PDU & pdu);
00386   
00390     virtual PBoolean OnReceivedAuthenticationRequired(
00391       SIPTransaction & transaction,
00392       SIP_PDU & response
00393     );
00394   
00397     virtual void OnReceivedRedirection(SIP_PDU & pdu);
00398 
00402     virtual void OnReceivedOK(
00403       SIPTransaction & transaction,
00404       SIP_PDU & response
00405     );
00406   
00409     virtual void OnCreatingINVITE(SIPInvite & pdu);
00410 
00413     virtual PBoolean SendInviteOK(const SDPSessionDescription & sdp);
00414         
00417     virtual PBoolean SendInviteResponse(
00418       SIP_PDU::StatusCodes code,
00419       const char * contact = NULL,
00420       const char * extra = NULL,
00421       const SDPSessionDescription * sdp = NULL
00422     );
00423 
00424     enum TypeOfINVITE {
00425       IsNewINVITE,
00426       IsDuplicateINVITE,
00427       IsReINVITE,
00428       IsLoopedINVITE
00429     };
00430 
00432     TypeOfINVITE CheckINVITE(
00433       const SIP_PDU & pdu
00434     ) const;
00436 
00437     OpalTransportAddress GetDefaultSDPConnectAddress(WORD port = 0) const;
00438 
00439     OpalTransport & GetTransport() const { return *transport; }
00440 
00441     SIPEndPoint & GetEndPoint() const { return endpoint; }
00442     SIPDialogContext & GetDialog() { return m_dialog; }
00443     const SIPDialogContext & GetDialog() const { return m_dialog; }
00444     SIPAuthentication * GetAuthenticator() const { return m_authentication; }
00445 
00446 #if OPAL_VIDEO
00447 
00452     virtual PBoolean OnMediaControlXML(SIP_PDU & pdu);
00453 #endif
00454 
00455     virtual void OnMediaCommand(OpalMediaCommand & note, INT extra);
00456 
00457     virtual void OnStartTransaction(SIPTransaction & transaction);
00458 
00459     virtual void OnReceivedMESSAGE(SIP_PDU & pdu);
00460     virtual void OnMessageReceived(const SIPURL & from, const SIP_PDU & pdu);
00461 
00462     PString GetLocalPartyURL() const;
00463 
00464   protected:
00465     PDECLARE_NOTIFIER(PTimer, SIPConnection, OnInviteResponseRetry);
00466     PDECLARE_NOTIFIER(PTimer, SIPConnection, OnAckTimeout);
00467 
00468     virtual bool OnSendSDP(
00469       bool isAnswerSDP,
00470       OpalRTPSessionManager & rtpSessions,
00471       SDPSessionDescription & sdpOut
00472     );
00473     virtual bool OfferSDPMediaDescription(
00474       const OpalMediaType & mediaType,
00475       unsigned sessionID,
00476       OpalRTPSessionManager & rtpSessions,
00477       SDPSessionDescription & sdpOut
00478     );
00479     virtual bool AnswerSDPMediaDescription(
00480       const SDPSessionDescription & sdpIn,
00481       unsigned sessionIndex,
00482       SDPSessionDescription & sdpOut
00483     );
00484 
00485     virtual void OnReceivedSDP(
00486       SIP_PDU & pdu
00487     );
00488     virtual bool OnReceivedSDPMediaDescription(
00489       SDPSessionDescription & sdp,
00490       unsigned sessionId
00491     );
00492 
00493     virtual OpalMediaSession * SetUpMediaSession(
00494       const unsigned rtpSessionId,
00495       const OpalMediaType & mediaType,
00496       SDPMediaDescription * mediaDescription,
00497       OpalTransportAddress & localAddress,
00498       bool & remoteChanged
00499     );
00500 
00501     bool SendReINVITE(PTRACE_PARAM(const char * msg));
00502     void StartPendingReINVITE();
00503 
00504     friend class SIPInvite;
00505     static PBoolean WriteINVITE(OpalTransport & transport, void * param);
00506     bool WriteINVITE(OpalTransport & transport);
00507 
00508     OpalTransport * CreateTransport(const OpalTransportAddress & address, PBoolean isLocalAddress = PFalse);
00509 
00510     void UpdateRemoteAddresses();
00511 
00512     void NotifyDialogState(
00513       SIPDialogNotification::States state,
00514       SIPDialogNotification::Events eventType = SIPDialogNotification::NoEvent,
00515       unsigned eventCode = 0
00516     );
00517 
00518 
00519     
00520     SIPEndPoint         & endpoint;
00521     OpalTransport       * transport;
00522     bool                  deleteTransport;
00523 
00524     enum HoldState {
00525       eHoldOff,
00526       eRetrieveInProgress,
00527 
00528       
00529       eHoldOn,
00530       eHoldInProgress
00531     };
00532     HoldState             m_holdToRemote;
00533     bool                  m_holdFromRemote;
00534     PString               forwardParty;
00535 
00536     SIP_PDU             * originalInvite;
00537     PTime                 originalInviteTime;
00538     time_t                m_sdpSessionId;
00539     unsigned              m_sdpVersion; 
00540     bool                  needReINVITE;
00541     bool                  m_handlingINVITE;
00542     SIPDialogContext      m_dialog;
00543     OpalGloballyUniqueID  m_dialogNotifyId;
00544     int                   m_appearanceCode;
00545     PString               m_alertInfo;
00546     SIPAuthentication   * m_authentication;
00547     unsigned              m_authenticatedCseq;
00548 
00549     std::map<SIP_PDU::Methods, unsigned> m_lastRxCSeq;
00550 
00551     PTimer                    ackTimer;
00552     PTimer                    ackRetry;
00553     SIP_PDU                   ackPacket;
00554     bool                      ackReceived;
00555     PSafePtr<SIPTransaction>  referTransaction;
00556     PSafeList<SIPTransaction> forkedInvitations; 
00557     PSafeList<SIPTransaction> pendingInvitations; 
00558 
00559     enum {
00560       ReleaseWithBYE,
00561       ReleaseWithCANCEL,
00562       ReleaseWithResponse,
00563       ReleaseWithNothing,
00564     } releaseMethod;
00565 
00566     OpalMediaFormatList remoteFormatList;
00567 
00568   protected:
00569     PTimer sessionTimer;
00570   public:
00571     PDECLARE_NOTIFIER(PTimer, SIPConnection, OnSessionTimeout);
00572 
00573   private:
00574     P_REMOVE_VIRTUAL_VOID(OnCreatingINVITE(SIP_PDU&));
00575     P_REMOVE_VIRTUAL_VOID(OnReceivedTrying(SIP_PDU &));
00576 };
00577 
00578 
00581 class SIP_RTP_Session : public RTP_UserData
00582 {
00583   PCLASSINFO(SIP_RTP_Session, RTP_UserData);
00584 
00589     SIP_RTP_Session(
00590       const SIPConnection & connection  
00591     );
00593 
00602     virtual void OnTxStatistics(
00603       const RTP_Session & session   
00604     ) const;
00605 
00612     virtual void OnRxStatistics(
00613       const RTP_Session & session   
00614     ) const;
00615 
00616 #if OPAL_VIDEO
00617 
00621     virtual void OnRxIntraFrameRequest(
00622       const RTP_Session & session   
00623     ) const;
00624 
00628     virtual void OnTxIntraFrameRequest(
00629       const RTP_Session & session   
00630     ) const;
00631 #endif
00632 
00633 
00634     virtual void SessionFailing(RTP_Session & );
00635 
00636   protected:
00637     const SIPConnection & connection; 
00638 };
00639 
00640 
00641 #endif // OPAL_SIP
00642 
00643 #endif // OPAL_SIP_SIPCON_H
00644 
00645 
00646