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