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  * $Log: sippdu.h,v $
00028  * Revision 2.53  2007/10/03 23:59:05  rjongbloed
00029  * Fixed correct operation of DNS SRV lookups to RFC3263 specification,
00030  *   thanks to Will Hawkins and Kris Marsh for what needs to be done.
00031  *
00032  * Revision 2.52  2007/09/21 01:34:09  rjongbloed
00033  * Rewrite of SIP transaction handling to:
00034  *   a) use PSafeObject and safe collections
00035  *   b) only one database of transactions, remove connection copy
00036  *   c) fix timers not always firing due to bogus deadlock avoidance
00037  *   d) cleaning up only occurs in the existing garbage collection thread
00038  *   e) use of read/write mutex on endpoint list to avoid possible deadlock
00039  *
00040  * Revision 2.51  2007/08/24 06:38:17  csoutheren
00041  * Add way to get empty DisplayName without always using default
00042  *
00043  * Revision 2.50  2007/07/02 04:07:58  rjongbloed
00044  * Added hooks to get at PDU strings being read/written.
00045  *
00046  * Revision 2.49  2007/06/29 06:59:56  rjongbloed
00047  * Major improvement to the "product info", normalising H.221 and User-Agent mechanisms.
00048  *
00049  * Revision 2.48  2007/06/10 08:55:11  rjongbloed
00050  * Major rework of how SIP utilises sockets, using new "socket bundling" subsystem.
00051  *
00052  * Revision 2.47  2007/05/15 20:48:32  dsandras
00053  * Added various handlers to manage subscriptions for presence, message
00054  * waiting indications, registrations, state publishing,
00055  * message conversations, ...
00056  * Adds/fixes support for RFC3856, RFC3903, RFC3863, RFC3265, ...
00057  * Many improvements over the original SIPInfo code.
00058  * Code contributed by NOVACOM (http://www.novacom.be) thanks to
00059  * EuroWeb (http://www.euroweb.hu).
00060  *
00061  * Revision 2.46  2007/03/30 14:45:32  hfriederich
00062  * Reorganization of hte way transactions are handled. Delete transactions
00063  *   in garbage collector when they're terminated. Update destructor code
00064  *   to improve safe destruction of SIPEndPoint instances.
00065  *
00066  * Revision 2.45  2006/12/18 03:18:41  csoutheren
00067  * Messy but simple fixes
00068  *   - Add access to SIP REGISTER timeout
00069  *   - Ensure OpalConnection options are correctly progagated
00070  *
00071  * Revision 2.44  2006/09/22 00:58:40  csoutheren
00072  * Fix usages of PAtomicInteger
00073  *
00074  * Revision 2.43  2006/08/12 04:09:24  csoutheren
00075  * Applied 1538497 - Add the PING method
00076  * Thanks to Paul Rolland
00077  *
00078  * Revision 2.42  2006/07/14 07:37:21  csoutheren
00079  * Implement qop authentication.
00080  *
00081  * Revision 2.41  2006/07/14 04:22:43  csoutheren
00082  * Applied 1517397 - More Phobos stability fix
00083  * Thanks to Dinis Rosario
00084  *
00085  * Revision 2.40  2006/07/14 01:15:51  csoutheren
00086  * Add support for "opaque" attribute in SIP authentication
00087  *
00088  * Revision 2.39  2006/07/09 10:18:28  csoutheren
00089  * Applied 1517393 - Opal T.38
00090  * Thanks to Drazen Dimoti
00091  *
00092  * Revision 2.38  2006/06/30 06:59:21  csoutheren
00093  * Applied 1494417 - Add check for ContentLength tag
00094  * Thanks to mturconi
00095  *
00096  * Revision 2.37  2006/05/30 04:58:06  csoutheren
00097  * Added suport for SIP INFO message (untested as yet)
00098  * Fixed some issues with SIP state machine on answering calls
00099  * Fixed some formatting issues
00100  *
00101  * Revision 2.36  2006/01/02 11:28:07  dsandras
00102  * Some documentation. Various code cleanups to prevent duplicate code.
00103  *
00104  * Revision 2.35  2005/12/04 15:02:00  dsandras
00105  * Fixed IP translation in the VIA field of most request PDUs.
00106  *
00107  * Revision 2.34  2005/11/30 13:35:26  csoutheren
00108  * Changed tags for Doxygen
00109  *
00110  * Revision 2.33  2005/11/07 06:34:53  csoutheren
00111  * Changed PMutex to PTimedMutex
00112  *
00113  * Revision 2.32  2005/10/22 17:14:45  dsandras
00114  * Send an OPTIONS request periodically when STUN is being used to maintain the registrations binding alive.
00115  *
00116  * Revision 2.31  2005/09/27 16:06:12  dsandras
00117  * Added function that returns the address to which a request should be sent
00118  * according to the RFC.
00119  * Removed OnCompleted method for SIPInvite, the ACK is now
00120  * sent from the SIPConnection class so that the response has been processed
00121  * for Record Route headers.
00122  * Added class for the ACK request to make the distinction between an ACK sent
00123  * for a 2xx response (in a dialog request) and an ACK sent for a non-2xx response.
00124  *
00125  * Revision 2.30  2005/09/21 19:49:25  dsandras
00126  * Added a function that returns the transport address where to send responses to incoming requests according to RFC3261 and RFC3581.
00127  *
00128  * Revision 2.29  2005/09/20 16:59:32  dsandras
00129  * Added method that adjusts the VIA field of incoming requests accordingly to the SIP RFC and RFC 3581 if the transport address/port do not correspond to what is specified in the Via. Thanks Ted Szoczei for the feedback.
00130  *
00131  * Revision 2.28  2005/08/10 19:34:34  dsandras
00132  * Added helper functions to get and set values of parameters in PDU fields.
00133  *
00134  * Revision 2.27  2005/06/04 12:44:36  dsandras
00135  * Applied patch from Ted Szoczei to fix leaks and problems on cancelling a call and to improve the Allow PDU field handling.
00136  *
00137  * Revision 2.26  2005/05/06 07:37:06  csoutheren
00138  * Various changed while working with SIP carrier
00139  *   - remove assumption that authentication realm is a domain name.
00140  *   - stopped rewrite of "To" field when proxy being used
00141  *   - fix Contact field in REGISTER to match actual port used when Symmetric NATin use
00142  *   - lots of formatting changes and cleanups
00143  *
00144  * Revision 2.25  2005/04/28 20:22:54  dsandras
00145  * Applied big sanity patch for SIP thanks to Ted Szoczei <tszoczei@microtronix.ca>.
00146  * Thanks a lot!
00147  *
00148  * Revision 2.24  2005/04/28 07:59:37  dsandras
00149  * Applied patch from Ted Szoczei to fix problem when answering to PDUs containing
00150  * multiple Via fields in the message header. Thanks!
00151  *
00152  * Revision 2.23  2005/04/11 11:12:38  dsandras
00153  * Added Method_MESSAGE support for future use.
00154  *
00155  * Revision 2.22  2005/04/10 21:18:24  dsandras
00156  * Added support for the SIPMessage PDU.
00157  *
00158  * Revision 2.21  2005/04/10 21:05:14  dsandras
00159  * Added support for SIP Invite using the same RTP Session (call hold).
00160  *
00161  * Revision 2.20  2005/04/10 21:04:08  dsandras
00162  * Added support for Blind Transfer (SIP REFER).
00163  *
00164  * Revision 2.19  2005/03/11 18:12:08  dsandras
00165  * Added support to specify the realm when registering. That way softphones already know what authentication information to use when required. The realm/domain can also be used in the From field.
00166  *
00167  * Revision 2.18  2005/02/19 22:48:48  dsandras
00168  * Added the possibility to register to several registrars and be able to do authenticated calls to each of them. Added SUBSCRIBE/NOTIFY support for Message Waiting Indications.
00169  *
00170  * Revision 2.17  2004/12/12 12:31:03  dsandras
00171  * GetDisplayName now contains more complex code.
00172  *
00173  * Revision 2.16  2004/08/22 12:27:44  rjongbloed
00174  * More work on SIP registration, time to live refresh and deregistration on exit.
00175  *
00176  * Revision 2.15  2004/03/14 10:14:13  rjongbloed
00177  * Changes to REGISTER to support authentication
00178  *
00179  * Revision 2.14  2004/03/14 08:34:09  csoutheren
00180  * Added ability to set User-Agent string
00181  *
00182  * Revision 2.13  2004/03/13 06:32:17  rjongbloed
00183  * Fixes for removal of SIP and H.323 subsystems.
00184  * More registration work.
00185  *
00186  * Revision 2.12  2004/03/09 12:09:55  rjongbloed
00187  * More work on SIP register.
00188  *
00189  * Revision 2.11  2003/12/16 10:22:45  rjongbloed
00190  * Applied enhancements, thank you very much Ted Szoczei
00191  *
00192  * Revision 2.10  2003/12/15 11:56:17  rjongbloed
00193  * Applied numerous bug fixes, thank you very much Ted Szoczei
00194  *
00195  * Revision 2.9  2002/09/16 02:52:35  robertj
00196  * Added #define so can select if #pragma interface/implementation is used on
00197  *   platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan.
00198  *
00199  * Revision 2.8  2002/04/16 07:53:15  robertj
00200  * Changes to support calls through proxies.
00201  *
00202  * Revision 2.7  2002/04/12 12:23:03  robertj
00203  * Allowed for endpoint listener that is not on port 5060.
00204  *
00205  * Revision 2.6  2002/04/10 08:12:17  robertj
00206  * Added call back for when transaction completed, used for invite descendant.
00207  *
00208  * Revision 2.5  2002/04/10 03:16:02  robertj
00209  * Major changes to RTP session management when initiating an INVITE.
00210  * Improvements in error handling and transaction cancelling.
00211  *
00212  * Revision 2.4  2002/04/09 01:02:14  robertj
00213  * Fixed problems with restarting INVITE on  authentication required response.
00214  *
00215  * Revision 2.3  2002/04/05 10:42:04  robertj
00216  * Major changes to support transactions (UDP timeouts and retries).
00217  *
00218  * Revision 2.2  2002/03/08 06:28:19  craigs
00219  * Changed to allow Authorisation to be included in other PDUs
00220  *
00221  * Revision 2.1  2002/02/01 04:53:01  robertj
00222  * Added (very primitive!) SIP support.
00223  *
00224  */
00225 
00226 #ifndef __OPAL_SIPPDU_H
00227 #define __OPAL_SIPPDU_H
00228 
00229 #ifdef P_USE_PRAGMA
00230 #pragma interface
00231 #endif
00232 
00233 
00234 #include <ptclib/mime.h>
00235 #include <ptclib/url.h>
00236 #include <sip/sdp.h>
00237 
00238  
00239 class OpalTransport;
00240 class OpalTransportAddress;
00241 class OpalProductInfo;
00242 
00243 class SIPEndPoint;
00244 class SIPConnection;
00245 class SIP_PDU;
00246 
00247 
00249 // SIPURL
00250 
00256 class SIPURL : public PURL
00257 {
00258   PCLASSINFO(SIPURL, PURL);
00259   public:
00260     SIPURL();
00261 
00264     SIPURL(
00265       const char * cstr,    
00266       const char * defaultScheme = NULL 
00267     );
00268 
00271     SIPURL(
00272       const PString & str,  
00273       const char * defaultScheme = NULL 
00274     );
00275 
00283     SIPURL(
00284       const PString & name,
00285       const OpalTransportAddress & address,
00286       WORD listenerPort = 0
00287     );
00288 
00292     PString AsQuotedString() const;
00293 
00296     PString GetDisplayName(BOOL useDefault = TRUE) const;
00297     
00298     void SetDisplayName(const PString & str) 
00299       { displayName = str; }
00300     
00301     OpalTransportAddress GetHostAddress() const;
00302 
00306     void AdjustForRequestURI();
00307 
00313     BOOL AdjustToDNS(
00314       PINDEX entry = 0  
00315     );
00316 
00317   protected:
00336     virtual BOOL InternalParse(
00337       const char * cstr,
00338       const char * defaultScheme
00339     );
00340 
00341     PString displayName;
00342 };
00343 
00344 
00346 // SIPMIMEInfo
00347 
00378 class SIPMIMEInfo : public PMIMEInfo
00379 {
00380   PCLASSINFO(SIPMIMEInfo, PMIMEInfo);
00381   public:
00382     SIPMIMEInfo(BOOL compactForm = FALSE);
00383 
00384     void SetForm(BOOL v) { compactForm = v; }
00385 
00386     PString GetContentType() const;
00387     void SetContentType(const PString & v);
00388 
00389     PString GetContentEncoding() const;
00390     void SetContentEncoding(const PString & v);
00391 
00392     PString GetFrom() const;
00393     void SetFrom(const PString & v);
00394 
00395     PString GetAccept() const;
00396     void SetAccept(const PString & v);
00397 
00398     PString GetAcceptEncoding() const;
00399     void SetAcceptEncoding(const PString & v);
00400 
00401     PString GetAcceptLanguage() const;
00402     void SetAcceptLanguage(const PString & v);
00403 
00404     PString GetAllow() const;
00405     void SetAllow(const PString & v);
00406 
00407     PString GetCallID() const;
00408     void SetCallID(const PString & v);
00409 
00410     PString GetContact() const;
00411     void SetContact(const PString & v);
00412     void SetContact(const SIPURL & url);
00413 
00414     PString GetSubject() const;
00415     void SetSubject(const PString & v);
00416 
00417     PString GetTo() const;
00418     void SetTo(const PString & v);
00419 
00420     PString GetVia() const;
00421     void SetVia(const PString & v);
00422 
00423     PStringList GetViaList() const;
00424     void SetViaList(const PStringList & v);
00425 
00426     PString GetReferTo() const;
00427     void SetReferTo(const PString & r);
00428 
00429     PString GetReferredBy() const;
00430     void SetReferredBy(const PString & r);
00431 
00432     PINDEX  GetContentLength() const;
00433     void SetContentLength(PINDEX v);
00434                 BOOL IsContentLengthPresent() const;
00435 
00436     PString GetCSeq() const;
00437     void SetCSeq(const PString & v);
00438 
00439     PString GetDate() const;
00440     void SetDate(const PString & v);
00441     void SetDate(const PTime & t);
00442     void SetDate(void); // set to current date
00443 
00444     unsigned GetExpires(unsigned dflt = UINT_MAX) const;// returns default value if not found
00445     void SetExpires(unsigned v);
00446 
00447     PINDEX GetMaxForwards() const;
00448     void SetMaxForwards(PINDEX v);
00449 
00450     PINDEX GetMinExpires() const;
00451     void SetMinExpires(PINDEX v);
00452 
00453     PString GetProxyAuthenticate() const;
00454     void SetProxyAuthenticate(const PString & v);
00455 
00456     PStringList GetRoute() const;
00457     void SetRoute(const PStringList & v);
00458 
00459     PStringList GetRecordRoute() const;
00460     void SetRecordRoute(const PStringList & v);
00461 
00462     unsigned GetCSeqIndex() const { return GetCSeq().AsUnsigned(); }
00463 
00464     PString GetSupported() const;
00465     void SetSupported(const PString & v);
00466 
00467     PString GetUnsupported() const;
00468     void SetUnsupported(const PString & v);
00469     
00470     PString GetEvent() const;
00471     void SetEvent(const PString & v);
00472     
00473     PString GetSubscriptionState() const;
00474     void SetSubscriptionState(const PString & v);
00475     
00476     PString GetUserAgent() const;
00477     void SetUserAgent(const PString & v);
00478 
00479     PString GetOrganization() const;
00480     void SetOrganization(const PString & v);
00481 
00482     void GetProductInfo(OpalProductInfo & info);
00483     void SetProductInfo(const PString & ua, const OpalProductInfo & info);
00484 
00485     PString GetWWWAuthenticate() const;
00486     void SetWWWAuthenticate(const PString & v);
00487 
00488     PString GetSIPIfMatch() const;
00489     void SetSIPIfMatch(const PString & v);
00490 
00491     PString GetSIPETag() const;
00492     void SetSIPETag(const PString & v);
00493 
00496     PString GetFieldParameter(const PString &,
00497                               const PString &);
00498     
00503     void SetFieldParameter(const PString &,
00504                            PString &,
00505                            const PString &);
00506     
00509     BOOL HasFieldParameter(const PString &,
00510                            const PString &);
00511 
00512   protected:
00515     PStringList GetRouteList(const char * name) const;
00516 
00520     void SetRouteList(const char * name, const PStringList & v);
00521 
00524     PString GetFullOrCompact(const char * fullForm, char compactForm) const;
00525 
00527     BOOL compactForm;
00528 };
00529 
00530 
00532 // SIPAuthentication
00533 
00534 class SIPAuthentication : public PObject
00535 {
00536   PCLASSINFO(SIPAuthentication, PObject);
00537   public:
00538     SIPAuthentication(
00539       const PString & username = PString::Empty(),
00540       const PString & password = PString::Empty()
00541     );
00542 
00543     SIPAuthentication & operator =(const SIPAuthentication & auth)
00544     {
00545       isProxy   = auth.isProxy;
00546       authRealm = auth.authRealm;
00547       username  = auth.username;
00548       password  = auth.password;
00549       nonce     = auth.nonce;
00550       algorithm = auth.algorithm;
00551                   opaque    = auth.opaque;
00552               
00553                   qopAuth    = auth.qopAuth;
00554                   qopAuthInt = auth.qopAuthInt;
00555                   cnonce     = auth.cnonce;
00556                   nonceCount.SetValue(auth.nonceCount);
00557 
00558       return *this;
00559     }
00560 
00561     BOOL Parse(
00562       const PCaselessString & auth,
00563       BOOL proxy
00564     );
00565 
00566     BOOL IsValid() const;
00567 
00568     BOOL Authorise(
00569       SIP_PDU & pdu
00570     ) const;
00571 
00572     enum Algorithm {
00573       Algorithm_MD5,
00574       NumAlgorithms
00575     };
00576 
00577     BOOL IsProxy() const                   { return isProxy; }
00578     const PString & GetAuthRealm() const   { return authRealm; }
00579     const PString & GetUsername() const    { return username; }
00580     const PString & GetPassword() const    { return password; }
00581     const PString & GetNonce() const       { return nonce; }
00582     Algorithm GetAlgorithm() const         { return algorithm; }
00583     const PString & GetOpaque() const      { return opaque; }
00584 
00585     void SetUsername(const PString & user) { username = user; }
00586     void SetPassword(const PString & pass) { password = pass; }
00587     void SetAuthRealm(const PString & r)   { authRealm = r; }
00588 
00589   protected:
00590     BOOL      isProxy;
00591     PString   authRealm;
00592     PString   username;
00593     PString   password;
00594     PString   nonce;
00595     Algorithm algorithm;
00596     PString   opaque;
00597 
00598     BOOL qopAuth;
00599     BOOL qopAuthInt;
00600     PString cnonce;
00601     mutable PAtomicInteger nonceCount;
00602 };
00603 
00604 
00606 // SIP_PDU
00607 
00613 class SIP_PDU : public PSafeObject
00614 {
00615   PCLASSINFO(SIP_PDU, PObject);
00616   public:
00617     enum Methods {
00618       Method_INVITE,
00619       Method_ACK,
00620       Method_OPTIONS,
00621       Method_BYE,
00622       Method_CANCEL,
00623       Method_REGISTER,
00624       Method_SUBSCRIBE,
00625       Method_NOTIFY,
00626       Method_REFER,
00627       Method_MESSAGE,
00628       Method_INFO,
00629       Method_PING,
00630       Method_PUBLISH,
00631       NumMethods
00632     };
00633 
00634     enum StatusCodes {
00635       IllegalStatusCode,
00636 
00637       Information_Trying                  = 100,
00638       Information_Ringing                 = 180,
00639       Information_CallForwarded           = 181,
00640       Information_Queued                  = 182,
00641       Information_Session_Progress        = 183,
00642 
00643       Successful_OK                       = 200,
00644       Successful_Accepted                         = 202,
00645 
00646       Redirection_MultipleChoices         = 300,
00647       Redirection_MovedPermanently        = 301,
00648       Redirection_MovedTemporarily        = 302,
00649       Redirection_UseProxy                = 305,
00650       Redirection_AlternativeService      = 380,
00651 
00652       Failure_BadRequest                  = 400,
00653       Failure_UnAuthorised                = 401,
00654       Failure_PaymentRequired             = 402,
00655       Failure_Forbidden                   = 403,
00656       Failure_NotFound                    = 404,
00657       Failure_MethodNotAllowed            = 405,
00658       Failure_NotAcceptable               = 406,
00659       Failure_ProxyAuthenticationRequired = 407,
00660       Failure_RequestTimeout              = 408,
00661       Failure_Conflict                    = 409,
00662       Failure_Gone                        = 410,
00663       Failure_LengthRequired              = 411,
00664       Failure_RequestEntityTooLarge       = 413,
00665       Failure_RequestURITooLong           = 414,
00666       Failure_UnsupportedMediaType        = 415,
00667       Failure_UnsupportedURIScheme        = 416,
00668       Failure_BadExtension                = 420,
00669       Failure_ExtensionRequired           = 421,
00670       Failure_IntervalTooBrief            = 423,
00671       Failure_TemporarilyUnavailable      = 480,
00672       Failure_TransactionDoesNotExist     = 481,
00673       Failure_LoopDetected                = 482,
00674       Failure_TooManyHops                 = 483,
00675       Failure_AddressIncomplete           = 484,
00676       Failure_Ambiguous                   = 485,
00677       Failure_BusyHere                    = 486,
00678       Failure_RequestTerminated           = 487,
00679       Failure_NotAcceptableHere           = 488,
00680       Failure_BadEvent                            = 489,
00681       Failure_RequestPending              = 491,
00682       Failure_Undecipherable              = 493,
00683 
00684       Failure_InternalServerError         = 500,
00685       Failure_NotImplemented              = 501,
00686       Failure_BadGateway                  = 502,
00687       Failure_ServiceUnavailable          = 503,
00688       Failure_ServerTimeout               = 504,
00689       Failure_SIPVersionNotSupported      = 505,
00690       Failure_MessageTooLarge             = 513,
00691 
00692       GlobalFailure_BusyEverywhere        = 600,
00693       GlobalFailure_Decline               = 603,
00694       GlobalFailure_DoesNotExistAnywhere  = 604,
00695       GlobalFailure_NotAcceptable         = 606,
00696 
00697       MaxStatusCode                       = 699
00698     };
00699 
00700         static const char * GetStatusCodeDescription (int code);
00701 
00702     enum {
00703       MaxSize = 65535
00704     };
00705 
00706     SIP_PDU();
00707 
00710     SIP_PDU(
00711       Methods method,
00712       const SIPURL & dest,
00713       const PString & to,
00714       const PString & from,
00715       const PString & callID,
00716       unsigned cseq,
00717       const OpalTransportAddress & via
00718     );
00721     SIP_PDU(
00722       Methods method,
00723       SIPConnection & connection,
00724       const OpalTransport & transport
00725     );
00726 
00730     SIP_PDU(
00731       const SIP_PDU & request,
00732       StatusCodes code,
00733       const char * contact = NULL,
00734       const char * extra = NULL
00735     );
00736     SIP_PDU(const SIP_PDU &);
00737     SIP_PDU & operator=(const SIP_PDU &);
00738     ~SIP_PDU();
00739 
00740     void PrintOn(
00741       ostream & strm
00742     ) const;
00743 
00744     void Construct(
00745       Methods method
00746     );
00747     void Construct(
00748       Methods method,
00749       const SIPURL & dest,
00750       const PString & to,
00751       const PString & from,
00752       const PString & callID,
00753       unsigned cseq,
00754       const OpalTransportAddress & via
00755     );
00756     void Construct(
00757       Methods method,
00758       SIPConnection & connection,
00759       const OpalTransport & transport
00760     );
00761 
00766     BOOL SetRoute(const PStringList & routeSet);
00767 
00770     void SetAllow(void);
00771 
00774     void AdjustVia(OpalTransport & transport);
00775     
00779     OpalTransportAddress GetViaAddress(OpalEndPoint &);
00780     
00784     OpalTransportAddress GetSendAddress(const PStringList & routeSet);
00785     
00788     BOOL Read(
00789       OpalTransport & transport
00790     );
00791 
00794     BOOL Write(
00795       OpalTransport & transport,
00796       const OpalTransportAddress & remoteAddress = OpalTransportAddress()
00797     );
00798 
00802     PString Build();
00803 
00804     PString GetTransactionID() const;
00805 
00806     Methods GetMethod() const                { return method; }
00807     StatusCodes GetStatusCode () const       { return statusCode; }
00808     const SIPURL & GetURI() const            { return uri; }
00809     unsigned GetVersionMajor() const         { return versionMajor; }
00810     unsigned GetVersionMinor() const         { return versionMinor; }
00811     const PString & GetEntityBody() const    { return entityBody; }
00812           PString & GetEntityBody()          { return entityBody; }
00813     const PString & GetInfo() const          { return info; }
00814     const SIPMIMEInfo & GetMIME() const      { return mime; }
00815           SIPMIMEInfo & GetMIME()            { return mime; }
00816     BOOL HasSDP() const                      { return sdp != NULL; }
00817     SDPSessionDescription & GetSDP() const   { return *PAssertNULL(sdp); }
00818     void SetSDP(SDPSessionDescription * s)   { sdp = s; }
00819     void SetSDP(const SDPSessionDescription & s) { sdp = new SDPSessionDescription(s); }
00820 
00821   protected:
00822     
00823     Methods     method;                 // Request type, ==NumMethods for Response
00824     StatusCodes statusCode;
00825     SIPURL      uri;                    // display name & URI, no tag
00826     unsigned    versionMajor;
00827     unsigned    versionMinor;
00828     PString     info;
00829     SIPMIMEInfo mime;
00830     PString     entityBody;
00831 
00832     OpalTransportAddress    lastTransportAddress;
00833     SDPSessionDescription * sdp;
00834 };
00835 
00836 
00837 PQUEUE(SIP_PDU_Queue, SIP_PDU);
00838 
00839 
00841 // SIPTransaction
00842 
00853 class SIPTransaction : public SIP_PDU
00854 {
00855     PCLASSINFO(SIPTransaction, SIP_PDU);
00856   public:
00857     SIPTransaction(
00858       SIPEndPoint   & endpoint,
00859       OpalTransport & transport,
00860       const PTimeInterval & minRetryTime = PMaxTimeInterval, 
00861       const PTimeInterval & maxRetryTime = PMaxTimeInterval
00862     );
00866     SIPTransaction(
00867       SIPConnection & connection,
00868       OpalTransport & transport,
00869       Methods method = NumMethods
00870     );
00871     ~SIPTransaction();
00872 
00873     BOOL Start();
00874     BOOL IsInProgress() const { return state == Trying || state == Proceeding; }
00875     BOOL IsFailed() const { return state > Terminated_Success; }
00876     BOOL IsCompleted() const { return state >= Completed; }
00877     BOOL IsCanceled() const { return state == Terminated_Cancelled; }
00878     BOOL IsTerminated() const { return state >= Terminated_Success; }
00879     void WaitForCompletion();
00880     BOOL Cancel();
00881     void Abort();
00882 
00883     virtual BOOL OnReceivedResponse(SIP_PDU & response);
00884     virtual BOOL OnCompleted(SIP_PDU & response);
00885 
00886     OpalTransport & GetTransport() const  { return transport; }
00887     SIPConnection * GetConnection() const { return connection; }
00888 
00889     const OpalTransportAddress & GetLocalAddress() const { return localAddress; }
00890 
00891   protected:
00892     void Construct(
00893       const PTimeInterval & minRetryTime = PMaxTimeInterval,
00894       const PTimeInterval & maxRetryTime = PMaxTimeInterval
00895     );
00896     BOOL ResendCANCEL();
00897 
00898     PDECLARE_NOTIFIER(PTimer, SIPTransaction, OnRetry);
00899     PDECLARE_NOTIFIER(PTimer, SIPTransaction, OnTimeout);
00900 
00901     enum States {
00902       NotStarted,
00903       Trying,
00904       Aborting,
00905       Proceeding,
00906       Cancelling,
00907       Completed,
00908       Terminated_Success,
00909       Terminated_Timeout,
00910       Terminated_RetriesExceeded,
00911       Terminated_TransportError,
00912       Terminated_Cancelled,
00913       Terminated_Aborted,
00914       NumStates
00915     };
00916     virtual void SetTerminated(States newState);
00917 
00918     SIPEndPoint   & endpoint;
00919     OpalTransport & transport;
00920     PSafePtr<SIPConnection> connection;
00921 
00922     States   state;
00923     unsigned retry;
00924     PTimer   retryTimer;
00925     PTimer   completionTimer;
00926 
00927     PSyncPoint completed;
00928 
00929     PTimeInterval retryTimeoutMin; 
00930     PTimeInterval retryTimeoutMax; 
00931 
00932     OpalTransportAddress localAddress;
00933 };
00934 
00935 
00937 // SIPInvite
00938 
00944 class SIPInvite : public SIPTransaction
00945 {
00946     PCLASSINFO(SIPInvite, SIPTransaction);
00947   public:
00948     SIPInvite(
00949       SIPConnection & connection,
00950       OpalTransport & transport
00951     );
00952     SIPInvite(
00953       SIPConnection & connection,
00954       OpalTransport & transport,
00955       RTP_SessionManager & sm
00956     );
00957     SIPInvite(
00958       SIPConnection & connection,
00959       OpalTransport & transport,
00960       unsigned rtpSessionId
00961     );
00962 
00963     virtual BOOL OnReceivedResponse(SIP_PDU & response);
00964 
00965     RTP_SessionManager & GetSessionManager() { return rtpSessions; }
00966 
00967   protected:
00968     RTP_SessionManager rtpSessions;
00969 };
00970 
00971 
00973 
00974 class SIPRegister : public SIPTransaction
00975 {
00976     PCLASSINFO(SIPRegister, SIPTransaction);
00977   public:
00978     SIPRegister(
00979       SIPEndPoint   & endpoint,
00980       OpalTransport & transport,
00981       const PStringList & routeSet,
00982       const SIPURL & address,
00983       const PString & id,
00984       unsigned expires,
00985       const PTimeInterval & minRetryTime = PMaxTimeInterval,
00986       const PTimeInterval & maxRetryTime = PMaxTimeInterval
00987     );
00988 };
00989 
00990 
00992 
00993 class SIPSubscribe : public SIPTransaction
00994 {
00995     PCLASSINFO(SIPSubscribe, SIPTransaction);
00996   public:
00999     enum SubscribeType {
01000       Unknown,
01001       MessageSummary,
01002       Presence
01003     };
01004 
01007     enum MWIType { 
01008       
01009       VoiceMessage, 
01010       FaxMessage, 
01011       PagerMessage, 
01012       MultimediaMessage, 
01013       TextMessage, 
01014       None 
01015     };
01016     SIPSubscribe(
01017         SIPEndPoint & ep,
01018         OpalTransport & trans,
01019         SIPSubscribe::SubscribeType & type,
01020         const PStringList & routeSet,
01021         const SIPURL & targetAddress,
01022         const PString & remotePartyAddress,
01023         const PString & localPartyAddress,
01024         const PString & id,
01025         const unsigned & cseq,
01026         unsigned expires
01027     );
01028 };
01029 
01030 
01032 
01033 class SIPPublish : public SIPTransaction
01034 {
01035     PCLASSINFO(SIPPublish, SIPTransaction);
01036   public:
01037     SIPPublish(
01038       SIPEndPoint & ep,
01039       OpalTransport & trans,
01040       const PStringList & routeSet,
01041       const SIPURL & targetAddress,
01042       const PString & sipIfMatch,
01043       const PString & body,
01044       unsigned expires
01045     );
01046 };
01047 
01048 
01050 
01051 class SIPRefer : public SIPTransaction
01052 {
01053   PCLASSINFO(SIPRefer, SIPTransaction);
01054   public:
01055     SIPRefer(
01056       SIPConnection & connection,
01057       OpalTransport & transport,
01058       const PString & refer
01059     );
01060     SIPRefer(
01061       SIPConnection & connection,
01062       OpalTransport & transport,
01063       const PString & refer,
01064       const PString & referred_by
01065     );
01066   protected:
01067     void Construct(
01068       SIPConnection & connection,
01069       OpalTransport & transport,
01070       const PString & refer,
01071       const PString & referred_by = PString::Empty()
01072     );
01073 };
01074 
01075 
01077 
01078 /* This is not a generic NOTIFY PDU, but the minimal one
01079  * that gets sent when receiving a REFER
01080  */
01081 class SIPReferNotify : public SIPTransaction
01082 {
01083     PCLASSINFO(SIPReferNotify, SIPTransaction);
01084   public:
01085     SIPReferNotify(
01086       SIPConnection & connection,
01087       OpalTransport & transport,
01088       StatusCodes code
01089     );
01090 };
01091 
01092 
01094 
01095 /* This is a MESSAGE PDU, with a body
01096  */
01097 class SIPMessage : public SIPTransaction
01098 {
01099     PCLASSINFO(SIPMessage, SIPTransaction);
01100     
01101   public:
01102     SIPMessage(
01103                SIPEndPoint & ep,
01104                OpalTransport & trans,
01105                const SIPURL & to,
01106                const PStringList & routeSet,
01107                const PString & body
01108     );
01109 };
01110 
01111 
01113 
01114 /* This is the ACK request sent when receiving a response to an outgoing
01115  * INVITE.
01116  */
01117 class SIPAck : public SIP_PDU
01118 {
01119     PCLASSINFO(SIPAck, SIP_PDU);
01120   public:
01121     // This ACK is sent for non-2xx responses
01122     SIPAck(
01123       SIPEndPoint & ep,
01124       SIPTransaction & invite,
01125       SIP_PDU & response); 
01126 
01127     // This ACK is sent for 2xx responses according to 17.1.1.3
01128     SIPAck(
01129       SIPTransaction & invite);
01130 
01131   protected:
01132     void Construct();
01133 
01134     SIPTransaction & transaction;
01135 };
01136 
01137 
01139 
01140 /* This is an OPTIONS request
01141  */
01142 class SIPOptions : public SIPTransaction
01143 {
01144     PCLASSINFO(SIPOptions, SIPTransaction);
01145     
01146   public:
01147     SIPOptions(
01148         SIPEndPoint & ep,
01149       OpalTransport & trans,
01150        const SIPURL & address
01151     );
01152 };
01153 
01154 
01156 
01157 /* This is a PING PDU, with a body
01158  */
01159 class SIPPing : public SIPTransaction
01160 {
01161   PCLASSINFO(SIPPing, SIPTransaction);
01162 
01163   public:
01164     SIPPing(
01165                SIPEndPoint & ep,
01166              OpalTransport & trans,
01167               const SIPURL & address,
01168               const PString & body = PString::Empty()
01169    );
01170 };
01171 
01172 
01173 #endif // __OPAL_SIPPDU_H
01174 
01175 
01176 // End of File ///////////////////////////////////////////////////////////////

Generated on Fri Mar 7 06:33:41 2008 for OPAL by  doxygen 1.5.1