OPAL  Version 3.10.4
sippdu.h
Go to the documentation of this file.
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 ///////////////////////////////////////////////////////////////