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 #define SIP_HEADER_CONTACT SIP_HEADER_PREFIX"Contact"
00063
00064 #define OPAL_OPT_SYMMETRIC_HOLD_PRODUCT "Symmetric-Hold-Product"
00065
00066
00068
00072 class SIPConnection : public OpalRTPConnection
00073 {
00074 PCLASSINFO(SIPConnection, OpalRTPConnection);
00075 public:
00076
00081 SIPConnection(
00082 OpalCall & call,
00083 SIPEndPoint & endpoint,
00084 const PString & token,
00085 const SIPURL & address,
00086 OpalTransport * transport,
00087 unsigned int options = 0,
00088 OpalConnection::StringOptions * stringOptions = NULL
00089 );
00090
00093 ~SIPConnection();
00095
00106 virtual bool IsNetworkConnection() const { return true; }
00107
00110 virtual PString GetPrefixName() const;
00111
00114 virtual PString GetIdentifier() 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
00194 virtual bool IsConnectionOnHold(
00195 bool fromRemote
00196 );
00197
00208 virtual PBoolean SetAlerting(
00209 const PString & calleeName,
00210 PBoolean withMedia
00211 );
00212
00217 virtual PBoolean SetConnected();
00218
00221 virtual OpalMediaFormatList GetMediaFormats() const;
00222
00225 virtual OpalMediaStreamPtr OpenMediaStream(
00226 const OpalMediaFormat & mediaFormat,
00227 unsigned sessionID,
00228 bool isSource
00229 );
00230
00235 virtual bool CloseMediaStream(
00236 OpalMediaStream & stream
00237 );
00238
00256 virtual void OnReleased();
00257
00267 virtual PBoolean ForwardCall(
00268 const PString & forwardParty
00269 );
00270
00276 virtual SendUserInputModes GetRealSendUserInputMode() const;
00277
00294 PBoolean SendUserInputTone(char tone, unsigned duration);
00295
00303 virtual void OnRTPStatistics(
00304 const RTP_Session & session
00305 ) const;
00307
00312 virtual void OnTransactionFailed(
00313 SIPTransaction & transaction
00314 );
00315
00318 virtual void OnReceivedPDU(SIP_PDU & pdu);
00319
00322 virtual void OnReceivedINVITE(SIP_PDU & pdu);
00323
00326 virtual void OnReceivedReINVITE(SIP_PDU & pdu);
00327
00330 virtual void OnReceivedACK(SIP_PDU & pdu);
00331
00334 virtual void OnReceivedOPTIONS(SIP_PDU & pdu);
00335
00338 virtual void OnReceivedNOTIFY(SIP_PDU & pdu);
00339
00343 virtual void OnAllowedEventNotify(
00344 const PString & eventName
00345 );
00346
00349 virtual void OnReceivedREFER(SIP_PDU & pdu);
00350
00353 virtual void OnReceivedINFO(SIP_PDU & pdu);
00354
00357 virtual void OnReceivedPING(SIP_PDU & pdu);
00358
00361 virtual void OnReceivedBYE(SIP_PDU & pdu);
00362
00365 virtual void OnReceivedCANCEL(SIP_PDU & pdu);
00366
00371 virtual void OnReceivedResponseToINVITE(
00372 SIPTransaction & transaction,
00373 SIP_PDU & response
00374 );
00375
00378 virtual void OnReceivedResponse(
00379 SIPTransaction & transaction,
00380 SIP_PDU & response
00381 );
00382
00385 virtual void OnReceivedTrying(
00386 SIPTransaction & transaction,
00387 SIP_PDU & response
00388 );
00389
00392 virtual void OnReceivedRinging(SIP_PDU & pdu);
00393
00396 virtual void OnReceivedSessionProgress(SIP_PDU & pdu);
00397
00401 virtual PBoolean OnReceivedAuthenticationRequired(
00402 SIPTransaction & transaction,
00403 SIP_PDU & response
00404 );
00405
00408 virtual void OnReceivedRedirection(SIP_PDU & pdu);
00409
00413 virtual void OnReceivedOK(
00414 SIPTransaction & transaction,
00415 SIP_PDU & response
00416 );
00417
00420 virtual void OnCreatingINVITE(SIPInvite & pdu);
00421
00424 virtual PBoolean SendInviteOK(const SDPSessionDescription & sdp);
00425
00428 virtual PBoolean SendInviteResponse(
00429 SIP_PDU::StatusCodes code,
00430 const char * contact = NULL,
00431 const char * extra = NULL,
00432 const SDPSessionDescription * sdp = NULL
00433 );
00434
00435 enum TypeOfINVITE {
00436 IsNewINVITE,
00437 IsDuplicateINVITE,
00438 IsReINVITE,
00439 IsLoopedINVITE
00440 };
00441
00443 TypeOfINVITE CheckINVITE(
00444 const SIP_PDU & pdu
00445 ) const;
00447
00448 OpalTransportAddress GetDefaultSDPConnectAddress(WORD port = 0) const;
00449
00450 OpalTransport & GetTransport() const { return *transport; }
00451 bool SetTransport(OpalTransport * transport);
00452
00453 SIPEndPoint & GetEndPoint() const { return endpoint; }
00454 SIPDialogContext & GetDialog() { return m_dialog; }
00455 const SIPDialogContext & GetDialog() const { return m_dialog; }
00456 SIPAuthentication * GetAuthenticator() const { return m_authentication; }
00457
00458 #if OPAL_VIDEO
00459
00464 virtual PBoolean OnMediaControlXML(SIP_PDU & pdu);
00465 #endif
00466
00467 virtual void OnMediaCommand(OpalMediaCommand & note, INT extra);
00468
00469 virtual void OnStartTransaction(SIPTransaction & transaction);
00470
00471 virtual void OnReceivedMESSAGE(SIP_PDU & pdu);
00472
00473 P_REMOVE_VIRTUAL_VOID(OnMessageReceived(const SIPURL & , const SIP_PDU & ));
00474 P_REMOVE_VIRTUAL_VOID(OnMessageReceived(const SIP_PDU & ));
00475
00476 #if OPAL_HAS_IM
00477 virtual bool TransmitExternalIM(
00478 const OpalMediaFormat & format,
00479 RTP_IMFrame & body
00480 );
00481 #endif
00482
00483 PString GetLocalPartyURL() const;
00484
00485 protected:
00486 PDECLARE_NOTIFIER(PTimer, SIPConnection, OnSessionTimeout);
00487 PDECLARE_NOTIFIER(PTimer, SIPConnection, OnInviteResponseRetry);
00488 PDECLARE_NOTIFIER(PTimer, SIPConnection, OnAckTimeout);
00489
00490 virtual bool OnSendSDP(
00491 bool isAnswerSDP,
00492 OpalRTPSessionManager & rtpSessions,
00493 SDPSessionDescription & sdpOut
00494 );
00495 virtual bool OfferSDPMediaDescription(
00496 const OpalMediaType & mediaType,
00497 unsigned sessionID,
00498 OpalRTPSessionManager & rtpSessions,
00499 SDPSessionDescription & sdpOut,
00500 bool offerOpenMediaStreamOnly = false
00501 );
00502 virtual bool AnswerSDPMediaDescription(
00503 const SDPSessionDescription & sdpIn,
00504 unsigned sessionIndex,
00505 SDPSessionDescription & sdpOut
00506 );
00507
00508 virtual void OnReceivedSDP(
00509 SIP_PDU & pdu
00510 );
00511 virtual bool OnReceivedSDPMediaDescription(
00512 SDPSessionDescription & sdp,
00513 unsigned sessionId
00514 );
00515
00516 virtual OpalMediaSession * SetUpMediaSession(
00517 const unsigned rtpSessionId,
00518 const OpalMediaType & mediaType,
00519 SDPMediaDescription * mediaDescription,
00520 OpalTransportAddress & localAddress,
00521 bool & remoteChanged
00522 );
00523
00524 bool SendReINVITE(PTRACE_PARAM(const char * msg));
00525 void StartPendingReINVITE();
00526
00527 friend class SIPInvite;
00528 static PBoolean WriteINVITE(OpalTransport & transport, void * param);
00529 bool WriteINVITE();
00530
00531 void UpdateRemoteAddresses();
00532
00533 void NotifyDialogState(
00534 SIPDialogNotification::States state,
00535 SIPDialogNotification::Events eventType = SIPDialogNotification::NoEvent,
00536 unsigned eventCode = 0
00537 );
00538
00539
00540
00541 SIPEndPoint & endpoint;
00542 OpalTransport * transport;
00543 bool deleteTransport;
00544 PStringList m_allowedEvents;
00545
00546 enum HoldState {
00547 eHoldOff,
00548 eRetrieveInProgress,
00549
00550
00551 eHoldOn,
00552 eHoldInProgress
00553 };
00554 HoldState m_holdToRemote;
00555 bool m_holdFromRemote;
00556 PString forwardParty;
00557
00558 SIP_PDU * originalInvite;
00559 PTime originalInviteTime;
00560 time_t m_sdpSessionId;
00561 unsigned m_sdpVersion;
00562 bool m_needReINVITE;
00563 bool m_handlingINVITE;
00564 bool m_symmetricOpenStream;
00565 SIPDialogContext m_dialog;
00566 OpalGloballyUniqueID m_dialogNotifyId;
00567 int m_appearanceCode;
00568 PString m_alertInfo;
00569 SIPAuthentication * m_authentication;
00570 unsigned m_authenticatedCseq;
00571 PTimer sessionTimer;
00572
00573 std::map<SIP_PDU::Methods, unsigned> m_lastRxCSeq;
00574
00575 PTimer ackTimer;
00576 PTimer ackRetry;
00577 unsigned ackRetryCount;
00578 SIP_PDU ackPacket;
00579 bool ackReceived;
00580 bool m_referInProgress;
00581 PSafeList<SIPTransaction> forkedInvitations;
00582 PSafeList<SIPTransaction> pendingInvitations;
00583 PSafeList<SIPTransaction> m_pendingTransactions;
00584
00585 #if OPAL_FAX
00586 bool m_switchedToFaxMode;
00587 #endif
00588
00589 enum {
00590 ReleaseWithBYE,
00591 ReleaseWithCANCEL,
00592 ReleaseWithResponse,
00593 ReleaseWithNothing,
00594 } releaseMethod;
00595
00596 OpalMediaFormatList m_remoteFormatList;
00597 OpalMediaFormatList m_answerFormatList;
00598 void SetRemoteMediaFormats(SDPSessionDescription * sdp);
00599
00600 private:
00601 P_REMOVE_VIRTUAL_VOID(OnCreatingINVITE(SIP_PDU&));
00602 P_REMOVE_VIRTUAL_VOID(OnReceivedTrying(SIP_PDU &));
00603
00604 friend class SIPTransaction;
00605 };
00606
00607
00610 class SIP_RTP_Session : public RTP_UserData
00611 {
00612 PCLASSINFO(SIP_RTP_Session, RTP_UserData);
00613
00618 SIP_RTP_Session(
00619 const SIPConnection & connection
00620 );
00622
00631 virtual void OnTxStatistics(
00632 const RTP_Session & session
00633 ) const;
00634
00641 virtual void OnRxStatistics(
00642 const RTP_Session & session
00643 ) const;
00644
00645 #if OPAL_VIDEO
00646
00650 virtual void OnRxIntraFrameRequest(
00651 const RTP_Session & session
00652 ) const;
00653
00657 virtual void OnTxIntraFrameRequest(
00658 const RTP_Session & session
00659 ) const;
00660 #endif
00661
00662
00663 virtual void SessionFailing(RTP_Session & );
00664
00665 protected:
00666 const SIPConnection & connection;
00667 };
00668
00669
00670 #endif // OPAL_SIP
00671
00672 #endif // OPAL_SIP_SIPCON_H
00673
00674
00675