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

Generated on 14 Aug 2013 for OPAL by  doxygen 1.4.7