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: 24609 $
00028  * $Author: rjongbloed $
00029  * $Date: 2010-07-29 02:18:34 -0500 (Thu, 29 Jul 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();
00738     void IncrementCSeq(unsigned inc) { m_lastSentCSeq += inc; }
00739 
00740     bool IsDuplicateCSeq(unsigned sequenceNumber);
00741 
00742     bool IsEstablished() const
00743     {
00744       return !m_callId.IsEmpty() &&
00745              !m_requestURI.IsEmpty() &&
00746              !m_localTag.IsEmpty() &&
00747              !m_remoteTag.IsEmpty();
00748     }
00749 
00750     bool UsePeerTransportAddress() const { return m_usePeerTransportAddress; }
00751 
00752     void SetForking(bool f) { m_forking = f; }
00753 
00754   protected:
00755     PString     m_callId;
00756     SIPURL      m_requestURI;
00757     SIPURL      m_localURI;
00758     PString     m_localTag;
00759     SIPURL      m_remoteURI;
00760     PString     m_remoteTag;
00761     PStringList m_routeSet;
00762     unsigned    m_lastSentCSeq;
00763     unsigned    m_lastReceivedCSeq;
00764     bool        m_usePeerTransportAddress;
00765     bool        m_forking;
00766     SIPURL      m_proxy;
00767 };
00768 
00769 
00771 
00772 struct SIPParameters
00773 {
00774   SIPParameters(
00775     const PString & aor = PString::Empty(),
00776     const PString & remote = PString::Empty()
00777   );
00778 
00779   void Normalise(
00780     const PString & defaultUser,
00781     const PTimeInterval & defaultExpire
00782   );
00783 
00784   PCaselessString m_remoteAddress;
00785   PCaselessString m_localAddress;
00786   PCaselessString m_proxyAddress;
00787   PCaselessString m_addressOfRecord;
00788   PCaselessString m_contactAddress;
00789   PString         m_authID;
00790   PString         m_password;
00791   PString         m_realm;
00792   unsigned        m_expire;
00793   unsigned        m_restoreTime;
00794   PTimeInterval   m_minRetryTime;
00795   PTimeInterval   m_maxRetryTime;
00796   void          * m_userData;
00797 };
00798 
00799 
00800 #if PTRACING
00801 ostream & operator<<(ostream & strm, const SIPParameters & params);
00802 #endif
00803 
00804 
00806 // SIPTransaction
00807 
00818 class SIPTransaction : public SIP_PDU
00819 {
00820     PCLASSINFO(SIPTransaction, SIP_PDU);
00821   public:
00822     SIPTransaction(
00823       Methods method,
00824       SIPEndPoint   & endpoint,
00825       OpalTransport & transport
00826     );
00830     SIPTransaction(
00831       Methods method,
00832       SIPConnection & connection
00833     );
00834     ~SIPTransaction();
00835 
00836     PBoolean Start();
00837     bool IsTrying()     const { return m_state == Trying; }
00838     bool IsProceeding() const { return m_state == Proceeding; }
00839     bool IsInProgress() const { return m_state == Trying || m_state == Proceeding; }
00840     bool IsFailed()     const { return m_state > Terminated_Success; }
00841     bool IsCompleted()  const { return m_state >= Completed; }
00842     bool IsCanceled()   const { return m_state == Cancelling || m_state == Terminated_Cancelled || m_state == Terminated_Aborted; }
00843     bool IsTerminated() const { return m_state >= Terminated_Success; }
00844 
00845     void WaitForTermination();
00846     PBoolean Cancel();
00847     void Abort();
00848 
00849     virtual PBoolean OnReceivedResponse(SIP_PDU & response);
00850     virtual PBoolean OnCompleted(SIP_PDU & response);
00851 
00852     OpalTransport & GetTransport()  const { return m_transport; }
00853     SIPConnection * GetConnection() const { return m_connection; }
00854     PString         GetInterface()  const { return m_localInterface; }
00855 
00856     static PString GenerateCallID();
00857 
00858   protected:
00859     bool SendPDU(SIP_PDU & pdu);
00860     bool ResendCANCEL();
00861     void SetParameters(const SIPParameters & params);
00862     void SetContact(const SIPURL & uri);
00863 
00864     PDECLARE_NOTIFIER(PTimer, SIPTransaction, OnRetry);
00865     PDECLARE_NOTIFIER(PTimer, SIPTransaction, OnTimeout);
00866 
00867     enum States {
00868       NotStarted,
00869       Trying,
00870       Proceeding,
00871       Cancelling,
00872       Completed,
00873       Terminated_Success,
00874       Terminated_Timeout,
00875       Terminated_RetriesExceeded,
00876       Terminated_TransportError,
00877       Terminated_Cancelled,
00878       Terminated_Aborted,
00879       NumStates
00880     };
00881     virtual void SetTerminated(States newState);
00882 
00883     SIPEndPoint           & m_endpoint;
00884     OpalTransport         & m_transport;
00885     PSafePtr<SIPConnection> m_connection;
00886     PTimeInterval           m_retryTimeoutMin; 
00887     PTimeInterval           m_retryTimeoutMax; 
00888 
00889     States     m_state;
00890     unsigned   m_retry;
00891     PTimer     m_retryTimer;
00892     PTimer     m_completionTimer;
00893     PSyncPoint m_terminated;
00894 
00895     PString              m_localInterface;
00896     OpalTransportAddress m_remoteAddress;
00897 };
00898 
00899 
00900 #define OPAL_PROXY_PARAM    "OPAL-proxy"
00901 #define OPAL_LOCAL_ID_PARAM "OPAL-local-id"
00902 
00903 
00905 // SIPInvite
00906 
00912 class SIPInvite : public SIPTransaction
00913 {
00914     PCLASSINFO(SIPInvite, SIPTransaction);
00915   public:
00916     SIPInvite(
00917       SIPConnection & connection,
00918       const OpalRTPSessionManager & sm
00919     );
00920 
00921     virtual PBoolean OnReceivedResponse(SIP_PDU & response);
00922 
00923     const OpalRTPSessionManager & GetSessionManager() const { return m_rtpSessions; }
00924           OpalRTPSessionManager & GetSessionManager()       { return m_rtpSessions; }
00925 
00926   protected:
00927     OpalRTPSessionManager m_rtpSessions;
00928 };
00929 
00930 
00932 
00933 class SIPRegister : public SIPTransaction
00934 {
00935     PCLASSINFO(SIPRegister, SIPTransaction);
00936   public:
00937     enum CompatibilityModes {
00938       e_FullyCompliant,                 
00941       e_CannotRegisterMultipleContacts, 
00945       e_CannotRegisterPrivateContacts   
00949     };
00950 
00952     struct Params : public SIPParameters {
00953       Params()
00954         : m_registrarAddress(m_remoteAddress)
00955         , m_compatibility(SIPRegister::e_FullyCompliant)
00956       { }
00957 
00958       Params(const Params & param)
00959         : SIPParameters(param)
00960         , m_registrarAddress(m_remoteAddress)
00961         , m_compatibility(param.m_compatibility)
00962       { }
00963 
00964       PCaselessString  & m_registrarAddress; // For backward compatibility
00965       CompatibilityModes m_compatibility;
00966     };
00967 
00968     SIPRegister(
00969       SIPEndPoint   & endpoint,
00970       OpalTransport & transport,
00971       const PString & callId,
00972       unsigned cseq,
00973       const Params & params
00974     );
00975 };
00976 
00977 
00978 #if PTRACING
00979 ostream & operator<<(ostream & strm, SIPRegister::CompatibilityModes mode);
00980 ostream & operator<<(ostream & strm, const SIPRegister::Params & params);
00981 #endif
00982 
00983 
00985 
00986 class SIPSubscribe : public SIPTransaction
00987 {
00988     PCLASSINFO(SIPSubscribe, SIPTransaction);
00989   public:
00992     enum PredefinedPackages {
00993       MessageSummary,
00994       Presence,
00995       Dialog,
00996 
00997       NumPredefinedPackages,
00998 
00999       Watcher = 0x8000,
01000 
01001       MessageSummaryWatcher = Watcher|MessageSummary,
01002       PresenceWatcher       = Watcher|Presence,
01003       DialogWatcher         = Watcher|Dialog,
01004 
01005       PackageMask = Watcher-1
01006     };
01007     friend PredefinedPackages operator|(PredefinedPackages p1, PredefinedPackages p2) { return (PredefinedPackages)((int)p1|(int)p2); }
01008 
01009     class EventPackage : public PCaselessString
01010     {
01011       PCLASSINFO(EventPackage, PCaselessString);
01012       public:
01013         EventPackage(PredefinedPackages = NumPredefinedPackages);
01014         explicit EventPackage(const PString & str) : PCaselessString(str) { }
01015         explicit EventPackage(const char   *  str) : PCaselessString(str) { }
01016 
01017         EventPackage & operator=(PredefinedPackages pkg);
01018         EventPackage & operator=(const PString & str) { PCaselessString::operator=(str); return *this; }
01019         EventPackage & operator=(const char   *  str) { PCaselessString::operator=(str); return *this; }
01020 
01021         bool operator==(PredefinedPackages pkg) const { return Compare(EventPackage(pkg)) == EqualTo; }
01022         bool operator==(const PString & str) const { return Compare(str) == EqualTo; }
01023         bool operator==(const char * cstr) const { return InternalCompare(0, P_MAX_INDEX, cstr) == EqualTo; }
01024         virtual Comparison InternalCompare(PINDEX offset, PINDEX length, const char * cstr) const;
01025 
01026         bool IsWatcher() const;
01027     };
01028 
01030     struct SubscriptionStatus {
01031       SIPSubscribeHandler * m_handler;           
01032       PString               m_addressofRecord;   
01033       bool                  m_wasSubscribing;    
01034       bool                  m_reSubscribing;     
01035       SIP_PDU::StatusCodes  m_reason;            
01036       OpalProductInfo       m_productInfo;       
01037       void                * m_userData;          
01038     };
01039 
01040     struct NotifyCallbackInfo {
01041       NotifyCallbackInfo(
01042         SIPEndPoint & ep,
01043         OpalTransport & trans,
01044         SIP_PDU & notify,
01045         SIP_PDU & response
01046       );
01047 
01048       bool SendResponse(
01049         SIP_PDU::StatusCodes status,
01050         const char * extra = NULL
01051       );
01052 
01053       SIPEndPoint   & m_endpoint;
01054       OpalTransport & m_transport;
01055       SIP_PDU       & m_notify;
01056       SIP_PDU       & m_response;
01057       bool            m_sendResponse;
01058     };
01059 
01060     struct Params : public SIPParameters
01061     {
01062       Params(PredefinedPackages pkg = NumPredefinedPackages)
01063         : m_agentAddress(m_remoteAddress)
01064         , m_eventPackage(pkg)
01065         , m_eventList(false)
01066       { }
01067 
01068       Params(const Params & param)
01069         : SIPParameters(param)
01070         , m_agentAddress(m_remoteAddress)
01071         , m_eventPackage(param.m_eventPackage)
01072         , m_eventList(param.m_eventList)
01073         , m_contentType(param.m_contentType)
01074         , m_onSubcribeStatus(param.m_onSubcribeStatus)
01075         , m_onNotify(param.m_onNotify)
01076       { }
01077 
01078       PCaselessString & m_agentAddress; // For backward compatibility
01079       EventPackage      m_eventPackage;
01080       bool              m_eventList;    // Enable RFC4662
01081       PCaselessString   m_contentType;  // May be \n separated list of types
01082 
01083       PNotifierTemplate<const SubscriptionStatus &> m_onSubcribeStatus;
01084       PNotifierTemplate<NotifyCallbackInfo &> m_onNotify;
01085     };
01086 
01087     SIPSubscribe(
01088         SIPEndPoint & ep,
01089         OpalTransport & trans,
01090         SIPDialogContext & dialog,
01091         const Params & params
01092     );
01093 };
01094 
01095 
01096 #if PTRACING
01097 ostream & operator<<(ostream & strm, const SIPSubscribe::Params & params);
01098 #endif
01099 
01100 
01101 typedef SIPSubscribe::EventPackage SIPEventPackage;
01102 
01103 
01105 
01106 class SIPHandler;
01107 
01108 class SIPEventPackageHandler
01109 {
01110 public:
01111   virtual ~SIPEventPackageHandler() { }
01112   virtual PCaselessString GetContentType() const = 0;
01113   virtual bool OnReceivedNOTIFY(SIPHandler & handler, SIP_PDU & request) = 0;
01114   virtual PString OnSendNOTIFY(SIPHandler & /*handler*/, const PObject * /*body*/) { return PString::Empty(); }
01115 };
01116 
01117 
01118 typedef PFactory<SIPEventPackageHandler, SIPEventPackage> SIPEventPackageFactory;
01119 
01120 
01122 
01123 class SIPNotify : public SIPTransaction
01124 {
01125     PCLASSINFO(SIPNotify, SIPTransaction);
01126   public:
01127     SIPNotify(
01128         SIPEndPoint & ep,
01129         OpalTransport & trans,
01130         SIPDialogContext & dialog,
01131         const SIPEventPackage & eventPackage,
01132         const PString & state,
01133         const PString & body
01134     );
01135 };
01136 
01137 
01139 
01140 class SIPPublish : public SIPTransaction
01141 {
01142     PCLASSINFO(SIPPublish, SIPTransaction);
01143   public:
01144     SIPPublish(
01145       SIPEndPoint & ep,
01146       OpalTransport & trans,
01147       const PString & id,
01148       const PString & sipIfMatch,
01149       const SIPSubscribe::Params & params,
01150       const PString & body
01151     );
01152 };
01153 
01154 
01156 
01157 class SIPRefer : public SIPTransaction
01158 {
01159   PCLASSINFO(SIPRefer, SIPTransaction);
01160   public:
01161     SIPRefer(
01162       SIPConnection & connection,
01163       const SIPURL & referTo,
01164       const SIPURL & referred_by = SIPURL()
01165     );
01166 };
01167 
01168 
01170 
01171 /* This is not a generic NOTIFY PDU, but the minimal one
01172  * that gets sent when receiving a REFER
01173  */
01174 class SIPReferNotify : public SIPTransaction
01175 {
01176     PCLASSINFO(SIPReferNotify, SIPTransaction);
01177   public:
01178     SIPReferNotify(
01179       SIPConnection & connection,
01180       StatusCodes code
01181     );
01182 };
01183 
01184 
01186 
01187 /* This is a MESSAGE PDU, with a body
01188  */
01189 class SIPMessage : public SIPTransaction
01190 {
01191   PCLASSINFO(SIPMessage, SIPTransaction);
01192   public:
01193     struct Params : public SIPParameters
01194     {
01195       Params()
01196       { 
01197         m_expire = 5000;
01198       }
01199 
01200       Params(const Params & param)
01201         : SIPParameters(param)
01202         , m_contentType(param.m_contentType)
01203         , m_id(param.m_id)
01204       { }
01205 
01206       PCaselessString m_contentType;
01207       PString m_id;
01208     };
01209 
01210 
01211   public:
01212     SIPMessage(
01213         SIPEndPoint & ep,
01214         OpalTransport & trans,
01215         const Params & params,
01216         const PString & body
01217     );
01218     SIPURL m_localAddress;
01219 };
01220 
01221 
01223 
01224 /* This is the ACK request sent when receiving a response to an outgoing
01225  * INVITE.
01226  */
01227 class SIPAck : public SIP_PDU
01228 {
01229     PCLASSINFO(SIPAck, SIP_PDU);
01230   public:
01231     SIPAck(
01232       SIPTransaction & invite,
01233       SIP_PDU & response
01234     );
01235 };
01236 
01237 
01239 
01240 /* This is an OPTIONS request
01241  */
01242 class SIPOptions : public SIPTransaction
01243 {
01244     PCLASSINFO(SIPOptions, SIPTransaction);
01245     
01246   public:
01247     SIPOptions(
01248         SIPEndPoint & ep,
01249       OpalTransport & trans,
01250        const SIPURL & address
01251     );
01252 };
01253 
01254 
01256 
01257 /* This is a PING PDU, with a body
01258  */
01259 class SIPPing : public SIPTransaction
01260 {
01261   PCLASSINFO(SIPPing, SIPTransaction);
01262 
01263   public:
01264     SIPPing(
01265       SIPEndPoint & ep,
01266       OpalTransport & trans,
01267       const SIPURL & address,
01268       const PString & body = PString::Empty()
01269     );
01270 };
01271 
01272 
01273 #endif // OPAL_SIP
01274 
01275 #endif // OPAL_SIP_SIPPDU_H
01276 
01277 
01278 // End of File ///////////////////////////////////////////////////////////////

Generated on Mon Feb 21 20:19:21 2011 for OPAL by  doxygen 1.4.7