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

Generated on Wed Aug 1 23:49:38 2012 for OPAL by  doxygen 1.4.7