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: 24198 $
00028  * $Author: rjongbloed $
00029  * $Date: 2010-04-06 20:26:52 -0500 (Tue, 06 Apr 2010) $
00030  */
00031 
00032 #ifndef OPAL_SIP_SIPPDU_H
00033 #define OPAL_SIP_SIPPDU_H
00034 
00035 #ifdef P_USE_PRAGMA
00036 #pragma interface
00037 #endif
00038 
00039 #include <opal/buildopts.h>
00040 
00041 #if OPAL_SIP
00042 
00043 #include <ptclib/mime.h>
00044 #include <ptclib/url.h>
00045 #include <ptclib/http.h>
00046 #include <sip/sdp.h>
00047 #include <opal/rtpconn.h>
00048 
00049  
00050 class OpalTransport;
00051 class OpalTransportAddress;
00052 class OpalProductInfo;
00053 
00054 class SIPEndPoint;
00055 class SIPConnection;
00056 class SIP_PDU;
00057 class SIPSubscribeHandler;
00058 class SIPDialogContext;
00059 
00060 
00062 // SIPURL
00063 
00069 class SIPURL : public PURL
00070 {
00071   PCLASSINFO(SIPURL, PURL);
00072   public:
00073     SIPURL();
00074 
00077     SIPURL(
00078       const char * cstr,    
00079       const char * defaultScheme = NULL 
00080     );
00081 
00084     SIPURL(
00085       const PString & str,  
00086       const char * defaultScheme = NULL 
00087     );
00088 
00096     SIPURL(
00097       const PString & name,
00098       const OpalTransportAddress & address,
00099       WORD listenerPort = 0
00100     );
00101 
00102     SIPURL(
00103       const OpalTransportAddress & _address, 
00104       WORD listenerPort = 0
00105     );
00106 
00115     virtual Comparison Compare(
00116       const PObject & obj   
00117     ) const;
00118 
00122     PString AsQuotedString() const;
00123 
00126     PString GetDisplayName(PBoolean useDefault = PTrue) const;
00127     
00128     void SetDisplayName(const PString & str) 
00129       { displayName = str; }
00130 
00133     PString GetFieldParameters() const { return fieldParameters; }
00134 
00137     void SetFieldParameters(const PString & str ) { fieldParameters = str; }
00138 
00141     OpalTransportAddress GetHostAddress() const;
00142 
00143     enum UsageContext {
00144       ExternalURI,  
00145       RequestURI,   
00146       ToURI,        
00147       FromURI,      
00148       ContactURI,   
00149       RouteURI,     
00150       RegisterURI   
00151     };
00152 
00158     void Sanitise(
00159       UsageContext context  
00160     );
00161 
00167     PBoolean AdjustToDNS(
00168       PINDEX entry = 0  
00169     );
00170 
00172     static PString GenerateTag();
00173 
00175     void SetTag(
00176       const PString & tag = GenerateTag()
00177     );
00178 
00179   protected:
00180     void ParseAsAddress(const PString & name, const OpalTransportAddress & _address, WORD listenerPort = 0);
00181 
00200     virtual PBoolean InternalParse(
00201       const char * cstr,
00202       const char * defaultScheme
00203     );
00204 
00205     PString displayName;
00206     PString fieldParameters;
00207 };
00208 
00209 
00211 // SIPMIMEInfo
00212 
00243 class SIPMIMEInfo : public PMIMEInfo
00244 {
00245   PCLASSINFO(SIPMIMEInfo, PMIMEInfo);
00246   public:
00247     SIPMIMEInfo(bool compactForm = false);
00248 
00249     virtual void PrintOn(ostream & strm) const;
00250     virtual void ReadFrom(istream & strm);
00251 
00252     void SetCompactForm(bool form) { compactForm = form; }
00253 
00254     PCaselessString GetContentType(bool includeParameters = false) const;
00255     void SetContentType(const PString & v);
00256 
00257     PCaselessString GetContentEncoding() const;
00258     void SetContentEncoding(const PString & v);
00259 
00260     PString GetFrom() const;
00261     void SetFrom(const PString & v);
00262 
00263     PString GetPAssertedIdentity() const;
00264     void SetPAssertedIdentity(const PString & v);
00265 
00266     PString GetPPreferredIdentity() const;
00267     void SetPPreferredIdentity(const PString & v);
00268 
00269     PString GetAccept() const;
00270     void SetAccept(const PString & v);
00271 
00272     PString GetAcceptEncoding() const;
00273     void SetAcceptEncoding(const PString & v);
00274 
00275     PString GetAcceptLanguage() const;
00276     void SetAcceptLanguage(const PString & v);
00277 
00278     PString GetAllow() const;
00279     void SetAllow(const PString & v);
00280 
00281     PString GetCallID() const;
00282     void SetCallID(const PString & v);
00283 
00284     PString GetContact() const;
00285     bool GetContacts(std::set<SIPURL> & contacts) const;
00286     void SetContact(const PString & v);
00287 
00288     PString GetSubject() const;
00289     void SetSubject(const PString & v);
00290 
00291     PString GetTo() const;
00292     void SetTo(const PString & v);
00293 
00294     PString GetVia() const;
00295     void SetVia(const PString & v);
00296 
00297     PStringList GetViaList() const;
00298     void SetViaList(const PStringList & v);
00299 
00300     PString GetReferTo() const;
00301     void SetReferTo(const PString & r);
00302 
00303     PString GetReferredBy() const;
00304     void SetReferredBy(const PString & r);
00305 
00306     PINDEX  GetContentLength() const;
00307     void SetContentLength(PINDEX v);
00308     PBoolean IsContentLengthPresent() const;
00309 
00310     PString GetCSeq() const;
00311     void SetCSeq(const PString & v);
00312 
00313     PString GetDate() const;
00314     void SetDate(const PString & v);
00315     void SetDate(const PTime & t);
00316     void SetDate(void); // set to current date
00317 
00318     unsigned GetExpires(unsigned dflt = UINT_MAX) const;// returns default value if not found
00319     void SetExpires(unsigned v);
00320 
00321     PINDEX GetMaxForwards() const;
00322     void SetMaxForwards(PINDEX v);
00323 
00324     PINDEX GetMinExpires() const;
00325     void SetMinExpires(PINDEX v);
00326 
00327     PString GetProxyAuthenticate() const;
00328     void SetProxyAuthenticate(const PString & v);
00329 
00330     PStringList GetRoute() const;
00331     void SetRoute(const PString & v);
00332     void SetRoute(const PStringList & v);
00333 
00334     PStringList GetRecordRoute(bool reversed) const;
00335     void SetRecordRoute(const PStringList & v);
00336 
00337     unsigned GetCSeqIndex() const { return GetCSeq().AsUnsigned(); }
00338 
00339     PString GetSupported() const;
00340     void SetSupported(const PString & v);
00341 
00342     PString GetUnsupported() const;
00343     void SetUnsupported(const PString & v);
00344     
00345     PString GetEvent() const;
00346     void SetEvent(const PString & v);
00347     
00348     PCaselessString GetSubscriptionState(PStringToString & info) const;
00349     void SetSubscriptionState(const PString & v);
00350     
00351     PString GetUserAgent() const;
00352     void SetUserAgent(const PString & v);
00353 
00354     PString GetOrganization() const;
00355     void SetOrganization(const PString & v);
00356 
00357     void GetProductInfo(OpalProductInfo & info) const;
00358     void SetProductInfo(const PString & ua, const OpalProductInfo & info);
00359 
00360     PString GetWWWAuthenticate() const;
00361     void SetWWWAuthenticate(const PString & v);
00362 
00363     PString GetSIPIfMatch() const;
00364     void SetSIPIfMatch(const PString & v);
00365 
00366     PString GetSIPETag() const;
00367     void SetSIPETag(const PString & v);
00368 
00369     PString GetRequire() const;
00370     void SetRequire(const PString & v, bool overwrite);
00371 
00372     void GetAlertInfo(PString & info, int & appearance);
00373     void SetAlertInfo(const PString & info, int appearance);
00374 
00375     PString GetAllowEvents() const;
00376     void SetAllowEvents(const PString & v);
00377 
00380     PString GetFieldParameter(
00381       const PString & fieldName,    
00382       const PString & paramName,    
00383       const PString & defaultValue = PString::Empty()  
00384     ) const { return ExtractFieldParameter((*this)(fieldName), paramName, defaultValue); }
00385 
00390     void SetFieldParameter(
00391       const PString & fieldName,    
00392       const PString & paramName,    
00393       const PString & newValue      
00394     ) { SetAt(fieldName, InsertFieldParameter((*this)(fieldName), paramName, newValue)); }
00395 
00398     static PString ExtractFieldParameter(
00399       const PString & fieldValue,   
00400       const PString & paramName,    
00401       const PString & defaultValue = PString::Empty()  
00402     );
00403 
00408     static PString InsertFieldParameter(
00409       const PString & fieldValue,   
00410       const PString & paramName,    
00411       const PString & newValue      
00412     );
00413 
00414   protected:
00417     PStringList GetRouteList(const char * name, bool reversed) const;
00418 
00422     void SetRouteList(const char * name, const PStringList & v);
00423 
00425     bool compactForm;
00426 };
00427 
00428 
00430 // SIPAuthentication
00431 
00432 typedef PHTTPClientAuthentication SIPAuthentication;
00433 
00434 class SIPAuthenticator : public PHTTPClientAuthentication::AuthObject
00435 {
00436   public:
00437     SIPAuthenticator(SIP_PDU & pdu);
00438     virtual PMIMEInfo & GetMIME();
00439     virtual PString GetURI();
00440     virtual PString GetEntityBody();
00441     virtual PString GetMethod();
00442 
00443   protected:  
00444     SIP_PDU & m_pdu;
00445 };
00446 
00447 
00448 
00450 // SIP_PDU
00451 
00457 class SIP_PDU : public PSafeObject
00458 {
00459   PCLASSINFO(SIP_PDU, PSafeObject);
00460   public:
00461     enum Methods {
00462       Method_INVITE,
00463       Method_ACK,
00464       Method_OPTIONS,
00465       Method_BYE,
00466       Method_CANCEL,
00467       Method_REGISTER,
00468       Method_SUBSCRIBE,
00469       Method_NOTIFY,
00470       Method_REFER,
00471       Method_MESSAGE,
00472       Method_INFO,
00473       Method_PING,
00474       Method_PUBLISH,
00475       NumMethods
00476     };
00477 
00478     enum StatusCodes {
00479       IllegalStatusCode,
00480       Local_TransportError,
00481       Local_BadTransportAddress,
00482       Local_Timeout,
00483 
00484       Information_Trying                  = 100,
00485       Information_Ringing                 = 180,
00486       Information_CallForwarded           = 181,
00487       Information_Queued                  = 182,
00488       Information_Session_Progress        = 183,
00489 
00490       Successful_OK                       = 200,
00491       Successful_Accepted                         = 202,
00492 
00493       Redirection_MultipleChoices         = 300,
00494       Redirection_MovedPermanently        = 301,
00495       Redirection_MovedTemporarily        = 302,
00496       Redirection_UseProxy                = 305,
00497       Redirection_AlternativeService      = 380,
00498 
00499       Failure_BadRequest                  = 400,
00500       Failure_UnAuthorised                = 401,
00501       Failure_PaymentRequired             = 402,
00502       Failure_Forbidden                   = 403,
00503       Failure_NotFound                    = 404,
00504       Failure_MethodNotAllowed            = 405,
00505       Failure_NotAcceptable               = 406,
00506       Failure_ProxyAuthenticationRequired = 407,
00507       Failure_RequestTimeout              = 408,
00508       Failure_Conflict                    = 409,
00509       Failure_Gone                        = 410,
00510       Failure_LengthRequired              = 411,
00511       Failure_RequestEntityTooLarge       = 413,
00512       Failure_RequestURITooLong           = 414,
00513       Failure_UnsupportedMediaType        = 415,
00514       Failure_UnsupportedURIScheme        = 416,
00515       Failure_BadExtension                = 420,
00516       Failure_ExtensionRequired           = 421,
00517       Failure_IntervalTooBrief            = 423,
00518       Failure_TemporarilyUnavailable      = 480,
00519       Failure_TransactionDoesNotExist     = 481,
00520       Failure_LoopDetected                = 482,
00521       Failure_TooManyHops                 = 483,
00522       Failure_AddressIncomplete           = 484,
00523       Failure_Ambiguous                   = 485,
00524       Failure_BusyHere                    = 486,
00525       Failure_RequestTerminated           = 487,
00526       Failure_NotAcceptableHere           = 488,
00527       Failure_BadEvent                    = 489,
00528       Failure_RequestPending              = 491,
00529       Failure_Undecipherable              = 493,
00530 
00531       Failure_InternalServerError         = 500,
00532       Failure_NotImplemented              = 501,
00533       Failure_BadGateway                  = 502,
00534       Failure_ServiceUnavailable          = 503,
00535       Failure_ServerTimeout               = 504,
00536       Failure_SIPVersionNotSupported      = 505,
00537       Failure_MessageTooLarge             = 513,
00538 
00539       GlobalFailure_BusyEverywhere        = 600,
00540       GlobalFailure_Decline               = 603,
00541       GlobalFailure_DoesNotExistAnywhere  = 604,
00542       GlobalFailure_NotAcceptable         = 606,
00543 
00544       MaxStatusCode                       = 699
00545     };
00546 
00547         static const char * GetStatusCodeDescription(int code);
00548     friend ostream & operator<<(ostream & strm, StatusCodes status);
00549 
00550     enum {
00551       MaxSize = 65535
00552     };
00553 
00554     SIP_PDU(
00555       Methods method = SIP_PDU::NumMethods
00556     );
00557 
00561     SIP_PDU(
00562       const SIP_PDU & request,
00563       StatusCodes code,
00564       const char * contact = NULL,
00565       const char * extra = NULL,
00566       const SDPSessionDescription * sdp = NULL
00567     );
00568 
00569     SIP_PDU(const SIP_PDU &);
00570     SIP_PDU & operator=(const SIP_PDU &);
00571     ~SIP_PDU();
00572 
00573     void PrintOn(
00574       ostream & strm
00575     ) const;
00576 
00577     void InitialiseHeaders(
00578       const SIPURL & dest,
00579       const SIPURL & to,
00580       const SIPURL & from,
00581       const PString & callID,
00582       unsigned cseq,
00583       const PString & via
00584     );
00585     void InitialiseHeaders(
00586       SIPDialogContext & dialog,
00587       const PString & via = PString::Empty()
00588     );
00589     void InitialiseHeaders(
00590       SIPConnection & connection,
00591       const OpalTransport & transport
00592     );
00593 
00598     bool SetRoute(const PStringList & routeSet);
00599     bool SetRoute(const SIPURL & proxy);
00600 
00603     void SetAllow(unsigned bitmask);
00604 
00607     void AdjustVia(OpalTransport & transport);
00608 
00609     PString CreateVia(
00610       SIPEndPoint & endpoint,
00611       const OpalTransport & transport,
00612       SIPConnection * connection = NULL
00613     );
00614 
00617     PBoolean Read(
00618       OpalTransport & transport
00619     );
00620 
00623     PBoolean Write(
00624       OpalTransport & transport,
00625       const OpalTransportAddress & remoteAddress = OpalTransportAddress(),
00626       const PString & localInterface = PString::Empty()
00627     );
00628 
00631     bool SendResponse(
00632       OpalTransport & transport,
00633       StatusCodes code,
00634       SIPEndPoint * endpoint = NULL,
00635       const char * contact = NULL,
00636       const char * extra = NULL
00637     );
00638     bool SendResponse(
00639       OpalTransport & transport,
00640       SIP_PDU & response,
00641       SIPEndPoint * endpoint = NULL
00642     );
00643 
00647     PString Build();
00648 
00649     PString GetTransactionID() const;
00650 
00651     Methods GetMethod() const                { return m_method; }
00652     StatusCodes GetStatusCode () const       { return m_statusCode; }
00653     void SetStatusCode (StatusCodes c)       { m_statusCode = c; }
00654     const SIPURL & GetURI() const            { return m_uri; }
00655     unsigned GetVersionMajor() const         { return m_versionMajor; }
00656     unsigned GetVersionMinor() const         { return m_versionMinor; }
00657     const PString & GetEntityBody() const    { return m_entityBody; }
00658     void SetEntityBody(const PString & body) { m_entityBody = body; }
00659     const PString & GetInfo() const          { return m_info; }
00660     void SetInfo(const PString & info)       { m_info = info; }
00661     const SIPMIMEInfo & GetMIME() const      { return m_mime; }
00662           SIPMIMEInfo & GetMIME()            { return m_mime; }
00663     void SetURI(const SIPURL & newuri)       { m_uri = newuri; }
00664     SDPSessionDescription * GetSDP();
00665     void SetSDP(SDPSessionDescription * sdp);
00666 
00667   protected:
00668     Methods     m_method;                 // Request type, ==NumMethods for Response
00669     StatusCodes m_statusCode;
00670     SIPURL      m_uri;                    // display name & URI, no tag
00671     unsigned    m_versionMajor;
00672     unsigned    m_versionMinor;
00673     PString     m_info;
00674     SIPMIMEInfo m_mime;
00675     PString     m_entityBody;
00676 
00677     SDPSessionDescription * m_SDP;
00678 
00679     mutable PString m_transactionID;
00680 
00681     bool m_usePeerTransportAddress;
00682 };
00683 
00684 
00685 PQUEUE(SIP_PDU_Queue, SIP_PDU);
00686 
00687 
00688 #if PTRACING
00689 ostream & operator<<(ostream & strm, SIP_PDU::Methods method);
00690 #endif
00691 
00692 
00694 // SIPDialogContext
00695 
00698 class SIPDialogContext
00699 {
00700   public:
00701     SIPDialogContext();
00702 
00703     PString AsString() const;
00704     bool FromString(
00705       const PString & str
00706     );
00707 
00708     const PString & GetCallID() const { return m_callId; }
00709     void SetCallID(const PString & id) { m_callId = id; }
00710 
00711     const SIPURL & GetRequestURI() const { return m_requestURI; }
00712     void SetRequestURI(const SIPURL & url) { m_requestURI = url; }
00713     bool SetRequestURI(const PString & uri) { return m_requestURI.Parse(uri); }
00714 
00715     const PString & GetLocalTag() const { return m_localTag; }
00716     void SetLocalTag(const PString & tag) { m_localTag = tag; }
00717 
00718     const SIPURL & GetLocalURI() const { return m_localURI; }
00719     void SetLocalURI(const SIPURL & url);
00720     bool SetLocalURI(const PString & uri);
00721 
00722     const PString & GetRemoteTag() const { return m_remoteTag; }
00723     void SetRemoteTag(const PString & tag) { m_remoteTag = tag; }
00724 
00725     const SIPURL & GetRemoteURI() const { return m_remoteURI; }
00726     void SetRemoteURI(const SIPURL & url);
00727     bool SetRemoteURI(const PString & uri);
00728 
00729     const PStringList & GetRouteSet() const { return m_routeSet; }
00730     void SetRouteSet(const PStringList & routes) { m_routeSet = routes; }
00731 
00732     const SIPURL & GetProxy() const { return m_proxy; }
00733     void SetProxy(const SIPURL & proxy, bool addToRouteSet);
00734 
00735     void Update(const SIP_PDU & response);
00736 
00737     unsigned GetNextCSeq(unsigned inc = 1) { return m_lastSentCSeq += inc; }
00738     bool IsDuplicateCSeq(unsigned sequenceNumber);
00739 
00740     bool IsEstablished() const
00741     {
00742       return !m_callId.IsEmpty() &&
00743              !m_requestURI.IsEmpty() &&
00744              !m_localTag.IsEmpty() &&
00745              !m_remoteTag.IsEmpty();
00746     }
00747 
00748     bool UsePeerTransportAddress() const { return m_usePeerTransportAddress; }
00749 
00750   protected:
00751     PString     m_callId;
00752     SIPURL      m_requestURI;
00753     SIPURL      m_localURI;
00754     PString     m_localTag;
00755     SIPURL      m_remoteURI;
00756     PString     m_remoteTag;
00757     PStringList m_routeSet;
00758     unsigned    m_lastSentCSeq;
00759     unsigned    m_lastReceivedCSeq;
00760     bool        m_usePeerTransportAddress;
00761     SIPURL      m_proxy;
00762 };
00763 
00764 
00766 
00767 struct SIPParameters
00768 {
00769   SIPParameters(
00770     const PString & aor = PString::Empty(),
00771     const PString & remote = PString::Empty()
00772   );
00773 
00774   void Normalise(
00775     const PString & defaultUser,
00776     const PTimeInterval & defaultExpire
00777   );
00778 
00779   PCaselessString m_remoteAddress;
00780   PCaselessString m_localAddress;
00781   PCaselessString m_proxyAddress;
00782   PCaselessString m_addressOfRecord;
00783   PCaselessString m_contactAddress;
00784   PString         m_authID;
00785   PString         m_password;
00786   PString         m_realm;
00787   unsigned        m_expire;
00788   unsigned        m_restoreTime;
00789   PTimeInterval   m_minRetryTime;
00790   PTimeInterval   m_maxRetryTime;
00791   void          * m_userData;
00792 };
00793 
00794 
00795 #if PTRACING
00796 ostream & operator<<(ostream & strm, const SIPParameters & params);
00797 #endif
00798 
00799 
00801 // SIPTransaction
00802 
00813 class SIPTransaction : public SIP_PDU
00814 {
00815     PCLASSINFO(SIPTransaction, SIP_PDU);
00816   public:
00817     SIPTransaction(
00818       Methods method,
00819       SIPEndPoint   & endpoint,
00820       OpalTransport & transport
00821     );
00825     SIPTransaction(
00826       Methods method,
00827       SIPConnection & connection
00828     );
00829     ~SIPTransaction();
00830 
00831     PBoolean Start();
00832     bool IsTrying()     const { return m_state == Trying; }
00833     bool IsProceeding() const { return m_state == Proceeding; }
00834     bool IsInProgress() const { return m_state == Trying || m_state == Proceeding; }
00835     bool IsFailed()     const { return m_state > Terminated_Success; }
00836     bool IsCompleted()  const { return m_state >= Completed; }
00837     bool IsCanceled()   const { return m_state == Cancelling || m_state == Terminated_Cancelled || m_state == Terminated_Aborted; }
00838     bool IsTerminated() const { return m_state >= Terminated_Success; }
00839 
00840     void WaitForTermination();
00841     PBoolean Cancel();
00842     void Abort();
00843 
00844     virtual PBoolean OnReceivedResponse(SIP_PDU & response);
00845     virtual PBoolean OnCompleted(SIP_PDU & response);
00846 
00847     OpalTransport & GetTransport()  const { return m_transport; }
00848     SIPConnection * GetConnection() const { return m_connection; }
00849     PString         GetInterface()  const { return m_localInterface; }
00850 
00851     static PString GenerateCallID();
00852 
00853   protected:
00854     bool SendPDU(SIP_PDU & pdu);
00855     bool ResendCANCEL();
00856     void SetParameters(const SIPParameters & params);
00857     void SetContact(const SIPURL & uri);
00858 
00859     PDECLARE_NOTIFIER(PTimer, SIPTransaction, OnRetry);
00860     PDECLARE_NOTIFIER(PTimer, SIPTransaction, OnTimeout);
00861 
00862     enum States {
00863       NotStarted,
00864       Trying,
00865       Proceeding,
00866       Cancelling,
00867       Completed,
00868       Terminated_Success,
00869       Terminated_Timeout,
00870       Terminated_RetriesExceeded,
00871       Terminated_TransportError,
00872       Terminated_Cancelled,
00873       Terminated_Aborted,
00874       NumStates
00875     };
00876     virtual void SetTerminated(States newState);
00877 
00878     SIPEndPoint           & m_endpoint;
00879     OpalTransport         & m_transport;
00880     PSafePtr<SIPConnection> m_connection;
00881     PTimeInterval           m_retryTimeoutMin; 
00882     PTimeInterval           m_retryTimeoutMax; 
00883 
00884     States     m_state;
00885     unsigned   m_retry;
00886     PTimer     m_retryTimer;
00887     PTimer     m_completionTimer;
00888     PSyncPoint m_terminated;
00889 
00890     PString              m_localInterface;
00891     OpalTransportAddress m_remoteAddress;
00892 };
00893 
00894 
00895 #define OPAL_PROXY_PARAM    "OPAL-proxy"
00896 #define OPAL_LOCAL_ID_PARAM "OPAL-local-id"
00897 
00898 
00900 // SIPInvite
00901 
00907 class SIPInvite : public SIPTransaction
00908 {
00909     PCLASSINFO(SIPInvite, SIPTransaction);
00910   public:
00911     SIPInvite(
00912       SIPConnection & connection,
00913       const OpalRTPSessionManager & sm
00914     );
00915 
00916     virtual PBoolean OnReceivedResponse(SIP_PDU & response);
00917 
00918     const OpalRTPSessionManager & GetSessionManager() const { return m_rtpSessions; }
00919           OpalRTPSessionManager & GetSessionManager()       { return m_rtpSessions; }
00920 
00921   protected:
00922     OpalRTPSessionManager m_rtpSessions;
00923 };
00924 
00925 
00927 
00928 class SIPRegister : public SIPTransaction
00929 {
00930     PCLASSINFO(SIPRegister, SIPTransaction);
00931   public:
00932     enum CompatibilityModes {
00933       e_FullyCompliant,                 
00936       e_CannotRegisterMultipleContacts, 
00940       e_CannotRegisterPrivateContacts   
00944     };
00945 
00947     struct Params : public SIPParameters {
00948       Params()
00949         : m_registrarAddress(m_remoteAddress)
00950         , m_compatibility(SIPRegister::e_FullyCompliant)
00951       { }
00952 
00953       Params(const Params & param)
00954         : SIPParameters(param)
00955         , m_registrarAddress(m_remoteAddress)
00956         , m_compatibility(param.m_compatibility)
00957       { }
00958 
00959       PCaselessString  & m_registrarAddress; // For backward compatibility
00960       CompatibilityModes m_compatibility;
00961     };
00962 
00963     SIPRegister(
00964       SIPEndPoint   & endpoint,
00965       OpalTransport & transport,
00966       const PString & callId,
00967       unsigned cseq,
00968       const Params & params
00969     );
00970 };
00971 
00972 
00973 #if PTRACING
00974 ostream & operator<<(ostream & strm, SIPRegister::CompatibilityModes mode);
00975 ostream & operator<<(ostream & strm, const SIPRegister::Params & params);
00976 #endif
00977 
00978 
00980 
00981 class SIPSubscribe : public SIPTransaction
00982 {
00983     PCLASSINFO(SIPSubscribe, SIPTransaction);
00984   public:
00987     enum PredefinedPackages {
00988       MessageSummary,
00989       Presence,
00990       Dialog,
00991 
00992       NumPredefinedPackages,
00993 
00994       Watcher = 0x8000,
00995 
00996       MessageSummaryWatcher = Watcher|MessageSummary,
00997       PresenceWatcher       = Watcher|Presence,
00998       DialogWatcher         = Watcher|Dialog,
00999 
01000       PackageMask = Watcher-1
01001     };
01002     friend PredefinedPackages operator|(PredefinedPackages p1, PredefinedPackages p2) { return (PredefinedPackages)((int)p1|(int)p2); }
01003 
01004     class EventPackage : public PCaselessString
01005     {
01006       PCLASSINFO(EventPackage, PCaselessString);
01007       public:
01008         EventPackage(PredefinedPackages = NumPredefinedPackages);
01009         explicit EventPackage(const PString & str) : PCaselessString(str) { }
01010         explicit EventPackage(const char   *  str) : PCaselessString(str) { }
01011 
01012         EventPackage & operator=(PredefinedPackages pkg);
01013         EventPackage & operator=(const PString & str) { PCaselessString::operator=(str); return *this; }
01014         EventPackage & operator=(const char   *  str) { PCaselessString::operator=(str); return *this; }
01015 
01016         bool operator==(PredefinedPackages pkg) const { return Compare(EventPackage(pkg)) == EqualTo; }
01017         bool operator==(const PString & str) const { return Compare(str) == EqualTo; }
01018         bool operator==(const char * cstr) const { return InternalCompare(0, P_MAX_INDEX, cstr) == EqualTo; }
01019         virtual Comparison InternalCompare(PINDEX offset, PINDEX length, const char * cstr) const;
01020 
01021         bool IsWatcher() const;
01022     };
01023 
01025     struct SubscriptionStatus {
01026       SIPSubscribeHandler * m_handler;           
01027       PString               m_addressofRecord;   
01028       bool                  m_wasSubscribing;    
01029       bool                  m_reSubscribing;     
01030       SIP_PDU::StatusCodes  m_reason;            
01031       OpalProductInfo       m_productInfo;       
01032       void                * m_userData;          
01033     };
01034 
01035     struct NotifyCallbackInfo {
01036       NotifyCallbackInfo(
01037         SIPEndPoint & ep,
01038         OpalTransport & trans,
01039         SIP_PDU & notify,
01040         SIP_PDU & response
01041       );
01042 
01043       bool SendResponse(
01044         SIP_PDU::StatusCodes status,
01045         const char * extra = NULL
01046       );
01047 
01048       SIPEndPoint   & m_endpoint;
01049       OpalTransport & m_transport;
01050       SIP_PDU       & m_notify;
01051       SIP_PDU       & m_response;
01052       bool            m_sendResponse;
01053     };
01054 
01055     struct Params : public SIPParameters
01056     {
01057       Params(PredefinedPackages pkg = NumPredefinedPackages)
01058         : m_agentAddress(m_remoteAddress)
01059         , m_eventPackage(pkg)
01060         , m_eventList(false)
01061       { }
01062 
01063       Params(const Params & param)
01064         : SIPParameters(param)
01065         , m_agentAddress(m_remoteAddress)
01066         , m_eventPackage(param.m_eventPackage)
01067         , m_eventList(param.m_eventList)
01068         , m_contentType(param.m_contentType)
01069         , m_onSubcribeStatus(param.m_onSubcribeStatus)
01070         , m_onNotify(param.m_onNotify)
01071       { }
01072 
01073       PCaselessString & m_agentAddress; // For backward compatibility
01074       EventPackage      m_eventPackage;
01075       bool              m_eventList;    // Enable RFC4662
01076       PCaselessString   m_contentType;  // May be \n separated list of types
01077 
01078       PNotifierTemplate<const SubscriptionStatus &> m_onSubcribeStatus;
01079       PNotifierTemplate<NotifyCallbackInfo &> m_onNotify;
01080     };
01081 
01082     SIPSubscribe(
01083         SIPEndPoint & ep,
01084         OpalTransport & trans,
01085         SIPDialogContext & dialog,
01086         const Params & params
01087     );
01088 };
01089 
01090 
01091 #if PTRACING
01092 ostream & operator<<(ostream & strm, const SIPSubscribe::Params & params);
01093 #endif
01094 
01095 
01096 typedef SIPSubscribe::EventPackage SIPEventPackage;
01097 
01098 
01100 
01101 class SIPHandler;
01102 
01103 class SIPEventPackageHandler
01104 {
01105 public:
01106   virtual ~SIPEventPackageHandler() { }
01107   virtual PCaselessString GetContentType() const = 0;
01108   virtual bool OnReceivedNOTIFY(SIPHandler & handler, SIP_PDU & request) = 0;
01109   virtual PString OnSendNOTIFY(SIPHandler & /*handler*/, const PObject * /*body*/) { return PString::Empty(); }
01110 };
01111 
01112 
01113 typedef PFactory<SIPEventPackageHandler, SIPEventPackage> SIPEventPackageFactory;
01114 
01115 
01117 
01118 class SIPNotify : public SIPTransaction
01119 {
01120     PCLASSINFO(SIPNotify, SIPTransaction);
01121   public:
01122     SIPNotify(
01123         SIPEndPoint & ep,
01124         OpalTransport & trans,
01125         SIPDialogContext & dialog,
01126         const SIPEventPackage & eventPackage,
01127         const PString & state,
01128         const PString & body
01129     );
01130 };
01131 
01132 
01134 
01135 class SIPPublish : public SIPTransaction
01136 {
01137     PCLASSINFO(SIPPublish, SIPTransaction);
01138   public:
01139     SIPPublish(
01140       SIPEndPoint & ep,
01141       OpalTransport & trans,
01142       const PString & id,
01143       const PString & sipIfMatch,
01144       const SIPSubscribe::Params & params,
01145       const PString & body
01146     );
01147 };
01148 
01149 
01151 
01152 class SIPRefer : public SIPTransaction
01153 {
01154   PCLASSINFO(SIPRefer, SIPTransaction);
01155   public:
01156     SIPRefer(
01157       SIPConnection & connection,
01158       const SIPURL & referTo,
01159       const SIPURL & referred_by = SIPURL()
01160     );
01161 };
01162 
01163 
01165 
01166 /* This is not a generic NOTIFY PDU, but the minimal one
01167  * that gets sent when receiving a REFER
01168  */
01169 class SIPReferNotify : public SIPTransaction
01170 {
01171     PCLASSINFO(SIPReferNotify, SIPTransaction);
01172   public:
01173     SIPReferNotify(
01174       SIPConnection & connection,
01175       StatusCodes code
01176     );
01177 };
01178 
01179 
01181 
01182 /* This is a MESSAGE PDU, with a body
01183  */
01184 class SIPMessage : public SIPTransaction
01185 {
01186   PCLASSINFO(SIPMessage, SIPTransaction);
01187   public:
01188     struct Params : public SIPParameters
01189     {
01190       Params()
01191       { 
01192         m_expire = 5000;
01193       }
01194 
01195       Params(const Params & param)
01196         : SIPParameters(param)
01197         , m_contentType(param.m_contentType)
01198         , m_id(param.m_id)
01199       { }
01200 
01201       PCaselessString m_contentType;
01202       PString m_id;
01203     };
01204 
01205 
01206   public:
01207     SIPMessage(
01208         SIPEndPoint & ep,
01209         OpalTransport & trans,
01210         const Params & params,
01211         const PString & body
01212     );
01213     SIPURL m_localAddress;
01214 };
01215 
01216 
01218 
01219 /* This is the ACK request sent when receiving a response to an outgoing
01220  * INVITE.
01221  */
01222 class SIPAck : public SIP_PDU
01223 {
01224     PCLASSINFO(SIPAck, SIP_PDU);
01225   public:
01226     SIPAck(
01227       SIPTransaction & invite,
01228       SIP_PDU & response
01229     );
01230 };
01231 
01232 
01234 
01235 /* This is an OPTIONS request
01236  */
01237 class SIPOptions : public SIPTransaction
01238 {
01239     PCLASSINFO(SIPOptions, SIPTransaction);
01240     
01241   public:
01242     SIPOptions(
01243         SIPEndPoint & ep,
01244       OpalTransport & trans,
01245        const SIPURL & address
01246     );
01247 };
01248 
01249 
01251 
01252 /* This is a PING PDU, with a body
01253  */
01254 class SIPPing : public SIPTransaction
01255 {
01256   PCLASSINFO(SIPPing, SIPTransaction);
01257 
01258   public:
01259     SIPPing(
01260       SIPEndPoint & ep,
01261       OpalTransport & trans,
01262       const SIPURL & address,
01263       const PString & body = PString::Empty()
01264     );
01265 };
01266 
01267 
01268 #endif // OPAL_SIP
01269 
01270 #endif // OPAL_SIP_SIPPDU_H
01271 
01272 
01273 // End of File ///////////////////////////////////////////////////////////////

Generated on Wed Dec 15 07:55:09 2010 for OPAL by  doxygen 1.4.7