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: 23176 $
00028  * $Author: rjongbloed $
00029  * $Date: 2009-07-29 07:36:35 +0000 (Wed, 29 Jul 2009) $
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 <sip/sdp.h>
00046 #include <opal/rtpconn.h>
00047 
00048  
00049 class OpalTransport;
00050 class OpalTransportAddress;
00051 class OpalProductInfo;
00052 
00053 class SIPEndPoint;
00054 class SIPConnection;
00055 class SIP_PDU;
00056 
00057 
00059 // SIPURL
00060 
00066 class SIPURL : public PURL
00067 {
00068   PCLASSINFO(SIPURL, PURL);
00069   public:
00070     SIPURL();
00071 
00074     SIPURL(
00075       const char * cstr,    
00076       const char * defaultScheme = NULL 
00077     );
00078 
00081     SIPURL(
00082       const PString & str,  
00083       const char * defaultScheme = NULL 
00084     );
00085 
00093     SIPURL(
00094       const PString & name,
00095       const OpalTransportAddress & address,
00096       WORD listenerPort = 0
00097     );
00098 
00099     SIPURL(
00100       const OpalTransportAddress & _address, 
00101       WORD listenerPort = 0
00102     );
00103 
00112     virtual Comparison Compare(
00113       const PObject & obj   
00114     ) const;
00115 
00119     PString AsQuotedString() const;
00120 
00123     PString GetDisplayName(PBoolean useDefault = PTrue) const;
00124     
00125     void SetDisplayName(const PString & str) 
00126       { displayName = str; }
00127 
00130     PString GetFieldParameters() const { return fieldParameters; }
00131 
00134     void SetFieldParameters(const PString & str ) { fieldParameters = str; }
00135 
00138     OpalTransportAddress GetHostAddress() const;
00139 
00140     enum UsageContext {
00141       ExternalURI,  
00142       RequestURI,   
00143       ToURI,        
00144       FromURI,      
00145       ContactURI,   
00146       RouteURI,     
00147       RegisterURI   
00148     };
00149 
00155     void Sanitise(
00156       UsageContext context  
00157     );
00158 
00164     PBoolean AdjustToDNS(
00165       PINDEX entry = 0  
00166     );
00167 
00169     static PString GenerateTag();
00170 
00172     void SetTag(
00173       const PString & tag = GenerateTag()
00174     );
00175 
00176   protected:
00177     void ParseAsAddress(const PString & name, const OpalTransportAddress & _address, WORD listenerPort = 0);
00178 
00197     virtual PBoolean InternalParse(
00198       const char * cstr,
00199       const char * defaultScheme
00200     );
00201 
00202     PString displayName;
00203     PString fieldParameters;
00204 };
00205 
00206 
00208 // SIPMIMEInfo
00209 
00240 class SIPMIMEInfo : public PMIMEInfo
00241 {
00242   PCLASSINFO(SIPMIMEInfo, PMIMEInfo);
00243   public:
00244     SIPMIMEInfo(bool compactForm = false);
00245 
00246     virtual void PrintOn(ostream & strm) const;
00247     virtual void ReadFrom(istream & strm);
00248 
00249     void SetCompactForm(bool form) { compactForm = form; }
00250 
00251     PCaselessString GetContentType(bool includeParameters = false) const;
00252     void SetContentType(const PString & v);
00253 
00254     PCaselessString GetContentEncoding() const;
00255     void SetContentEncoding(const PString & v);
00256 
00257     PString GetFrom() const;
00258     void SetFrom(const PString & v);
00259 
00260     PString GetPAssertedIdentity() const;
00261     void SetPAssertedIdentity(const PString & v);
00262 
00263     PString GetPPreferredIdentity() const;
00264     void SetPPreferredIdentity(const PString & v);
00265 
00266     PString GetAccept() const;
00267     void SetAccept(const PString & v);
00268 
00269     PString GetAcceptEncoding() const;
00270     void SetAcceptEncoding(const PString & v);
00271 
00272     PString GetAcceptLanguage() const;
00273     void SetAcceptLanguage(const PString & v);
00274 
00275     PString GetAllow() const;
00276     void SetAllow(const PString & v);
00277 
00278     PString GetCallID() const;
00279     void SetCallID(const PString & v);
00280 
00281     PString GetContact() const;
00282     bool GetContacts(std::list<SIPURL> & contacts) const;
00283     void SetContact(const PString & v);
00284     void SetContact(const SIPURL & url);
00285 
00286     PString GetSubject() const;
00287     void SetSubject(const PString & v);
00288 
00289     PString GetTo() const;
00290     void SetTo(const PString & v);
00291 
00292     PString GetVia() const;
00293     void SetVia(const PString & v);
00294 
00295     PStringList GetViaList() const;
00296     void SetViaList(const PStringList & v);
00297 
00298     PString GetReferTo() const;
00299     void SetReferTo(const PString & r);
00300 
00301     PString GetReferredBy() const;
00302     void SetReferredBy(const PString & r);
00303 
00304     PINDEX  GetContentLength() const;
00305     void SetContentLength(PINDEX v);
00306     PBoolean IsContentLengthPresent() const;
00307 
00308     PString GetCSeq() const;
00309     void SetCSeq(const PString & v);
00310 
00311     PString GetDate() const;
00312     void SetDate(const PString & v);
00313     void SetDate(const PTime & t);
00314     void SetDate(void); // set to current date
00315 
00316     unsigned GetExpires(unsigned dflt = UINT_MAX) const;// returns default value if not found
00317     void SetExpires(unsigned v);
00318 
00319     PINDEX GetMaxForwards() const;
00320     void SetMaxForwards(PINDEX v);
00321 
00322     PINDEX GetMinExpires() const;
00323     void SetMinExpires(PINDEX v);
00324 
00325     PString GetProxyAuthenticate() const;
00326     void SetProxyAuthenticate(const PString & v);
00327 
00328     PStringList GetRoute() const;
00329     void SetRoute(const PString & v);
00330     void SetRoute(const PStringList & v);
00331 
00332     PStringList GetRecordRoute(bool reversed) const;
00333     void SetRecordRoute(const PStringList & v);
00334 
00335     unsigned GetCSeqIndex() const { return GetCSeq().AsUnsigned(); }
00336 
00337     PString GetSupported() const;
00338     void SetSupported(const PString & v);
00339 
00340     PString GetUnsupported() const;
00341     void SetUnsupported(const PString & v);
00342     
00343     PString GetEvent() const;
00344     void SetEvent(const PString & v);
00345     
00346     PCaselessString GetSubscriptionState() const;
00347     void SetSubscriptionState(const PString & v);
00348     
00349     PString GetUserAgent() const;
00350     void SetUserAgent(const PString & v);
00351 
00352     PString GetOrganization() const;
00353     void SetOrganization(const PString & v);
00354 
00355     void GetProductInfo(OpalProductInfo & info);
00356     void SetProductInfo(const PString & ua, const OpalProductInfo & info);
00357 
00358     PString GetWWWAuthenticate() const;
00359     void SetWWWAuthenticate(const PString & v);
00360 
00361     PString GetSIPIfMatch() const;
00362     void SetSIPIfMatch(const PString & v);
00363 
00364     PString GetSIPETag() const;
00365     void SetSIPETag(const PString & v);
00366 
00367     PString GetRequire() const;
00368     void SetRequire(const PString & v, bool overwrite);
00369 
00370     void GetAlertInfo(PString & info, int & appearance);
00371     void SetAlertInfo(const PString & info, int appearance);
00372 
00375     PString GetFieldParameter(
00376       const PString & fieldName,    
00377       const PString & paramName,    
00378       const PString & defaultValue = PString::Empty()  
00379     ) const { return ExtractFieldParameter((*this)(fieldName), paramName, defaultValue); }
00380 
00385     void SetFieldParameter(
00386       const PString & fieldName,    
00387       const PString & paramName,    
00388       const PString & newValue      
00389     ) { SetAt(fieldName, InsertFieldParameter((*this)(fieldName), paramName, newValue)); }
00390 
00393     static PString ExtractFieldParameter(
00394       const PString & fieldValue,   
00395       const PString & paramName,    
00396       const PString & defaultValue = PString::Empty()  
00397     );
00398 
00403     static PString InsertFieldParameter(
00404       const PString & fieldValue,   
00405       const PString & paramName,    
00406       const PString & newValue      
00407     );
00408 
00409   protected:
00412     PStringList GetRouteList(const char * name, bool reversed) const;
00413 
00417     void SetRouteList(const char * name, const PStringList & v);
00418 
00420     bool compactForm;
00421 };
00422 
00423 
00425 // SIPAuthentication
00426 
00427 class SIPAuthentication : public PObject
00428 {
00429   PCLASSINFO(SIPAuthentication, PObject);
00430   public:
00431     SIPAuthentication();
00432 
00433     virtual Comparison Compare(
00434       const PObject & other
00435     ) const;
00436 
00437     virtual PBoolean Parse(
00438       const PString & auth,
00439       PBoolean proxy
00440     ) = 0;
00441 
00442     virtual PBoolean Authorise(
00443       SIP_PDU & pdu
00444     ) const =  0;
00445 
00446     virtual PBoolean IsProxy() const               { return isProxy; }
00447 
00448     virtual PString GetUsername() const   { return username; }
00449     virtual PString GetPassword() const   { return password; }
00450     virtual PString GetAuthRealm() const  { return PString::Empty(); }
00451 
00452     virtual void SetUsername(const PString & user) { username = user; }
00453     virtual void SetPassword(const PString & pass) { password = pass; }
00454     virtual void SetAuthRealm(const PString &)     { }
00455 
00456     PString GetAuthParam(const PString & auth, const char * name) const;
00457     PString AsHex(PMessageDigest5::Code & digest) const;
00458     PString AsHex(const PBYTEArray & data) const;
00459 
00460     static SIPAuthentication * ParseAuthenticationRequired(bool isProxy,
00461                                                 const PString & line,
00462                                                       PString & errorMsg);
00463 
00464   protected:
00465     PBoolean  isProxy;
00466 
00467     PString   username;
00468     PString   password;
00469 };
00470 
00471 typedef PFactory<SIPAuthentication> SIPAuthenticationFactory;
00472 
00474 
00475 class SIPDigestAuthentication : public SIPAuthentication
00476 {
00477   PCLASSINFO(SIPDigestAuthentication, SIPAuthentication);
00478   public:
00479     SIPDigestAuthentication();
00480 
00481     SIPDigestAuthentication & operator =(
00482       const SIPDigestAuthentication & auth
00483     );
00484 
00485     virtual Comparison Compare(
00486       const PObject & other
00487     ) const;
00488 
00489     virtual PBoolean Parse(
00490       const PString & auth,
00491       PBoolean proxy
00492     );
00493 
00494     virtual PBoolean Authorise(
00495       SIP_PDU & pdu
00496     ) const;
00497 
00498     virtual PString GetAuthRealm() const         { return authRealm; }
00499     virtual void SetAuthRealm(const PString & r) { authRealm = r; }
00500 
00501     enum Algorithm {
00502       Algorithm_MD5,
00503       NumAlgorithms
00504     };
00505     const PString & GetNonce() const       { return nonce; }
00506     Algorithm GetAlgorithm() const         { return algorithm; }
00507     const PString & GetOpaque() const      { return opaque; }
00508 
00509   protected:
00510     PString   authRealm;
00511     PString   nonce;
00512     Algorithm algorithm;
00513     PString   opaque;
00514 
00515     PBoolean qopAuth;
00516     PBoolean qopAuthInt;
00517     PString cnonce;
00518     mutable PAtomicInteger nonceCount;
00519 };
00520 
00522 // SIP_PDU
00523 
00529 class SIP_PDU : public PSafeObject
00530 {
00531   PCLASSINFO(SIP_PDU, PSafeObject);
00532   public:
00533     enum Methods {
00534       Method_INVITE,
00535       Method_ACK,
00536       Method_OPTIONS,
00537       Method_BYE,
00538       Method_CANCEL,
00539       Method_REGISTER,
00540       Method_SUBSCRIBE,
00541       Method_NOTIFY,
00542       Method_REFER,
00543       Method_MESSAGE,
00544       Method_INFO,
00545       Method_PING,
00546       Method_PUBLISH,
00547       NumMethods
00548     };
00549 
00550     enum StatusCodes {
00551       IllegalStatusCode,
00552       Local_TransportError,
00553       Local_BadTransportAddress,
00554       Local_Timeout,
00555 
00556       Information_Trying                  = 100,
00557       Information_Ringing                 = 180,
00558       Information_CallForwarded           = 181,
00559       Information_Queued                  = 182,
00560       Information_Session_Progress        = 183,
00561 
00562       Successful_OK                       = 200,
00563       Successful_Accepted                         = 202,
00564 
00565       Redirection_MultipleChoices         = 300,
00566       Redirection_MovedPermanently        = 301,
00567       Redirection_MovedTemporarily        = 302,
00568       Redirection_UseProxy                = 305,
00569       Redirection_AlternativeService      = 380,
00570 
00571       Failure_BadRequest                  = 400,
00572       Failure_UnAuthorised                = 401,
00573       Failure_PaymentRequired             = 402,
00574       Failure_Forbidden                   = 403,
00575       Failure_NotFound                    = 404,
00576       Failure_MethodNotAllowed            = 405,
00577       Failure_NotAcceptable               = 406,
00578       Failure_ProxyAuthenticationRequired = 407,
00579       Failure_RequestTimeout              = 408,
00580       Failure_Conflict                    = 409,
00581       Failure_Gone                        = 410,
00582       Failure_LengthRequired              = 411,
00583       Failure_RequestEntityTooLarge       = 413,
00584       Failure_RequestURITooLong           = 414,
00585       Failure_UnsupportedMediaType        = 415,
00586       Failure_UnsupportedURIScheme        = 416,
00587       Failure_BadExtension                = 420,
00588       Failure_ExtensionRequired           = 421,
00589       Failure_IntervalTooBrief            = 423,
00590       Failure_TemporarilyUnavailable      = 480,
00591       Failure_TransactionDoesNotExist     = 481,
00592       Failure_LoopDetected                = 482,
00593       Failure_TooManyHops                 = 483,
00594       Failure_AddressIncomplete           = 484,
00595       Failure_Ambiguous                   = 485,
00596       Failure_BusyHere                    = 486,
00597       Failure_RequestTerminated           = 487,
00598       Failure_NotAcceptableHere           = 488,
00599       Failure_BadEvent                    = 489,
00600       Failure_RequestPending              = 491,
00601       Failure_Undecipherable              = 493,
00602 
00603       Failure_InternalServerError         = 500,
00604       Failure_NotImplemented              = 501,
00605       Failure_BadGateway                  = 502,
00606       Failure_ServiceUnavailable          = 503,
00607       Failure_ServerTimeout               = 504,
00608       Failure_SIPVersionNotSupported      = 505,
00609       Failure_MessageTooLarge             = 513,
00610 
00611       GlobalFailure_BusyEverywhere        = 600,
00612       GlobalFailure_Decline               = 603,
00613       GlobalFailure_DoesNotExistAnywhere  = 604,
00614       GlobalFailure_NotAcceptable         = 606,
00615 
00616       MaxStatusCode                       = 699
00617     };
00618 
00619         static const char * GetStatusCodeDescription(int code);
00620     friend ostream & operator<<(ostream & strm, StatusCodes status);
00621 
00622     enum {
00623       MaxSize = 65535
00624     };
00625 
00626     SIP_PDU();
00627 
00630     SIP_PDU(
00631       Methods method,
00632       const SIPURL & dest,
00633       const PString & to,
00634       const PString & from,
00635       const PString & callID,
00636       unsigned cseq,
00637       const OpalTransportAddress & via
00638     );
00641     SIP_PDU(
00642       Methods method,
00643       SIPConnection & connection,
00644       const OpalTransport & transport
00645     );
00646 
00650     SIP_PDU(
00651       const SIP_PDU & request,
00652       StatusCodes code,
00653       const char * contact = NULL,
00654       const char * extra = NULL,
00655       const SDPSessionDescription * sdp = NULL
00656     );
00657     SIP_PDU(const SIP_PDU &);
00658     SIP_PDU & operator=(const SIP_PDU &);
00659     ~SIP_PDU();
00660 
00661     void PrintOn(
00662       ostream & strm
00663     ) const;
00664 
00665     void Construct(
00666       Methods method
00667     );
00668     void Construct(
00669       Methods method,
00670       const SIPURL & dest,
00671       const PString & to,
00672       const PString & from,
00673       const PString & callID,
00674       unsigned cseq,
00675       const OpalTransportAddress & via
00676     );
00677     void Construct(
00678       Methods method,
00679       SIPConnection & connection,
00680       const OpalTransport & transport
00681     );
00682 
00687     bool SetRoute(const PStringList & routeSet);
00688     bool SetRoute(const SIPURL & proxy);
00689 
00692     void SetAllow(unsigned bitmask);
00693 
00696     void AdjustVia(OpalTransport & transport);
00697     
00700     PBoolean Read(
00701       OpalTransport & transport
00702     );
00703 
00706     PBoolean Write(
00707       OpalTransport & transport,
00708       const OpalTransportAddress & remoteAddress = OpalTransportAddress(),
00709       const PString & localInterface = PString::Empty()
00710     );
00711 
00714     bool SendResponse(
00715       OpalTransport & transport,
00716       StatusCodes code,
00717       SIPEndPoint * endpoint = NULL,
00718       const char * contact = NULL,
00719       const char * extra = NULL
00720     );
00721     bool SendResponse(
00722       OpalTransport & transport,
00723       SIP_PDU & response,
00724       SIPEndPoint * endpoint = NULL
00725     );
00726 
00730     PString Build();
00731 
00732     PString GetTransactionID() const;
00733 
00734     Methods GetMethod() const                { return method; }
00735     StatusCodes GetStatusCode () const       { return statusCode; }
00736     const SIPURL & GetURI() const            { return uri; }
00737     unsigned GetVersionMajor() const         { return versionMajor; }
00738     unsigned GetVersionMinor() const         { return versionMinor; }
00739     const PString & GetEntityBody() const    { return entityBody; }
00740           PString & GetEntityBody()          { return entityBody; }
00741     const PString & GetInfo() const          { return info; }
00742     const SIPMIMEInfo & GetMIME() const      { return mime; }
00743           SIPMIMEInfo & GetMIME()            { return mime; }
00744     void SetURI(const SIPURL & newuri)       { uri = newuri; }
00745     SDPSessionDescription * GetSDP();
00746     void SetSDP(SDPSessionDescription * sdp);
00747 
00748   protected:
00749     Methods     method;                 // Request type, ==NumMethods for Response
00750     StatusCodes statusCode;
00751     SIPURL      uri;                    // display name & URI, no tag
00752     unsigned    versionMajor;
00753     unsigned    versionMinor;
00754     PString     info;
00755     SIPMIMEInfo mime;
00756     PString     entityBody;
00757 
00758     SDPSessionDescription * m_SDP;
00759 
00760     mutable PString transactionID;
00761 
00762     bool m_usePeerTransportAddress;
00763 };
00764 
00765 
00766 PQUEUE(SIP_PDU_Queue, SIP_PDU);
00767 
00768 
00769 #if PTRACING
00770 ostream & operator<<(ostream & strm, SIP_PDU::Methods method);
00771 #endif
00772 
00773 
00775 // SIPDialogContext
00776 
00779 class SIPDialogContext
00780 {
00781   public:
00782     SIPDialogContext();
00783 
00784     PString AsString() const;
00785     bool FromString(
00786       const PString & str
00787     );
00788 
00789     const PString & GetCallID() const { return m_callId; }
00790     void SetCallID(const PString & id) { m_callId = id; }
00791 
00792     const SIPURL & GetRequestURI() const { return m_requestURI; }
00793     void SetRequestURI(const SIPURL & url) { m_requestURI = url; }
00794     bool SetRequestURI(const PString & uri) { return m_requestURI.Parse(uri); }
00795 
00796     const PString & GetLocalTag() const { return m_localTag; }
00797     void SetLocalTag(const PString & tag) { m_localTag = tag; }
00798 
00799     const SIPURL & GetLocalURI() const { return m_localURI; }
00800     void SetLocalURI(const SIPURL & url);
00801     bool SetLocalURI(const PString & uri);
00802 
00803     const PString & GetRemoteTag() const { return m_remoteTag; }
00804     void SetRemoteTag(const PString & tag) { m_remoteTag = tag; }
00805 
00806     const SIPURL & GetRemoteURI() const { return m_remoteURI; }
00807     void SetRemoteURI(const SIPURL & url);
00808     bool SetRemoteURI(const PString & uri);
00809 
00810     const PStringList & GetRouteSet() const { return m_routeSet; }
00811     void SetRouteSet(const PStringList & routes) { m_routeSet = routes; }
00812     void UpdateRouteSet(const SIPURL & proxy);
00813 
00814     void Update(const SIP_PDU & response);
00815 
00816     unsigned GetNextCSeq(unsigned inc = 1) { return m_lastSentCSeq += inc; }
00817     bool IsDuplicateCSeq(unsigned sequenceNumber);
00818 
00819     bool IsEstablished() const
00820     {
00821       return !m_callId.IsEmpty() &&
00822              !m_requestURI.IsEmpty() &&
00823              !m_localTag.IsEmpty() &&
00824              !m_remoteTag.IsEmpty();
00825     }
00826 
00827     bool UsePeerTransportAddress() const { return m_usePeerTransportAddress; }
00828 
00829   protected:
00830     PString     m_callId;
00831     SIPURL      m_requestURI;
00832     SIPURL      m_localURI;
00833     PString     m_localTag;
00834     SIPURL      m_remoteURI;
00835     PString     m_remoteTag;
00836     PStringList m_routeSet;
00837     unsigned    m_lastSentCSeq;
00838     unsigned    m_lastReceivedCSeq;
00839     bool        m_usePeerTransportAddress;
00840 };
00841 
00842 
00844 // SIPTransaction
00845 
00856 class SIPTransaction : public SIP_PDU
00857 {
00858     PCLASSINFO(SIPTransaction, SIP_PDU);
00859   public:
00860     SIPTransaction(
00861       SIPEndPoint   & endpoint,
00862       OpalTransport & transport,
00863       const PTimeInterval & minRetryTime = PMaxTimeInterval, 
00864       const PTimeInterval & maxRetryTime = PMaxTimeInterval
00865     );
00869     SIPTransaction(
00870       SIPConnection & connection,
00871       OpalTransport & transport,
00872       Methods method = NumMethods
00873     );
00874     ~SIPTransaction();
00875 
00876     void Construct(
00877       const PTimeInterval & minRetryTime = PMaxTimeInterval,
00878       const PTimeInterval & maxRetryTime = PMaxTimeInterval
00879     );
00880     void Construct(
00881       Methods method, 
00882       SIPDialogContext & dialog
00883     );
00884 
00885     PBoolean Start();
00886     bool IsTrying()     const { return state == Trying; }
00887     bool IsProceeding() const { return state == Proceeding; }
00888     bool IsInProgress() const { return state == Trying || state == Proceeding; }
00889     bool IsFailed()     const { return state > Terminated_Success; }
00890     bool IsCompleted()  const { return state >= Completed; }
00891     bool IsCanceled()   const { return state == Cancelling || state == Terminated_Cancelled || state == Terminated_Aborted; }
00892     bool IsTerminated() const { return state >= Terminated_Success; }
00893 
00894     void WaitForCompletion();
00895     PBoolean Cancel();
00896     void Abort();
00897 
00898     virtual PBoolean OnReceivedResponse(SIP_PDU & response);
00899     virtual PBoolean OnCompleted(SIP_PDU & response);
00900 
00901     OpalTransport & GetTransport() const  { return transport; }
00902     SIPConnection * GetConnection() const { return connection; }
00903     PString         GetInterface() const { return m_localInterface; }
00904 
00905     static PString GenerateCallID();
00906     
00907   protected:
00908     bool SendPDU(SIP_PDU & pdu);
00909     bool ResendCANCEL();
00910 
00911     PDECLARE_NOTIFIER(PTimer, SIPTransaction, OnRetry);
00912     PDECLARE_NOTIFIER(PTimer, SIPTransaction, OnTimeout);
00913 
00914     enum States {
00915       NotStarted,
00916       Trying,
00917       Proceeding,
00918       Cancelling,
00919       Completed,
00920       Terminated_Success,
00921       Terminated_Timeout,
00922       Terminated_RetriesExceeded,
00923       Terminated_TransportError,
00924       Terminated_Cancelled,
00925       Terminated_Aborted,
00926       NumStates
00927     };
00928     virtual void SetTerminated(States newState);
00929 
00930     SIPEndPoint           & endpoint;
00931     OpalTransport         & transport;
00932     PSafePtr<SIPConnection> connection;
00933     PTimeInterval           retryTimeoutMin; 
00934     PTimeInterval           retryTimeoutMax; 
00935 
00936     States     state;
00937     unsigned   retry;
00938     PTimer     retryTimer;
00939     PTimer     completionTimer;
00940     PSyncPoint completed;
00941     PString              m_localInterface;
00942     OpalTransportAddress m_remoteAddress;
00943 };
00944 
00945 
00947 // SIPInvite
00948 
00954 class SIPInvite : public SIPTransaction
00955 {
00956     PCLASSINFO(SIPInvite, SIPTransaction);
00957   public:
00958     SIPInvite(
00959       SIPConnection & connection,
00960       OpalTransport & transport,
00961       const OpalRTPSessionManager & sm
00962     );
00963 
00964     virtual PBoolean OnReceivedResponse(SIP_PDU & response);
00965 
00966     const OpalRTPSessionManager & GetSessionManager() const { return rtpSessions; }
00967           OpalRTPSessionManager & GetSessionManager()       { return rtpSessions; }
00968 
00969   protected:
00970     OpalRTPSessionManager rtpSessions;
00971 };
00972 
00973 
00975 
00976 class SIPRegister : public SIPTransaction
00977 {
00978     PCLASSINFO(SIPRegister, SIPTransaction);
00979   public:
00980     struct Params {
00981       Params();
00982 
00983       PString       m_addressOfRecord;
00984       PString       m_registrarAddress;
00985       PString       m_contactAddress;
00986       PString       m_authID;
00987       PString       m_password;
00988       PString       m_realm;
00989       unsigned      m_expire;
00990       unsigned      m_restoreTime;
00991       PTimeInterval m_minRetryTime;
00992       PTimeInterval m_maxRetryTime;
00993       void          * m_userData;
00994     };
00995 
00996     SIPRegister(
00997       SIPEndPoint   & endpoint,
00998       OpalTransport & transport,
00999       const SIPURL & proxy,
01000       const PString & callId,
01001       unsigned cseq,
01002       const Params & params
01003     );
01004 };
01005 
01006 
01008 
01009 class SIPSubscribe : public SIPTransaction
01010 {
01011     PCLASSINFO(SIPSubscribe, SIPTransaction);
01012   public:
01015     enum PredefinedPackages {
01016       MessageSummary,
01017       Presence,
01018       Dialog,
01019       NumPredefinedPackages,
01020 
01021       PackageMask = 0x7fff,
01022       Watcher     = 0x8000
01023     };
01024 
01025     class EventPackage : public PCaselessString
01026     {
01027       PCLASSINFO(EventPackage, PCaselessString);
01028       public:
01029         EventPackage(unsigned int);
01030         EventPackage(const PString & str);
01031         EventPackage(const char * cstr);
01032         bool operator==(PredefinedPackages) const;
01033         bool operator==(const PString & str) const { return Compare(str) == EqualTo; }
01034         bool operator==(const char * cstr) const { return InternalCompare(0, P_MAX_INDEX, cstr) == EqualTo; }
01035         virtual Comparison InternalCompare(PINDEX offset, PINDEX length, const char * cstr) const;
01036 
01037         bool IsWatcher() const   { return m_isWatcher; }
01038 
01039       protected:
01040         bool m_isWatcher;
01041     };
01042 
01043     struct Params {
01044       Params(unsigned pkg = NumPredefinedPackages);
01045 
01046       EventPackage  m_eventPackage;
01047       PString       m_agentAddress;
01048       PString       m_addressOfRecord;
01049       PString       m_contactAddress;
01050       PString       m_authID;
01051       PString       m_password;
01052       PString       m_realm;
01053       unsigned      m_expire;
01054       unsigned      m_restoreTime;
01055       PTimeInterval m_minRetryTime;
01056       PTimeInterval m_maxRetryTime;
01057       void          * m_userData;
01058       PString       m_from;
01059     };
01060 
01061     SIPSubscribe(
01062         SIPEndPoint & ep,
01063         OpalTransport & trans,
01064         SIPDialogContext & dialog,
01065         const Params & params
01066     );
01067 };
01068 
01069 
01070 typedef SIPSubscribe::EventPackage SIPEventPackage;
01071 
01072 
01074 
01075 class SIPHandler;
01076 
01077 class SIPEventPackageHandler
01078 {
01079 public:
01080   virtual ~SIPEventPackageHandler() { }
01081   virtual PCaselessString GetContentType() const = 0;
01082   virtual bool OnReceivedNOTIFY(SIPHandler & handler, SIP_PDU & request) = 0;
01083   virtual PString OnSendNOTIFY(SIPHandler & /*handler*/, const PObject * /*body*/) { return PString::Empty(); }
01084 };
01085 
01086 
01087 typedef PFactory<SIPEventPackageHandler, SIPEventPackage> SIPEventPackageFactory;
01088 
01089 
01091 
01092 class SIPNotify : public SIPTransaction
01093 {
01094     PCLASSINFO(SIPNotify, SIPTransaction);
01095   public:
01096     SIPNotify(
01097         SIPEndPoint & ep,
01098         OpalTransport & trans,
01099         SIPDialogContext & dialog,
01100         const SIPEventPackage & eventPackage,
01101         const PString & state,
01102         const PString & body
01103     );
01104 };
01105 
01106 
01108 
01109 class SIPPublish : public SIPTransaction
01110 {
01111     PCLASSINFO(SIPPublish, SIPTransaction);
01112   public:
01113     SIPPublish(
01114       SIPEndPoint & ep,
01115       OpalTransport & trans,
01116       const PString & id,
01117       const PString & sipIfMatch,
01118       SIPSubscribe::Params & params,
01119       const PString & body
01120     );
01121 };
01122 
01123 
01125 
01126 class SIPRefer : public SIPTransaction
01127 {
01128   PCLASSINFO(SIPRefer, SIPTransaction);
01129   public:
01130     SIPRefer(
01131       SIPConnection & connection,
01132       OpalTransport & transport,
01133       const SIPURL & refer
01134     );
01135     SIPRefer(
01136       SIPConnection & connection,
01137       OpalTransport & transport,
01138       const SIPURL & refer,
01139       const SIPURL & referred_by
01140     );
01141   protected:
01142     void Construct(
01143       SIPConnection & connection,
01144       OpalTransport & transport,
01145       const SIPURL & refer,
01146       const SIPURL & referred_by
01147     );
01148 };
01149 
01150 
01152 
01153 /* This is not a generic NOTIFY PDU, but the minimal one
01154  * that gets sent when receiving a REFER
01155  */
01156 class SIPReferNotify : public SIPTransaction
01157 {
01158     PCLASSINFO(SIPReferNotify, SIPTransaction);
01159   public:
01160     SIPReferNotify(
01161       SIPConnection & connection,
01162       OpalTransport & transport,
01163       StatusCodes code
01164     );
01165 };
01166 
01167 
01169 
01170 /* This is a MESSAGE PDU, with a body
01171  */
01172 class SIPMessage : public SIPTransaction
01173 {
01174     PCLASSINFO(SIPMessage, SIPTransaction);
01175     
01176   public:
01177     SIPMessage(
01178       SIPEndPoint & ep,
01179       OpalTransport & trans,
01180       const SIPURL & proxy,
01181       const SIPURL & to,
01182       const PString & id,
01183       const PString & body,
01184       SIPURL & m_localAddress
01185     );
01186 };
01187 
01188 
01190 
01191 /* This is the ACK request sent when receiving a response to an outgoing
01192  * INVITE.
01193  */
01194 class SIPAck : public SIP_PDU
01195 {
01196     PCLASSINFO(SIPAck, SIP_PDU);
01197   public:
01198     SIPAck(
01199       SIPTransaction & invite,
01200       SIP_PDU & response
01201     );
01202 };
01203 
01204 
01206 
01207 /* This is an OPTIONS request
01208  */
01209 class SIPOptions : public SIPTransaction
01210 {
01211     PCLASSINFO(SIPOptions, SIPTransaction);
01212     
01213   public:
01214     SIPOptions(
01215         SIPEndPoint & ep,
01216       OpalTransport & trans,
01217        const SIPURL & address
01218     );
01219 };
01220 
01221 
01223 
01224 /* This is a PING PDU, with a body
01225  */
01226 class SIPPing : public SIPTransaction
01227 {
01228   PCLASSINFO(SIPPing, SIPTransaction);
01229 
01230   public:
01231     SIPPing(
01232                SIPEndPoint & ep,
01233              OpalTransport & trans,
01234               const SIPURL & address,
01235               const PString & body = PString::Empty()
01236    );
01237 };
01238 
01239 
01240 #endif // OPAL_SIP
01241 
01242 #endif // OPAL_SIP_SIPPDU_H
01243 
01244 
01245 // End of File ///////////////////////////////////////////////////////////////

Generated on Mon Aug 3 20:50:25 2009 for OPAL by  doxygen 1.5.1