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