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 #define SIP_HEADER_PREFIX "SIP-Header:"
00061 #define SIP_HEADER_REPLACES SIP_HEADER_PREFIX"Replaces"
00062
00063
00065
00069 class SIPConnection : public OpalRTPConnection
00070 {
00071 PCLASSINFO(SIPConnection, OpalRTPConnection);
00072 public:
00073
00078 SIPConnection(
00079 OpalCall & call,
00080 SIPEndPoint & endpoint,
00081 const PString & token,
00082 const SIPURL & address,
00083 OpalTransport * transport,
00084 unsigned int options = 0,
00085 OpalConnection::StringOptions * stringOptions = NULL
00086 );
00087
00090 ~SIPConnection();
00092
00103 virtual bool IsNetworkConnection() const { return true; }
00104
00107 virtual PString GetPrefixName() const;
00108
00111 virtual PString GetIdentifier() const;
00112
00119 virtual PString GetRemotePartyURL() const;
00120
00127 virtual PBoolean SetUpConnection();
00128
00135 virtual PString GetDestinationAddress();
00136
00144 virtual PString GetCalledPartyURL();
00145
00159 virtual PString GetAlertingType() const;
00160
00174 virtual bool SetAlertingType(const PString & info);
00175
00182 virtual bool TransferConnection(
00183 const PString & remoteParty
00184 );
00185
00188 virtual bool HoldConnection();
00189
00193 virtual bool RetrieveConnection();
00194
00199 virtual bool IsConnectionOnHold(
00200 bool fromRemote
00201 );
00202
00213 virtual PBoolean SetAlerting(
00214 const PString & calleeName,
00215 PBoolean withMedia
00216 );
00217
00222 virtual PBoolean SetConnected();
00223
00226 virtual OpalMediaFormatList GetMediaFormats() const;
00227
00230 virtual OpalMediaStreamPtr OpenMediaStream(
00231 const OpalMediaFormat & mediaFormat,
00232 unsigned sessionID,
00233 bool isSource
00234 );
00235
00240 virtual bool CloseMediaStream(
00241 OpalMediaStream & stream
00242 );
00243
00261 virtual void OnReleased();
00262
00272 virtual PBoolean ForwardCall(
00273 const PString & forwardParty
00274 );
00275
00281 virtual SendUserInputModes GetRealSendUserInputMode() const;
00282
00299 PBoolean SendUserInputTone(char tone, unsigned duration);
00300
00308 virtual void OnRTPStatistics(
00309 const RTP_Session & session
00310 ) const;
00312
00317 virtual void OnTransactionFailed(
00318 SIPTransaction & transaction
00319 );
00320
00323 virtual void OnReceivedPDU(SIP_PDU & pdu);
00324
00327 virtual void OnReceivedINVITE(SIP_PDU & pdu);
00328
00331 virtual void OnReceivedReINVITE(SIP_PDU & pdu);
00332
00335 virtual void OnReceivedACK(SIP_PDU & pdu);
00336
00339 virtual void OnReceivedOPTIONS(SIP_PDU & pdu);
00340
00343 virtual void OnReceivedNOTIFY(SIP_PDU & pdu);
00344
00348 virtual void OnAllowedEventNotify(
00349 const PString & eventName
00350 );
00351
00354 virtual void OnReceivedREFER(SIP_PDU & pdu);
00355
00358 virtual void OnReceivedINFO(SIP_PDU & pdu);
00359
00362 virtual void OnReceivedPING(SIP_PDU & pdu);
00363
00366 virtual void OnReceivedBYE(SIP_PDU & pdu);
00367
00370 virtual void OnReceivedCANCEL(SIP_PDU & pdu);
00371
00376 virtual void OnReceivedResponseToINVITE(
00377 SIPTransaction & transaction,
00378 SIP_PDU & response
00379 );
00380
00383 virtual void OnReceivedResponse(
00384 SIPTransaction & transaction,
00385 SIP_PDU & response
00386 );
00387
00390 virtual void OnReceivedTrying(
00391 SIPTransaction & transaction,
00392 SIP_PDU & response
00393 );
00394
00397 virtual void OnReceivedRinging(SIP_PDU & pdu);
00398
00401 virtual void OnReceivedSessionProgress(SIP_PDU & pdu);
00402
00406 virtual PBoolean OnReceivedAuthenticationRequired(
00407 SIPTransaction & transaction,
00408 SIP_PDU & response
00409 );
00410
00413 virtual void OnReceivedRedirection(SIP_PDU & pdu);
00414
00418 virtual void OnReceivedOK(
00419 SIPTransaction & transaction,
00420 SIP_PDU & response
00421 );
00422
00425 virtual void OnCreatingINVITE(SIPInvite & pdu);
00426
00429 virtual PBoolean SendInviteOK(const SDPSessionDescription & sdp);
00430
00433 virtual PBoolean SendInviteResponse(
00434 SIP_PDU::StatusCodes code,
00435 const char * contact = NULL,
00436 const char * extra = NULL,
00437 const SDPSessionDescription * sdp = NULL
00438 );
00439
00440 enum TypeOfINVITE {
00441 IsNewINVITE,
00442 IsDuplicateINVITE,
00443 IsReINVITE,
00444 IsLoopedINVITE
00445 };
00446
00448 TypeOfINVITE CheckINVITE(
00449 const SIP_PDU & pdu
00450 ) const;
00452
00453 OpalTransportAddress GetDefaultSDPConnectAddress(WORD port = 0) const;
00454
00455 OpalTransport & GetTransport() const { return *transport; }
00456 bool SetTransport(OpalTransport * transport);
00457
00458 SIPEndPoint & GetEndPoint() const { return endpoint; }
00459 SIPDialogContext & GetDialog() { return m_dialog; }
00460 const SIPDialogContext & GetDialog() const { return m_dialog; }
00461 SIPAuthentication * GetAuthenticator() const { return m_authentication; }
00462
00463 #if OPAL_VIDEO
00464
00469 virtual PBoolean OnMediaControlXML(SIP_PDU & pdu);
00470 #endif
00471
00472 virtual void OnMediaCommand(OpalMediaCommand & note, INT extra);
00473
00474 virtual void OnStartTransaction(SIPTransaction & transaction);
00475
00476 virtual void OnReceivedMESSAGE(SIP_PDU & pdu);
00477
00478 P_REMOVE_VIRTUAL_VOID(OnMessageReceived(const SIPURL & , const SIP_PDU & ));
00479 P_REMOVE_VIRTUAL_VOID(OnMessageReceived(const SIP_PDU & ));
00480
00481 #if OPAL_HAS_IM
00482 virtual bool TransmitExternalIM(
00483 const OpalMediaFormat & format,
00484 RTP_IMFrame & body
00485 );
00486 #endif
00487
00488 PString GetLocalPartyURL() const;
00489
00490 protected:
00491 PDECLARE_NOTIFIER(PTimer, SIPConnection, OnSessionTimeout);
00492 PDECLARE_NOTIFIER(PTimer, SIPConnection, OnInviteResponseRetry);
00493 PDECLARE_NOTIFIER(PTimer, SIPConnection, OnAckTimeout);
00494
00495 virtual bool OnSendSDP(
00496 bool isAnswerSDP,
00497 OpalRTPSessionManager & rtpSessions,
00498 SDPSessionDescription & sdpOut
00499 );
00500 virtual bool OfferSDPMediaDescription(
00501 const OpalMediaType & mediaType,
00502 unsigned sessionID,
00503 OpalRTPSessionManager & rtpSessions,
00504 SDPSessionDescription & sdpOut,
00505 bool offerOpenMediaStreamOnly = false
00506 );
00507 virtual bool AnswerSDPMediaDescription(
00508 const SDPSessionDescription & sdpIn,
00509 unsigned sessionIndex,
00510 SDPSessionDescription & sdpOut
00511 );
00512
00513 virtual void OnReceivedSDP(
00514 SIP_PDU & pdu
00515 );
00516 virtual bool OnReceivedSDPMediaDescription(
00517 SDPSessionDescription & sdp,
00518 unsigned sessionId
00519 );
00520
00521 virtual OpalMediaSession * SetUpMediaSession(
00522 const unsigned rtpSessionId,
00523 const OpalMediaType & mediaType,
00524 SDPMediaDescription * mediaDescription,
00525 OpalTransportAddress & localAddress,
00526 bool & remoteChanged
00527 );
00528
00529 bool SendReINVITE(PTRACE_PARAM(const char * msg));
00530 void StartPendingReINVITE();
00531
00532 friend class SIPInvite;
00533 static PBoolean WriteINVITE(OpalTransport & transport, void * param);
00534 bool WriteINVITE();
00535
00536 void UpdateRemoteAddresses();
00537
00538 void NotifyDialogState(
00539 SIPDialogNotification::States state,
00540 SIPDialogNotification::Events eventType = SIPDialogNotification::NoEvent,
00541 unsigned eventCode = 0
00542 );
00543
00544
00545
00546 SIPEndPoint & endpoint;
00547 OpalTransport * transport;
00548 bool deleteTransport;
00549 PStringList m_allowedEvents;
00550
00551 enum HoldState {
00552 eHoldOff,
00553 eRetrieveInProgress,
00554
00555
00556 eHoldOn,
00557 eHoldInProgress
00558 };
00559 HoldState m_holdToRemote;
00560 bool m_holdFromRemote;
00561 PString forwardParty;
00562
00563 SIP_PDU * originalInvite;
00564 PTime originalInviteTime;
00565 time_t m_sdpSessionId;
00566 unsigned m_sdpVersion;
00567 bool m_needReINVITE;
00568 bool m_handlingINVITE;
00569 bool m_symmetricOpenStream;
00570 SIPDialogContext m_dialog;
00571 OpalGloballyUniqueID m_dialogNotifyId;
00572 int m_appearanceCode;
00573 PString m_alertInfo;
00574 SIPAuthentication * m_authentication;
00575 unsigned m_authenticatedCseq;
00576 PTimer sessionTimer;
00577
00578 std::map<SIP_PDU::Methods, unsigned> m_lastRxCSeq;
00579
00580 PTimer ackTimer;
00581 PTimer ackRetry;
00582 SIP_PDU ackPacket;
00583 bool ackReceived;
00584 bool m_referInProgress;
00585 PSafeList<SIPTransaction> forkedInvitations;
00586 PSafeList<SIPTransaction> pendingInvitations;
00587 PSafeList<SIPTransaction> m_pendingTransactions;
00588
00589 #if OPAL_FAX
00590 bool m_switchedToFaxMode;
00591 #endif
00592
00593 enum {
00594 ReleaseWithBYE,
00595 ReleaseWithCANCEL,
00596 ReleaseWithResponse,
00597 ReleaseWithNothing,
00598 } releaseMethod;
00599
00600 OpalMediaFormatList m_remoteFormatList;
00601 OpalMediaFormatList m_answerFormatList;
00602 void SetRemoteMediaFormats(SDPSessionDescription * sdp);
00603
00604 private:
00605 P_REMOVE_VIRTUAL_VOID(OnCreatingINVITE(SIP_PDU&));
00606 P_REMOVE_VIRTUAL_VOID(OnReceivedTrying(SIP_PDU &));
00607
00608 friend class SIPTransaction;
00609 };
00610
00611
00614 class SIP_RTP_Session : public RTP_UserData
00615 {
00616 PCLASSINFO(SIP_RTP_Session, RTP_UserData);
00617
00622 SIP_RTP_Session(
00623 const SIPConnection & connection
00624 );
00626
00635 virtual void OnTxStatistics(
00636 const RTP_Session & session
00637 ) const;
00638
00645 virtual void OnRxStatistics(
00646 const RTP_Session & session
00647 ) const;
00648
00649 #if OPAL_VIDEO
00650
00654 virtual void OnRxIntraFrameRequest(
00655 const RTP_Session & session
00656 ) const;
00657
00661 virtual void OnTxIntraFrameRequest(
00662 const RTP_Session & session
00663 ) const;
00664 #endif
00665
00666
00667 virtual void SessionFailing(RTP_Session & );
00668
00669 protected:
00670 const SIPConnection & connection;
00671 };
00672
00673
00674 #endif // OPAL_SIP
00675
00676 #endif // OPAL_SIP_SIPCON_H
00677
00678
00679