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

Generated on Sun Nov 21 20:20:51 2010 for OPAL by  doxygen 1.4.7