OPAL Version 3.10.2
|
00001 /* 00002 * sippdu.h 00003 * 00004 * Session Initiation Protocol PDU support. 00005 * 00006 * Open Phone Abstraction Library (OPAL) 00007 * Formally known as the Open H323 project. 00008 * 00009 * Copyright (c) 2002 Equivalence Pty. Ltd. 00010 * 00011 * The contents of this file are subject to the Mozilla Public License 00012 * Version 1.0 (the "License"); you may not use this file except in 00013 * compliance with the License. You may obtain a copy of the License at 00014 * http://www.mozilla.org/MPL/ 00015 * 00016 * Software distributed under the License is distributed on an "AS IS" 00017 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 00018 * the License for the specific language governing rights and limitations 00019 * under the License. 00020 * 00021 * The Original Code is Open Phone Abstraction Library. 00022 * 00023 * The Initial Developer of the Original Code is Equivalence Pty. Ltd. 00024 * 00025 * Contributor(s): ______________________________________. 00026 * 00027 * $Revision: 25988 $ 00028 * $Author: rjongbloed $ 00029 * $Date: 2011-06-08 22:06:13 -0500 (Wed, 08 Jun 2011) $ 00030 */ 00031 00032 #ifndef OPAL_SIP_SIPPDU_H 00033 #define OPAL_SIP_SIPPDU_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 <ptclib/mime.h> 00044 #include <ptclib/url.h> 00045 #include <ptclib/http.h> 00046 #include <sip/sdp.h> 00047 #include <opal/rtpconn.h> 00048 00049 00050 class OpalTransport; 00051 class OpalTransportAddress; 00052 class OpalProductInfo; 00053 00054 class SIPEndPoint; 00055 class SIPConnection; 00056 class SIP_PDU; 00057 class SIPSubscribeHandler; 00058 class SIPDialogContext; 00059 00060 00062 // SIPURL 00063 00069 class SIPURL : public PURL 00070 { 00071 PCLASSINFO(SIPURL, PURL); 00072 public: 00073 SIPURL(); 00074 00077 SIPURL( 00078 const char * cstr, 00079 const char * defaultScheme = NULL 00080 ); 00081 00084 SIPURL( 00085 const PString & str, 00086 const char * defaultScheme = NULL 00087 ); 00088 00098 SIPURL( 00099 const PString & name, 00100 const OpalTransportAddress & address, 00101 WORD listenerPort = 0 00102 ); 00103 00104 SIPURL( 00105 const OpalTransportAddress & _address, 00106 WORD listenerPort = 0 00107 ); 00108 00117 virtual Comparison Compare( 00118 const PObject & obj 00119 ) const; 00120 00124 PString AsQuotedString() const; 00125 00128 PString GetDisplayName(PBoolean useDefault = true) const; 00129 00130 void SetDisplayName(const PString & str) 00131 { 00132 m_displayName = str; 00133 } 00134 00136 const PStringOptions & GetFieldParameters() const { return m_fieldParameters; } 00137 PStringOptions & GetFieldParameters() { return m_fieldParameters; } 00138 00141 OpalTransportAddress GetHostAddress() const; 00142 00143 enum UsageContext { 00144 ExternalURI, 00145 RequestURI, 00146 ToURI, 00147 FromURI, 00148 RouteURI, 00149 RedirectURI, 00150 ContactURI, 00151 RegContactURI, 00152 RegisterURI 00153 }; 00154 00160 void Sanitise( 00161 UsageContext context 00162 ); 00163 00169 PBoolean AdjustToDNS( 00170 PINDEX entry = 0 00171 ); 00172 00174 static PString GenerateTag(); 00175 00177 void SetTag( 00178 const PString & tag = PString::Empty(), 00179 bool force = false 00180 ); 00181 00182 protected: 00183 void ParseAsAddress(const PString & name, const OpalTransportAddress & _address, WORD listenerPort = 0); 00184 00204 virtual PBoolean InternalParse( 00205 const char * cstr, 00206 const char * defaultScheme 00207 ); 00208 00209 PString m_displayName; 00210 PStringOptions m_fieldParameters; 00211 }; 00212 00213 00214 class SIPURLList : public std::list<SIPURL> 00215 { 00216 public: 00217 bool FromString(const PString & str, bool reversed = false); 00218 PString ToString() const; 00219 }; 00220 00221 00222 00224 // SIPMIMEInfo 00225 00256 class SIPMIMEInfo : public PMIMEInfo 00257 { 00258 PCLASSINFO(SIPMIMEInfo, PMIMEInfo); 00259 public: 00260 SIPMIMEInfo(bool compactForm = false); 00261 00262 virtual void PrintOn(ostream & strm) const; 00263 virtual void ReadFrom(istream & strm); 00264 00265 void SetCompactForm(bool form) { compactForm = form; } 00266 00267 PCaselessString GetContentType(bool includeParameters = false) const; 00268 void SetContentType(const PString & v); 00269 00270 PCaselessString GetContentEncoding() const; 00271 void SetContentEncoding(const PString & v); 00272 00273 PString GetFrom() const; 00274 void SetFrom(const PString & v); 00275 00276 PString GetPAssertedIdentity() const; 00277 void SetPAssertedIdentity(const PString & v); 00278 00279 PString GetPPreferredIdentity() const; 00280 void SetPPreferredIdentity(const PString & v); 00281 00282 PString GetAccept() const; 00283 void SetAccept(const PString & v); 00284 00285 PString GetAcceptEncoding() const; 00286 void SetAcceptEncoding(const PString & v); 00287 00288 PString GetAcceptLanguage() const; 00289 void SetAcceptLanguage(const PString & v); 00290 00291 PString GetAllow() const; 00292 unsigned GetAllowBitMask() const; 00293 void SetAllow(const PString & v); 00294 00295 PString GetCallID() const; 00296 void SetCallID(const PString & v); 00297 00298 PString GetContact() const; 00299 bool GetContacts(SIPURLList & contacts) const; 00300 void SetContact(const PString & v); 00301 00302 PString GetSubject() const; 00303 void SetSubject(const PString & v); 00304 00305 PString GetTo() const; 00306 void SetTo(const PString & v); 00307 00308 PString GetVia() const; 00309 void SetVia(const PString & v); 00310 00311 bool GetViaList(PStringList & v) const; 00312 void SetViaList(const PStringList & v); 00313 00314 PString GetFirstVia() const; 00315 OpalTransportAddress GetViaReceivedAddress() const; 00316 00317 PString GetReferTo() const; 00318 void SetReferTo(const PString & r); 00319 00320 PString GetReferredBy() const; 00321 void SetReferredBy(const PString & r); 00322 00323 PINDEX GetContentLength() const; 00324 void SetContentLength(PINDEX v); 00325 PBoolean IsContentLengthPresent() const; 00326 00327 PString GetCSeq() const; 00328 void SetCSeq(const PString & v); 00329 00330 PString GetDate() const; 00331 void SetDate(const PString & v); 00332 void SetDate(const PTime & t); 00333 void SetDate(void); // set to current date 00334 00335 unsigned GetExpires(unsigned dflt = UINT_MAX) const;// returns default value if not found 00336 void SetExpires(unsigned v); 00337 00338 PINDEX GetMaxForwards() const; 00339 void SetMaxForwards(PINDEX v); 00340 00341 PINDEX GetMinExpires() const; 00342 void SetMinExpires(PINDEX v); 00343 00344 PString GetProxyAuthenticate() const; 00345 void SetProxyAuthenticate(const PString & v); 00346 00347 PString GetRoute() const; 00348 bool GetRoute(SIPURLList & proxies) const; 00349 void SetRoute(const PString & v); 00350 void SetRoute(const SIPURLList & proxies); 00351 00352 PString GetRecordRoute() const; 00353 bool GetRecordRoute(SIPURLList & proxies, bool reversed) const; 00354 void SetRecordRoute(const PString & v); 00355 void SetRecordRoute(const SIPURLList & proxies); 00356 00357 unsigned GetCSeqIndex() const { return GetCSeq().AsUnsigned(); } 00358 00359 PStringSet GetRequire() const; 00360 void SetRequire(const PStringSet & v); 00361 void AddRequire(const PString & v); 00362 00363 PStringSet GetSupported() const; 00364 void SetSupported(const PStringSet & v); 00365 void AddSupported(const PString & v); 00366 00367 PStringSet GetUnsupported() const; 00368 void SetUnsupported(const PStringSet & v); 00369 void AddUnsupported(const PString & v); 00370 00371 PString GetEvent() const; 00372 void SetEvent(const PString & v); 00373 00374 PCaselessString GetSubscriptionState(PStringToString & info) const; 00375 void SetSubscriptionState(const PString & v); 00376 00377 PString GetUserAgent() const; 00378 void SetUserAgent(const PString & v); 00379 00380 PString GetOrganization() const; 00381 void SetOrganization(const PString & v); 00382 00383 void GetProductInfo(OpalProductInfo & info) const; 00384 void SetProductInfo(const PString & ua, const OpalProductInfo & info); 00385 00386 PString GetWWWAuthenticate() const; 00387 void SetWWWAuthenticate(const PString & v); 00388 00389 PString GetSIPIfMatch() const; 00390 void SetSIPIfMatch(const PString & v); 00391 00392 PString GetSIPETag() const; 00393 void SetSIPETag(const PString & v); 00394 00395 void GetAlertInfo(PString & info, int & appearance); 00396 void SetAlertInfo(const PString & info, int appearance); 00397 00398 PString GetCallInfo() const; 00399 00400 PString GetAllowEvents() const; 00401 void SetAllowEvents(const PString & v); 00402 00405 PString GetFieldParameter( 00406 const PString & fieldName, 00407 const PString & paramName, 00408 const PString & defaultValue = PString::Empty() 00409 ) const { return ExtractFieldParameter((*this)(fieldName), paramName, defaultValue); } 00410 00415 void SetFieldParameter( 00416 const PString & fieldName, 00417 const PString & paramName, 00418 const PString & newValue 00419 ) { SetAt(fieldName, InsertFieldParameter((*this)(fieldName), paramName, newValue)); } 00420 00423 static PString ExtractFieldParameter( 00424 const PString & fieldValue, 00425 const PString & paramName, 00426 const PString & defaultValue = PString::Empty() 00427 ); 00428 00433 static PString InsertFieldParameter( 00434 const PString & fieldValue, 00435 const PString & paramName, 00436 const PString & newValue 00437 ); 00438 00439 protected: 00440 PStringSet GetTokenSet(const char * field) const; 00441 void AddTokenSet(const char * field, const PString & token); 00442 void SetTokenSet(const char * field, const PStringSet & tokens); 00443 00445 bool compactForm; 00446 }; 00447 00448 00450 // SIPAuthentication 00451 00452 typedef PHTTPClientAuthentication SIPAuthentication; 00453 00454 class SIPAuthenticator : public PHTTPClientAuthentication::AuthObject 00455 { 00456 public: 00457 SIPAuthenticator(SIP_PDU & pdu); 00458 virtual PMIMEInfo & GetMIME(); 00459 virtual PString GetURI(); 00460 virtual PString GetEntityBody(); 00461 virtual PString GetMethod(); 00462 00463 protected: 00464 SIP_PDU & m_pdu; 00465 }; 00466 00467 00468 00470 // SIP_PDU 00471 00477 class SIP_PDU : public PSafeObject 00478 { 00479 PCLASSINFO(SIP_PDU, PSafeObject); 00480 public: 00481 enum Methods { 00482 Method_INVITE, 00483 Method_ACK, 00484 Method_OPTIONS, 00485 Method_BYE, 00486 Method_CANCEL, 00487 Method_REGISTER, 00488 Method_SUBSCRIBE, 00489 Method_NOTIFY, 00490 Method_REFER, 00491 Method_MESSAGE, 00492 Method_INFO, 00493 Method_PING, 00494 Method_PUBLISH, 00495 Method_PRACK, 00496 NumMethods 00497 }; 00498 00499 enum StatusCodes { 00500 IllegalStatusCode, 00501 Local_TransportError, 00502 Local_BadTransportAddress, 00503 Local_Timeout, 00504 00505 Information_Trying = 100, 00506 Information_Ringing = 180, 00507 Information_CallForwarded = 181, 00508 Information_Queued = 182, 00509 Information_Session_Progress = 183, 00510 00511 Successful_OK = 200, 00512 Successful_Accepted = 202, 00513 00514 Redirection_MultipleChoices = 300, 00515 Redirection_MovedPermanently = 301, 00516 Redirection_MovedTemporarily = 302, 00517 Redirection_UseProxy = 305, 00518 Redirection_AlternativeService = 380, 00519 00520 Failure_BadRequest = 400, 00521 Failure_UnAuthorised = 401, 00522 Failure_PaymentRequired = 402, 00523 Failure_Forbidden = 403, 00524 Failure_NotFound = 404, 00525 Failure_MethodNotAllowed = 405, 00526 Failure_NotAcceptable = 406, 00527 Failure_ProxyAuthenticationRequired = 407, 00528 Failure_RequestTimeout = 408, 00529 Failure_Conflict = 409, 00530 Failure_Gone = 410, 00531 Failure_LengthRequired = 411, 00532 Failure_RequestEntityTooLarge = 413, 00533 Failure_RequestURITooLong = 414, 00534 Failure_UnsupportedMediaType = 415, 00535 Failure_UnsupportedURIScheme = 416, 00536 Failure_BadExtension = 420, 00537 Failure_ExtensionRequired = 421, 00538 Failure_IntervalTooBrief = 423, 00539 Failure_TemporarilyUnavailable = 480, 00540 Failure_TransactionDoesNotExist = 481, 00541 Failure_LoopDetected = 482, 00542 Failure_TooManyHops = 483, 00543 Failure_AddressIncomplete = 484, 00544 Failure_Ambiguous = 485, 00545 Failure_BusyHere = 486, 00546 Failure_RequestTerminated = 487, 00547 Failure_NotAcceptableHere = 488, 00548 Failure_BadEvent = 489, 00549 Failure_RequestPending = 491, 00550 Failure_Undecipherable = 493, 00551 00552 Failure_InternalServerError = 500, 00553 Failure_NotImplemented = 501, 00554 Failure_BadGateway = 502, 00555 Failure_ServiceUnavailable = 503, 00556 Failure_ServerTimeout = 504, 00557 Failure_SIPVersionNotSupported = 505, 00558 Failure_MessageTooLarge = 513, 00559 00560 GlobalFailure_BusyEverywhere = 600, 00561 GlobalFailure_Decline = 603, 00562 GlobalFailure_DoesNotExistAnywhere = 604, 00563 GlobalFailure_NotAcceptable = 606, 00564 00565 MaxStatusCode = 699 00566 }; 00567 00568 static const char * GetStatusCodeDescription(int code); 00569 friend ostream & operator<<(ostream & strm, StatusCodes status); 00570 00571 SIP_PDU( 00572 Methods method = SIP_PDU::NumMethods 00573 ); 00574 00578 SIP_PDU( 00579 const SIP_PDU & request, 00580 StatusCodes code, 00581 const SDPSessionDescription * sdp = NULL 00582 ); 00583 00584 SIP_PDU(const SIP_PDU &); 00585 SIP_PDU & operator=(const SIP_PDU &); 00586 ~SIP_PDU(); 00587 00588 void PrintOn( 00589 ostream & strm 00590 ) const; 00591 00592 void InitialiseHeaders( 00593 const SIPURL & dest, 00594 const SIPURL & to, 00595 const SIPURL & from, 00596 const PString & callID, 00597 unsigned cseq, 00598 const PString & via 00599 ); 00600 void InitialiseHeaders( 00601 SIPDialogContext & dialog, 00602 const PString & via = PString::Empty(), 00603 unsigned cseq = 0 00604 ); 00605 void InitialiseHeaders( 00606 SIPConnection & connection, 00607 const OpalTransport & transport, 00608 unsigned cseq = 0 00609 ); 00610 void InitialiseHeaders( 00611 const SIP_PDU & request 00612 ); 00613 00618 bool SetRoute(const SIPURLList & routeSet); 00619 bool SetRoute(const SIPURL & proxy); 00620 00623 void SetAllow(unsigned bitmask); 00624 00627 void AdjustVia(OpalTransport & transport); 00628 00629 PString CreateVia( 00630 SIPEndPoint & endpoint, 00631 const OpalTransport & transport, 00632 SIPConnection * connection = NULL 00633 ); 00634 00637 SIP_PDU::StatusCodes Read( 00638 OpalTransport & transport 00639 ); 00640 00643 PBoolean Write( 00644 OpalTransport & transport, 00645 const OpalTransportAddress & remoteAddress = OpalTransportAddress(), 00646 const PString & localInterface = PString::Empty() 00647 ); 00648 00651 bool SendResponse( 00652 OpalTransport & transport, 00653 StatusCodes code, 00654 SIPEndPoint * endpoint = NULL 00655 ) const; 00656 bool SendResponse( 00657 OpalTransport & transport, 00658 SIP_PDU & response, 00659 SIPEndPoint * endpoint = NULL 00660 ) const; 00661 00665 PString Build(); 00666 00667 PString GetTransactionID() const; 00668 00669 Methods GetMethod() const { return m_method; } 00670 StatusCodes GetStatusCode () const { return m_statusCode; } 00671 void SetStatusCode (StatusCodes c) { m_statusCode = c; } 00672 const SIPURL & GetURI() const { return m_uri; } 00673 unsigned GetVersionMajor() const { return m_versionMajor; } 00674 unsigned GetVersionMinor() const { return m_versionMinor; } 00675 const PString & GetEntityBody() const { return m_entityBody; } 00676 void SetEntityBody(const PString & body) { m_entityBody = body; } 00677 void SetEntityBody(); 00678 const PString & GetInfo() const { return m_info; } 00679 void SetInfo(const PString & info) { m_info = info; } 00680 const SIPMIMEInfo & GetMIME() const { return m_mime; } 00681 SIPMIMEInfo & GetMIME() { return m_mime; } 00682 void SetURI(const SIPURL & newuri) { m_uri = newuri; } 00683 SDPSessionDescription * GetSDP(const OpalMediaFormatList & masterList); 00684 void SetSDP(SDPSessionDescription * sdp); 00685 00686 protected: 00687 Methods m_method; // Request type, ==NumMethods for Response 00688 StatusCodes m_statusCode; 00689 SIPURL m_uri; // display name & URI, no tag 00690 unsigned m_versionMajor; 00691 unsigned m_versionMinor; 00692 PString m_info; 00693 SIPMIMEInfo m_mime; 00694 PString m_entityBody; 00695 00696 SDPSessionDescription * m_SDP; 00697 00698 mutable PString m_transactionID; 00699 }; 00700 00701 00702 PQUEUE(SIP_PDU_Queue, SIP_PDU); 00703 00704 00705 #if PTRACING 00706 ostream & operator<<(ostream & strm, SIP_PDU::Methods method); 00707 #endif 00708 00709 00711 // SIPDialogContext 00712 00715 class SIPDialogContext 00716 { 00717 public: 00718 SIPDialogContext(); 00719 SIPDialogContext(const SIPMIMEInfo & mime); 00720 00721 PString AsString() const; 00722 bool FromString( 00723 const PString & str 00724 ); 00725 00726 const PString & GetCallID() const { return m_callId; } 00727 void SetCallID(const PString & id) { m_callId = id; } 00728 00729 const SIPURL & GetRequestURI() const { return m_requestURI; } 00730 void SetRequestURI(const SIPURL & url) { m_requestURI = url; } 00731 bool SetRequestURI(const PString & uri) { return m_requestURI.Parse(uri); } 00732 00733 const PString & GetLocalTag() const { return m_localTag; } 00734 void SetLocalTag(const PString & tag) { m_localTag = tag; } 00735 00736 const SIPURL & GetLocalURI() const { return m_localURI; } 00737 void SetLocalURI(const SIPURL & url); 00738 bool SetLocalURI(const PString & uri); 00739 00740 const PString & GetRemoteTag() const { return m_remoteTag; } 00741 void SetRemoteTag(const PString & tag) { m_remoteTag = tag; } 00742 00743 const SIPURL & GetRemoteURI() const { return m_remoteURI; } 00744 void SetRemoteURI(const SIPURL & url); 00745 bool SetRemoteURI(const PString & uri); 00746 00747 const SIPURLList & GetRouteSet() const { return m_routeSet; } 00748 void SetRouteSet(const PString & str) { m_routeSet.FromString(str); } 00749 00750 const SIPURL & GetProxy() const { return m_proxy; } 00751 void SetProxy(const SIPURL & proxy, bool addToRouteSet); 00752 00753 void Update(OpalTransport & transport, const SIP_PDU & response); 00754 00755 unsigned GetNextCSeq(); 00756 void IncrementCSeq(unsigned inc) { m_lastSentCSeq += inc; } 00757 00758 bool IsDuplicateCSeq(unsigned sequenceNumber); 00759 00760 bool IsEstablished() const 00761 { 00762 return !m_callId.IsEmpty() && 00763 !m_requestURI.IsEmpty() && 00764 !m_localTag.IsEmpty() && 00765 !m_remoteTag.IsEmpty(); 00766 } 00767 00768 OpalTransportAddress GetRemoteTransportAddress() const; 00769 00770 void SetForking(bool f) { m_forking = f; } 00771 00772 protected: 00773 PString m_callId; 00774 SIPURL m_requestURI; 00775 SIPURL m_localURI; 00776 PString m_localTag; 00777 SIPURL m_remoteURI; 00778 PString m_remoteTag; 00779 SIPURLList m_routeSet; 00780 unsigned m_lastSentCSeq; 00781 unsigned m_lastReceivedCSeq; 00782 OpalTransportAddress m_externalTransportAddress; 00783 bool m_forking; 00784 SIPURL m_proxy; 00785 }; 00786 00787 00789 00790 struct SIPParameters 00791 { 00792 SIPParameters( 00793 const PString & aor = PString::Empty(), 00794 const PString & remote = PString::Empty() 00795 ); 00796 00797 void Normalise( 00798 const PString & defaultUser, 00799 const PTimeInterval & defaultExpire 00800 ); 00801 00802 PCaselessString m_remoteAddress; 00803 PCaselessString m_localAddress; 00804 PCaselessString m_proxyAddress; 00805 PCaselessString m_addressOfRecord; 00806 PCaselessString m_contactAddress; 00807 SIPMIMEInfo m_mime; 00808 PString m_authID; 00809 PString m_password; 00810 PString m_realm; 00811 unsigned m_expire; 00812 unsigned m_restoreTime; 00813 PTimeInterval m_minRetryTime; 00814 PTimeInterval m_maxRetryTime; 00815 void * m_userData; 00816 }; 00817 00818 00819 #if PTRACING 00820 ostream & operator<<(ostream & strm, const SIPParameters & params); 00821 #endif 00822 00823 00825 // SIPTransaction 00826 00837 class SIPTransaction : public SIP_PDU 00838 { 00839 PCLASSINFO(SIPTransaction, SIP_PDU); 00840 public: 00841 SIPTransaction( 00842 Methods method, 00843 SIPEndPoint & endpoint, 00844 OpalTransport & transport 00845 ); 00849 SIPTransaction( 00850 Methods method, 00851 SIPConnection & connection 00852 ); 00853 ~SIPTransaction(); 00854 00855 /* Under some circumstances a new transaction with all the same parameters 00856 but different ID needs to be created, e.g. when get authentication error. */ 00857 virtual SIPTransaction * CreateDuplicate() const = 0; 00858 00859 PBoolean Start(); 00860 bool IsTrying() const { return m_state == Trying; } 00861 bool IsProceeding() const { return m_state == Proceeding; } 00862 bool IsInProgress() const { return m_state == Trying || m_state == Proceeding; } 00863 bool IsFailed() const { return m_state > Terminated_Success; } 00864 bool IsCompleted() const { return m_state >= Completed; } 00865 bool IsCanceled() const { return m_state == Cancelling || m_state == Terminated_Cancelled || m_state == Terminated_Aborted; } 00866 bool IsTerminated() const { return m_state >= Terminated_Success; } 00867 00868 void WaitForCompletion(); 00869 PBoolean Cancel(); 00870 void Abort(); 00871 00872 virtual PBoolean OnReceivedResponse(SIP_PDU & response); 00873 virtual PBoolean OnCompleted(SIP_PDU & response); 00874 00875 OpalTransport & GetTransport() const { return m_transport; } 00876 SIPConnection * GetConnection() const { return m_connection; } 00877 PString GetInterface() const { return m_localInterface; } 00878 void SetInterface(const PString & localIf) { m_localInterface = localIf; } 00879 00880 static PString GenerateCallID(); 00881 00882 protected: 00883 bool SendPDU(SIP_PDU & pdu); 00884 bool ResendCANCEL(); 00885 void SetParameters(const SIPParameters & params); 00886 00887 PDECLARE_NOTIFIER(PTimer, SIPTransaction, OnRetry); 00888 PDECLARE_NOTIFIER(PTimer, SIPTransaction, OnTimeout); 00889 00890 enum States { 00891 NotStarted, 00892 Trying, 00893 Proceeding, 00894 Cancelling, 00895 Completed, 00896 Terminated_Success, 00897 Terminated_Timeout, 00898 Terminated_RetriesExceeded, 00899 Terminated_TransportError, 00900 Terminated_Cancelled, 00901 Terminated_Aborted, 00902 NumStates 00903 }; 00904 virtual void SetTerminated(States newState); 00905 00906 SIPEndPoint & m_endpoint; 00907 OpalTransport & m_transport; 00908 PSafePtr<SIPConnection> m_connection; 00909 PTimeInterval m_retryTimeoutMin; 00910 PTimeInterval m_retryTimeoutMax; 00911 00912 States m_state; 00913 unsigned m_retry; 00914 PTimer m_retryTimer; 00915 PTimer m_completionTimer; 00916 PSyncPoint m_completed; 00917 00918 PString m_localInterface; 00919 OpalTransportAddress m_remoteAddress; 00920 }; 00921 00922 00923 #define OPAL_PROXY_PARAM "OPAL-proxy" 00924 #define OPAL_LOCAL_ID_PARAM "OPAL-local-id" 00925 00926 00928 // SIPResponse 00929 00932 class SIPResponse : public SIPTransaction 00933 { 00934 PCLASSINFO(SIPResponse, SIPTransaction); 00935 public: 00936 SIPResponse( 00937 SIPEndPoint & endpoint, 00938 StatusCodes code 00939 ); 00940 00941 virtual SIPTransaction * CreateDuplicate() const; 00942 00943 bool Send(OpalTransport & transport, const SIP_PDU & command); 00944 }; 00945 00946 00948 // SIPInvite 00949 00955 class SIPInvite : public SIPTransaction 00956 { 00957 PCLASSINFO(SIPInvite, SIPTransaction); 00958 public: 00959 SIPInvite( 00960 SIPConnection & connection, 00961 const OpalRTPSessionManager & sm 00962 ); 00963 00964 virtual SIPTransaction * CreateDuplicate() const; 00965 00966 virtual PBoolean OnReceivedResponse(SIP_PDU & response); 00967 00968 const OpalRTPSessionManager & GetSessionManager() const { return m_rtpSessions; } 00969 OpalRTPSessionManager & GetSessionManager() { return m_rtpSessions; } 00970 00971 protected: 00972 OpalRTPSessionManager m_rtpSessions; 00973 }; 00974 00975 00977 00978 /* This is the ACK request sent when receiving a response to an outgoing 00979 * INVITE. 00980 */ 00981 class SIPAck : public SIP_PDU 00982 { 00983 PCLASSINFO(SIPAck, SIP_PDU); 00984 public: 00985 SIPAck( 00986 SIPTransaction & invite, 00987 SIP_PDU & response 00988 ); 00989 00990 virtual SIPTransaction * CreateDuplicate() const; 00991 }; 00992 00993 00995 00996 /* This is a BYE request 00997 */ 00998 class SIPBye : public SIPTransaction 00999 { 01000 PCLASSINFO(SIPBye, SIPTransaction); 01001 01002 public: 01003 SIPBye( 01004 SIPEndPoint & ep, 01005 OpalTransport & trans, 01006 SIPDialogContext dialog 01007 ); 01008 SIPBye( 01009 SIPConnection & conn 01010 ); 01011 01012 virtual SIPTransaction * CreateDuplicate() const; 01013 }; 01014 01015 01017 01018 class SIPRegister : public SIPTransaction 01019 { 01020 PCLASSINFO(SIPRegister, SIPTransaction); 01021 public: 01022 enum CompatibilityModes { 01023 e_FullyCompliant, 01026 e_CannotRegisterMultipleContacts, 01030 e_CannotRegisterPrivateContacts 01034 }; 01035 01037 struct Params : public SIPParameters { 01038 Params() 01039 : m_registrarAddress(m_remoteAddress) 01040 , m_compatibility(SIPRegister::e_FullyCompliant) 01041 { } 01042 01043 Params(const Params & param) 01044 : SIPParameters(param) 01045 , m_registrarAddress(m_remoteAddress) 01046 , m_compatibility(param.m_compatibility) 01047 { } 01048 01049 PCaselessString & m_registrarAddress; // For backward compatibility 01050 CompatibilityModes m_compatibility; 01051 }; 01052 01053 SIPRegister( 01054 SIPEndPoint & endpoint, 01055 OpalTransport & transport, 01056 const PString & callId, 01057 unsigned cseq, 01058 const Params & params 01059 ); 01060 01061 virtual SIPTransaction * CreateDuplicate() const; 01062 }; 01063 01064 01065 #if PTRACING 01066 ostream & operator<<(ostream & strm, SIPRegister::CompatibilityModes mode); 01067 ostream & operator<<(ostream & strm, const SIPRegister::Params & params); 01068 #endif 01069 01070 01072 01073 class SIPSubscribe : public SIPTransaction 01074 { 01075 PCLASSINFO(SIPSubscribe, SIPTransaction); 01076 public: 01079 enum PredefinedPackages { 01080 MessageSummary, 01081 Presence, 01082 Dialog, 01083 01084 NumPredefinedPackages, 01085 01086 Watcher = 0x8000, 01087 01088 MessageSummaryWatcher = Watcher|MessageSummary, 01089 PresenceWatcher = Watcher|Presence, 01090 DialogWatcher = Watcher|Dialog, 01091 01092 PackageMask = Watcher-1 01093 }; 01094 friend PredefinedPackages operator|(PredefinedPackages p1, PredefinedPackages p2) { return (PredefinedPackages)((int)p1|(int)p2); } 01095 01096 class EventPackage : public PCaselessString 01097 { 01098 PCLASSINFO(EventPackage, PCaselessString); 01099 public: 01100 EventPackage(PredefinedPackages = NumPredefinedPackages); 01101 explicit EventPackage(const PString & str) : PCaselessString(str) { } 01102 explicit EventPackage(const char * str) : PCaselessString(str) { } 01103 01104 EventPackage & operator=(PredefinedPackages pkg); 01105 EventPackage & operator=(const PString & str) { PCaselessString::operator=(str); return *this; } 01106 EventPackage & operator=(const char * str) { PCaselessString::operator=(str); return *this; } 01107 01108 bool operator==(PredefinedPackages pkg) const { return Compare(EventPackage(pkg)) == EqualTo; } 01109 bool operator==(const PString & str) const { return Compare(str) == EqualTo; } 01110 bool operator==(const char * cstr) const { return InternalCompare(0, P_MAX_INDEX, cstr) == EqualTo; } 01111 virtual Comparison InternalCompare(PINDEX offset, PINDEX length, const char * cstr) const; 01112 01113 bool IsWatcher() const; 01114 }; 01115 01117 struct SubscriptionStatus { 01118 SIPSubscribeHandler * m_handler; 01119 PString m_addressofRecord; 01120 bool m_wasSubscribing; 01121 bool m_reSubscribing; 01122 SIP_PDU::StatusCodes m_reason; 01123 OpalProductInfo m_productInfo; 01124 void * m_userData; 01125 }; 01126 01127 struct NotifyCallbackInfo { 01128 NotifyCallbackInfo( 01129 SIPEndPoint & ep, 01130 OpalTransport & trans, 01131 SIP_PDU & notify, 01132 SIP_PDU & response 01133 ); 01134 01135 bool SendResponse( 01136 SIP_PDU::StatusCodes status, 01137 const char * extra = NULL 01138 ); 01139 01140 SIPEndPoint & m_endpoint; 01141 OpalTransport & m_transport; 01142 SIP_PDU & m_notify; 01143 SIP_PDU & m_response; 01144 bool m_sendResponse; 01145 }; 01146 01147 struct Params : public SIPParameters 01148 { 01149 Params(PredefinedPackages pkg = NumPredefinedPackages) 01150 : m_agentAddress(m_remoteAddress) 01151 , m_eventPackage(pkg) 01152 , m_eventList(false) 01153 { } 01154 01155 Params(const Params & param) 01156 : SIPParameters(param) 01157 , m_agentAddress(m_remoteAddress) 01158 , m_eventPackage(param.m_eventPackage) 01159 , m_eventList(param.m_eventList) 01160 , m_contentType(param.m_contentType) 01161 , m_onSubcribeStatus(param.m_onSubcribeStatus) 01162 , m_onNotify(param.m_onNotify) 01163 { } 01164 01165 PCaselessString & m_agentAddress; // For backward compatibility 01166 EventPackage m_eventPackage; 01167 bool m_eventList; // Enable RFC4662 01168 PCaselessString m_contentType; // May be \n separated list of types 01169 01170 PNotifierTemplate<const SubscriptionStatus &> m_onSubcribeStatus; 01171 PNotifierTemplate<NotifyCallbackInfo &> m_onNotify; 01172 }; 01173 01174 SIPSubscribe( 01175 SIPEndPoint & ep, 01176 OpalTransport & trans, 01177 SIPDialogContext & dialog, 01178 const Params & params 01179 ); 01180 01181 virtual SIPTransaction * CreateDuplicate() const; 01182 }; 01183 01184 01185 #if PTRACING 01186 ostream & operator<<(ostream & strm, const SIPSubscribe::Params & params); 01187 #endif 01188 01189 01190 typedef SIPSubscribe::EventPackage SIPEventPackage; 01191 01192 01194 01195 class SIPHandler; 01196 01197 class SIPEventPackageHandler 01198 { 01199 public: 01200 virtual ~SIPEventPackageHandler() { } 01201 virtual PCaselessString GetContentType() const = 0; 01202 virtual bool ValidateContentType(const PString & type, const SIPMIMEInfo & mime); 01203 virtual bool OnReceivedNOTIFY(SIPHandler & handler, SIP_PDU & request) = 0; 01204 virtual PString OnSendNOTIFY(SIPHandler & /*handler*/, const PObject * /*body*/) { return PString::Empty(); } 01205 }; 01206 01207 01208 typedef PFactory<SIPEventPackageHandler, SIPEventPackage> SIPEventPackageFactory; 01209 01210 01212 01213 class SIPNotify : public SIPTransaction 01214 { 01215 PCLASSINFO(SIPNotify, SIPTransaction); 01216 public: 01217 SIPNotify( 01218 SIPEndPoint & ep, 01219 OpalTransport & trans, 01220 SIPDialogContext & dialog, 01221 const SIPEventPackage & eventPackage, 01222 const PString & state, 01223 const PString & body 01224 ); 01225 01226 virtual SIPTransaction * CreateDuplicate() const; 01227 }; 01228 01229 01231 01232 class SIPPublish : public SIPTransaction 01233 { 01234 PCLASSINFO(SIPPublish, SIPTransaction); 01235 public: 01236 SIPPublish( 01237 SIPEndPoint & ep, 01238 OpalTransport & trans, 01239 const PString & id, 01240 const PString & sipIfMatch, 01241 const SIPSubscribe::Params & params, 01242 const PString & body 01243 ); 01244 01245 virtual SIPTransaction * CreateDuplicate() const; 01246 }; 01247 01248 01250 01251 class SIPRefer : public SIPTransaction 01252 { 01253 PCLASSINFO(SIPRefer, SIPTransaction); 01254 public: 01255 SIPRefer( 01256 SIPConnection & connection, 01257 const SIPURL & referTo, 01258 const SIPURL & referred_by = SIPURL() 01259 ); 01260 01261 virtual SIPTransaction * CreateDuplicate() const; 01262 }; 01263 01264 01266 01267 /* This is not a generic NOTIFY PDU, but the minimal one 01268 * that gets sent when receiving a REFER 01269 */ 01270 class SIPReferNotify : public SIPTransaction 01271 { 01272 PCLASSINFO(SIPReferNotify, SIPTransaction); 01273 public: 01274 SIPReferNotify( 01275 SIPConnection & connection, 01276 StatusCodes code 01277 ); 01278 01279 virtual SIPTransaction * CreateDuplicate() const; 01280 }; 01281 01282 01284 01285 /* This is a MESSAGE PDU, with a body 01286 */ 01287 class SIPMessage : public SIPTransaction 01288 { 01289 PCLASSINFO(SIPMessage, SIPTransaction); 01290 public: 01291 struct Params : public SIPParameters 01292 { 01293 Params() 01294 : m_contentType("text/plain;charset=UTF-8") 01295 { 01296 m_expire = 5000; 01297 } 01298 01299 PCaselessString m_contentType; 01300 PString m_id; 01301 PString m_body; 01302 PAtomicInteger::IntegerType m_messageId; 01303 }; 01304 01305 SIPMessage( 01306 SIPEndPoint & ep, 01307 OpalTransport & trans, 01308 const Params & params 01309 ); 01310 SIPMessage( 01311 SIPConnection & connection, 01312 const Params & params 01313 ); 01314 01315 virtual SIPTransaction * CreateDuplicate() const; 01316 01317 const SIPURL & GetLocalAddress() const { return m_localAddress; } 01318 01319 private: 01320 void Construct(const Params & params); 01321 01322 SIPURL m_localAddress; 01323 }; 01324 01325 01327 01328 /* This is an OPTIONS request 01329 */ 01330 class SIPOptions : public SIPTransaction 01331 { 01332 PCLASSINFO(SIPOptions, SIPTransaction); 01333 01334 public: 01335 struct Params : public SIPParameters 01336 { 01337 Params() 01338 : m_acceptContent("application/sdp, application/media_control+xml, application/dtmf, application/dtmf-relay") 01339 { 01340 } 01341 01342 PCaselessString m_acceptContent; 01343 PCaselessString m_contentType; 01344 PString m_body; 01345 }; 01346 01347 SIPOptions( 01348 SIPEndPoint & ep, 01349 OpalTransport & trans, 01350 const PString & id, 01351 const Params & params 01352 ); 01353 SIPOptions( 01354 SIPConnection & conn, 01355 const Params & params 01356 ); 01357 01358 virtual SIPTransaction * CreateDuplicate() const; 01359 01360 protected: 01361 void Construct(const Params & params); 01362 }; 01363 01364 01366 01367 /* This is an INFO request 01368 */ 01369 class SIPInfo : public SIPTransaction 01370 { 01371 PCLASSINFO(SIPInfo, SIPTransaction); 01372 01373 public: 01374 struct Params 01375 { 01376 Params(const PString & contentType = PString::Empty(), 01377 const PString & body = PString::Empty()) 01378 : m_contentType(contentType) 01379 , m_body(body) 01380 { 01381 } 01382 01383 PCaselessString m_contentType; 01384 PString m_body; 01385 }; 01386 01387 SIPInfo( 01388 SIPConnection & conn, 01389 const Params & params 01390 ); 01391 01392 virtual SIPTransaction * CreateDuplicate() const; 01393 }; 01394 01395 01397 01398 /* This is a PING PDU, with a body 01399 */ 01400 class SIPPing : public SIPTransaction 01401 { 01402 PCLASSINFO(SIPPing, SIPTransaction); 01403 01404 public: 01405 SIPPing( 01406 SIPEndPoint & ep, 01407 OpalTransport & trans, 01408 const SIPURL & address 01409 ); 01410 01411 virtual SIPTransaction * CreateDuplicate() const; 01412 }; 01413 01414 01416 01417 /* This is a PRACK PDU 01418 */ 01419 class SIPPrack : public SIPTransaction 01420 { 01421 PCLASSINFO(SIPPrack, SIPTransaction); 01422 01423 public: 01424 SIPPrack( 01425 SIPConnection & conn, 01426 const PString & rack 01427 ); 01428 01429 virtual SIPTransaction * CreateDuplicate() const; 01430 }; 01431 01432 01433 #endif // OPAL_SIP 01434 01435 #endif // OPAL_SIP_SIPPDU_H 01436 01437 01438 // End of File ///////////////////////////////////////////////////////////////