00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef OPAL_SIP_SIPPDU_H
00033 #define OPAL_SIP_SIPPDU_H
00034
00035 #ifdef P_USE_PRAGMA
00036 #pragma interface
00037 #endif
00038
00039 #include <opal/buildopts.h>
00040
00041 #if OPAL_SIP
00042
00043 #include <ptclib/mime.h>
00044 #include <ptclib/url.h>
00045 #include <ptclib/http.h>
00046 #include <sip/sdp.h>
00047 #include <opal/rtpconn.h>
00048
00049
00050 class OpalTransport;
00051 class OpalTransportAddress;
00052 class OpalProductInfo;
00053
00054 class SIPEndPoint;
00055 class SIPConnection;
00056 class SIP_PDU;
00057 class SIPSubscribeHandler;
00058 class SIPDialogContext;
00059
00060
00062
00063
00069 class SIPURL : public PURL
00070 {
00071 PCLASSINFO(SIPURL, PURL);
00072 public:
00073 SIPURL();
00074
00077 SIPURL(
00078 const char * cstr,
00079 const char * defaultScheme = NULL
00080 );
00081
00084 SIPURL(
00085 const PString & str,
00086 const char * defaultScheme = NULL
00087 );
00088
00096 SIPURL(
00097 const PString & name,
00098 const OpalTransportAddress & address,
00099 WORD listenerPort = 0
00100 );
00101
00102 SIPURL(
00103 const OpalTransportAddress & _address,
00104 WORD listenerPort = 0
00105 );
00106
00115 virtual Comparison Compare(
00116 const PObject & obj
00117 ) const;
00118
00122 PString AsQuotedString() const;
00123
00126 PString GetDisplayName(PBoolean useDefault = PTrue) const;
00127
00128 void SetDisplayName(const PString & str)
00129 { displayName = str; }
00130
00133 PString GetFieldParameters() const { return fieldParameters; }
00134
00137 void SetFieldParameters(const PString & str ) { fieldParameters = str; }
00138
00141 OpalTransportAddress GetHostAddress() const;
00142
00143 enum UsageContext {
00144 ExternalURI,
00145 RequestURI,
00146 ToURI,
00147 FromURI,
00148 ContactURI,
00149 RouteURI,
00150 RegisterURI
00151 };
00152
00158 void Sanitise(
00159 UsageContext context
00160 );
00161
00167 PBoolean AdjustToDNS(
00168 PINDEX entry = 0
00169 );
00170
00172 static PString GenerateTag();
00173
00175 void SetTag(
00176 const PString & tag = GenerateTag()
00177 );
00178
00179 protected:
00180 void ParseAsAddress(const PString & name, const OpalTransportAddress & _address, WORD listenerPort = 0);
00181
00200 virtual PBoolean InternalParse(
00201 const char * cstr,
00202 const char * defaultScheme
00203 );
00204
00205 PString displayName;
00206 PString fieldParameters;
00207 };
00208
00209
00211
00212
00243 class SIPMIMEInfo : public PMIMEInfo
00244 {
00245 PCLASSINFO(SIPMIMEInfo, PMIMEInfo);
00246 public:
00247 SIPMIMEInfo(bool compactForm = false);
00248
00249 virtual void PrintOn(ostream & strm) const;
00250 virtual void ReadFrom(istream & strm);
00251
00252 void SetCompactForm(bool form) { compactForm = form; }
00253
00254 PCaselessString GetContentType(bool includeParameters = false) const;
00255 void SetContentType(const PString & v);
00256
00257 PCaselessString GetContentEncoding() const;
00258 void SetContentEncoding(const PString & v);
00259
00260 PString GetFrom() const;
00261 void SetFrom(const PString & v);
00262
00263 PString GetPAssertedIdentity() const;
00264 void SetPAssertedIdentity(const PString & v);
00265
00266 PString GetPPreferredIdentity() const;
00267 void SetPPreferredIdentity(const PString & v);
00268
00269 PString GetAccept() const;
00270 void SetAccept(const PString & v);
00271
00272 PString GetAcceptEncoding() const;
00273 void SetAcceptEncoding(const PString & v);
00274
00275 PString GetAcceptLanguage() const;
00276 void SetAcceptLanguage(const PString & v);
00277
00278 PString GetAllow() const;
00279 void SetAllow(const PString & v);
00280
00281 PString GetCallID() const;
00282 void SetCallID(const PString & v);
00283
00284 PString GetContact() const;
00285 bool GetContacts(std::set<SIPURL> & contacts) const;
00286 void SetContact(const PString & v);
00287
00288 PString GetSubject() const;
00289 void SetSubject(const PString & v);
00290
00291 PString GetTo() const;
00292 void SetTo(const PString & v);
00293
00294 PString GetVia() const;
00295 void SetVia(const PString & v);
00296
00297 PStringList GetViaList() const;
00298 void SetViaList(const PStringList & v);
00299
00300 PString GetReferTo() const;
00301 void SetReferTo(const PString & r);
00302
00303 PString GetReferredBy() const;
00304 void SetReferredBy(const PString & r);
00305
00306 PINDEX GetContentLength() const;
00307 void SetContentLength(PINDEX v);
00308 PBoolean IsContentLengthPresent() const;
00309
00310 PString GetCSeq() const;
00311 void SetCSeq(const PString & v);
00312
00313 PString GetDate() const;
00314 void SetDate(const PString & v);
00315 void SetDate(const PTime & t);
00316 void SetDate(void);
00317
00318 unsigned GetExpires(unsigned dflt = UINT_MAX) const;
00319 void SetExpires(unsigned v);
00320
00321 PINDEX GetMaxForwards() const;
00322 void SetMaxForwards(PINDEX v);
00323
00324 PINDEX GetMinExpires() const;
00325 void SetMinExpires(PINDEX v);
00326
00327 PString GetProxyAuthenticate() const;
00328 void SetProxyAuthenticate(const PString & v);
00329
00330 PStringList GetRoute() const;
00331 void SetRoute(const PString & v);
00332 void SetRoute(const PStringList & v);
00333
00334 PStringList GetRecordRoute(bool reversed) const;
00335 void SetRecordRoute(const PStringList & v);
00336
00337 unsigned GetCSeqIndex() const { return GetCSeq().AsUnsigned(); }
00338
00339 PString GetSupported() const;
00340 void SetSupported(const PString & v);
00341
00342 PString GetUnsupported() const;
00343 void SetUnsupported(const PString & v);
00344
00345 PString GetEvent() const;
00346 void SetEvent(const PString & v);
00347
00348 PCaselessString GetSubscriptionState(PStringToString & info) const;
00349 void SetSubscriptionState(const PString & v);
00350
00351 PString GetUserAgent() const;
00352 void SetUserAgent(const PString & v);
00353
00354 PString GetOrganization() const;
00355 void SetOrganization(const PString & v);
00356
00357 void GetProductInfo(OpalProductInfo & info) const;
00358 void SetProductInfo(const PString & ua, const OpalProductInfo & info);
00359
00360 PString GetWWWAuthenticate() const;
00361 void SetWWWAuthenticate(const PString & v);
00362
00363 PString GetSIPIfMatch() const;
00364 void SetSIPIfMatch(const PString & v);
00365
00366 PString GetSIPETag() const;
00367 void SetSIPETag(const PString & v);
00368
00369 PString GetRequire() const;
00370 void SetRequire(const PString & v, bool overwrite);
00371
00372 void GetAlertInfo(PString & info, int & appearance);
00373 void SetAlertInfo(const PString & info, int appearance);
00374
00375 PString GetAllowEvents() const;
00376 void SetAllowEvents(const PString & v);
00377
00380 PString GetFieldParameter(
00381 const PString & fieldName,
00382 const PString & paramName,
00383 const PString & defaultValue = PString::Empty()
00384 ) const { return ExtractFieldParameter((*this)(fieldName), paramName, defaultValue); }
00385
00390 void SetFieldParameter(
00391 const PString & fieldName,
00392 const PString & paramName,
00393 const PString & newValue
00394 ) { SetAt(fieldName, InsertFieldParameter((*this)(fieldName), paramName, newValue)); }
00395
00398 static PString ExtractFieldParameter(
00399 const PString & fieldValue,
00400 const PString & paramName,
00401 const PString & defaultValue = PString::Empty()
00402 );
00403
00408 static PString InsertFieldParameter(
00409 const PString & fieldValue,
00410 const PString & paramName,
00411 const PString & newValue
00412 );
00413
00414 protected:
00417 PStringList GetRouteList(const char * name, bool reversed) const;
00418
00422 void SetRouteList(const char * name, const PStringList & v);
00423
00425 bool compactForm;
00426 };
00427
00428
00430
00431
00432 typedef PHTTPClientAuthentication SIPAuthentication;
00433
00434 class SIPAuthenticator : public PHTTPClientAuthentication::AuthObject
00435 {
00436 public:
00437 SIPAuthenticator(SIP_PDU & pdu);
00438 virtual PMIMEInfo & GetMIME();
00439 virtual PString GetURI();
00440 virtual PString GetEntityBody();
00441 virtual PString GetMethod();
00442
00443 protected:
00444 SIP_PDU & m_pdu;
00445 };
00446
00447
00448
00450
00451
00457 class SIP_PDU : public PSafeObject
00458 {
00459 PCLASSINFO(SIP_PDU, PSafeObject);
00460 public:
00461 enum Methods {
00462 Method_INVITE,
00463 Method_ACK,
00464 Method_OPTIONS,
00465 Method_BYE,
00466 Method_CANCEL,
00467 Method_REGISTER,
00468 Method_SUBSCRIBE,
00469 Method_NOTIFY,
00470 Method_REFER,
00471 Method_MESSAGE,
00472 Method_INFO,
00473 Method_PING,
00474 Method_PUBLISH,
00475 NumMethods
00476 };
00477
00478 enum StatusCodes {
00479 IllegalStatusCode,
00480 Local_TransportError,
00481 Local_BadTransportAddress,
00482 Local_Timeout,
00483
00484 Information_Trying = 100,
00485 Information_Ringing = 180,
00486 Information_CallForwarded = 181,
00487 Information_Queued = 182,
00488 Information_Session_Progress = 183,
00489
00490 Successful_OK = 200,
00491 Successful_Accepted = 202,
00492
00493 Redirection_MultipleChoices = 300,
00494 Redirection_MovedPermanently = 301,
00495 Redirection_MovedTemporarily = 302,
00496 Redirection_UseProxy = 305,
00497 Redirection_AlternativeService = 380,
00498
00499 Failure_BadRequest = 400,
00500 Failure_UnAuthorised = 401,
00501 Failure_PaymentRequired = 402,
00502 Failure_Forbidden = 403,
00503 Failure_NotFound = 404,
00504 Failure_MethodNotAllowed = 405,
00505 Failure_NotAcceptable = 406,
00506 Failure_ProxyAuthenticationRequired = 407,
00507 Failure_RequestTimeout = 408,
00508 Failure_Conflict = 409,
00509 Failure_Gone = 410,
00510 Failure_LengthRequired = 411,
00511 Failure_RequestEntityTooLarge = 413,
00512 Failure_RequestURITooLong = 414,
00513 Failure_UnsupportedMediaType = 415,
00514 Failure_UnsupportedURIScheme = 416,
00515 Failure_BadExtension = 420,
00516 Failure_ExtensionRequired = 421,
00517 Failure_IntervalTooBrief = 423,
00518 Failure_TemporarilyUnavailable = 480,
00519 Failure_TransactionDoesNotExist = 481,
00520 Failure_LoopDetected = 482,
00521 Failure_TooManyHops = 483,
00522 Failure_AddressIncomplete = 484,
00523 Failure_Ambiguous = 485,
00524 Failure_BusyHere = 486,
00525 Failure_RequestTerminated = 487,
00526 Failure_NotAcceptableHere = 488,
00527 Failure_BadEvent = 489,
00528 Failure_RequestPending = 491,
00529 Failure_Undecipherable = 493,
00530
00531 Failure_InternalServerError = 500,
00532 Failure_NotImplemented = 501,
00533 Failure_BadGateway = 502,
00534 Failure_ServiceUnavailable = 503,
00535 Failure_ServerTimeout = 504,
00536 Failure_SIPVersionNotSupported = 505,
00537 Failure_MessageTooLarge = 513,
00538
00539 GlobalFailure_BusyEverywhere = 600,
00540 GlobalFailure_Decline = 603,
00541 GlobalFailure_DoesNotExistAnywhere = 604,
00542 GlobalFailure_NotAcceptable = 606,
00543
00544 MaxStatusCode = 699
00545 };
00546
00547 static const char * GetStatusCodeDescription(int code);
00548 friend ostream & operator<<(ostream & strm, StatusCodes status);
00549
00550 enum {
00551 MaxSize = 65535
00552 };
00553
00554 SIP_PDU(
00555 Methods method = SIP_PDU::NumMethods
00556 );
00557
00561 SIP_PDU(
00562 const SIP_PDU & request,
00563 StatusCodes code,
00564 const char * contact = NULL,
00565 const char * extra = NULL,
00566 const SDPSessionDescription * sdp = NULL
00567 );
00568
00569 SIP_PDU(const SIP_PDU &);
00570 SIP_PDU & operator=(const SIP_PDU &);
00571 ~SIP_PDU();
00572
00573 void PrintOn(
00574 ostream & strm
00575 ) const;
00576
00577 void InitialiseHeaders(
00578 const SIPURL & dest,
00579 const SIPURL & to,
00580 const SIPURL & from,
00581 const PString & callID,
00582 unsigned cseq,
00583 const PString & via
00584 );
00585 void InitialiseHeaders(
00586 SIPDialogContext & dialog,
00587 const PString & via = PString::Empty()
00588 );
00589 void InitialiseHeaders(
00590 SIPConnection & connection,
00591 const OpalTransport & transport
00592 );
00593
00598 bool SetRoute(const PStringList & routeSet);
00599 bool SetRoute(const SIPURL & proxy);
00600
00603 void SetAllow(unsigned bitmask);
00604
00607 void AdjustVia(OpalTransport & transport);
00608
00609 PString CreateVia(
00610 SIPEndPoint & endpoint,
00611 const OpalTransport & transport,
00612 SIPConnection * connection = NULL
00613 );
00614
00617 PBoolean Read(
00618 OpalTransport & transport
00619 );
00620
00623 PBoolean Write(
00624 OpalTransport & transport,
00625 const OpalTransportAddress & remoteAddress = OpalTransportAddress(),
00626 const PString & localInterface = PString::Empty()
00627 );
00628
00631 bool SendResponse(
00632 OpalTransport & transport,
00633 StatusCodes code,
00634 SIPEndPoint * endpoint = NULL,
00635 const char * contact = NULL,
00636 const char * extra = NULL
00637 );
00638 bool SendResponse(
00639 OpalTransport & transport,
00640 SIP_PDU & response,
00641 SIPEndPoint * endpoint = NULL
00642 );
00643
00647 PString Build();
00648
00649 PString GetTransactionID() const;
00650
00651 Methods GetMethod() const { return m_method; }
00652 StatusCodes GetStatusCode () const { return m_statusCode; }
00653 void SetStatusCode (StatusCodes c) { m_statusCode = c; }
00654 const SIPURL & GetURI() const { return m_uri; }
00655 unsigned GetVersionMajor() const { return m_versionMajor; }
00656 unsigned GetVersionMinor() const { return m_versionMinor; }
00657 const PString & GetEntityBody() const { return m_entityBody; }
00658 void SetEntityBody(const PString & body) { m_entityBody = body; }
00659 const PString & GetInfo() const { return m_info; }
00660 void SetInfo(const PString & info) { m_info = info; }
00661 const SIPMIMEInfo & GetMIME() const { return m_mime; }
00662 SIPMIMEInfo & GetMIME() { return m_mime; }
00663 void SetURI(const SIPURL & newuri) { m_uri = newuri; }
00664 SDPSessionDescription * GetSDP();
00665 void SetSDP(SDPSessionDescription * sdp);
00666
00667 protected:
00668 Methods m_method;
00669 StatusCodes m_statusCode;
00670 SIPURL m_uri;
00671 unsigned m_versionMajor;
00672 unsigned m_versionMinor;
00673 PString m_info;
00674 SIPMIMEInfo m_mime;
00675 PString m_entityBody;
00676
00677 SDPSessionDescription * m_SDP;
00678
00679 mutable PString m_transactionID;
00680
00681 bool m_usePeerTransportAddress;
00682 };
00683
00684
00685 PQUEUE(SIP_PDU_Queue, SIP_PDU);
00686
00687
00688 #if PTRACING
00689 ostream & operator<<(ostream & strm, SIP_PDU::Methods method);
00690 #endif
00691
00692
00694
00695
00698 class SIPDialogContext
00699 {
00700 public:
00701 SIPDialogContext();
00702
00703 PString AsString() const;
00704 bool FromString(
00705 const PString & str
00706 );
00707
00708 const PString & GetCallID() const { return m_callId; }
00709 void SetCallID(const PString & id) { m_callId = id; }
00710
00711 const SIPURL & GetRequestURI() const { return m_requestURI; }
00712 void SetRequestURI(const SIPURL & url) { m_requestURI = url; }
00713 bool SetRequestURI(const PString & uri) { return m_requestURI.Parse(uri); }
00714
00715 const PString & GetLocalTag() const { return m_localTag; }
00716 void SetLocalTag(const PString & tag) { m_localTag = tag; }
00717
00718 const SIPURL & GetLocalURI() const { return m_localURI; }
00719 void SetLocalURI(const SIPURL & url);
00720 bool SetLocalURI(const PString & uri);
00721
00722 const PString & GetRemoteTag() const { return m_remoteTag; }
00723 void SetRemoteTag(const PString & tag) { m_remoteTag = tag; }
00724
00725 const SIPURL & GetRemoteURI() const { return m_remoteURI; }
00726 void SetRemoteURI(const SIPURL & url);
00727 bool SetRemoteURI(const PString & uri);
00728
00729 const PStringList & GetRouteSet() const { return m_routeSet; }
00730 void SetRouteSet(const PStringList & routes) { m_routeSet = routes; }
00731
00732 const SIPURL & GetProxy() const { return m_proxy; }
00733 void SetProxy(const SIPURL & proxy, bool addToRouteSet);
00734
00735 void Update(const SIP_PDU & response);
00736
00737 unsigned GetNextCSeq();
00738 void IncrementCSeq(unsigned inc) { m_lastSentCSeq += inc; }
00739
00740 bool IsDuplicateCSeq(unsigned sequenceNumber);
00741
00742 bool IsEstablished() const
00743 {
00744 return !m_callId.IsEmpty() &&
00745 !m_requestURI.IsEmpty() &&
00746 !m_localTag.IsEmpty() &&
00747 !m_remoteTag.IsEmpty();
00748 }
00749
00750 bool UsePeerTransportAddress() const { return m_usePeerTransportAddress; }
00751
00752 void SetForking(bool f) { m_forking = f; }
00753
00754 protected:
00755 PString m_callId;
00756 SIPURL m_requestURI;
00757 SIPURL m_localURI;
00758 PString m_localTag;
00759 SIPURL m_remoteURI;
00760 PString m_remoteTag;
00761 PStringList m_routeSet;
00762 unsigned m_lastSentCSeq;
00763 unsigned m_lastReceivedCSeq;
00764 bool m_usePeerTransportAddress;
00765 bool m_forking;
00766 SIPURL m_proxy;
00767 };
00768
00769
00771
00772 struct SIPParameters
00773 {
00774 SIPParameters(
00775 const PString & aor = PString::Empty(),
00776 const PString & remote = PString::Empty()
00777 );
00778
00779 void Normalise(
00780 const PString & defaultUser,
00781 const PTimeInterval & defaultExpire
00782 );
00783
00784 PCaselessString m_remoteAddress;
00785 PCaselessString m_localAddress;
00786 PCaselessString m_proxyAddress;
00787 PCaselessString m_addressOfRecord;
00788 PCaselessString m_contactAddress;
00789 PString m_authID;
00790 PString m_password;
00791 PString m_realm;
00792 unsigned m_expire;
00793 unsigned m_restoreTime;
00794 PTimeInterval m_minRetryTime;
00795 PTimeInterval m_maxRetryTime;
00796 void * m_userData;
00797 };
00798
00799
00800 #if PTRACING
00801 ostream & operator<<(ostream & strm, const SIPParameters & params);
00802 #endif
00803
00804
00806
00807
00818 class SIPTransaction : public SIP_PDU
00819 {
00820 PCLASSINFO(SIPTransaction, SIP_PDU);
00821 public:
00822 SIPTransaction(
00823 Methods method,
00824 SIPEndPoint & endpoint,
00825 OpalTransport & transport
00826 );
00830 SIPTransaction(
00831 Methods method,
00832 SIPConnection & connection
00833 );
00834 ~SIPTransaction();
00835
00836 PBoolean Start();
00837 bool IsTrying() const { return m_state == Trying; }
00838 bool IsProceeding() const { return m_state == Proceeding; }
00839 bool IsInProgress() const { return m_state == Trying || m_state == Proceeding; }
00840 bool IsFailed() const { return m_state > Terminated_Success; }
00841 bool IsCompleted() const { return m_state >= Completed; }
00842 bool IsCanceled() const { return m_state == Cancelling || m_state == Terminated_Cancelled || m_state == Terminated_Aborted; }
00843 bool IsTerminated() const { return m_state >= Terminated_Success; }
00844
00845 void WaitForTermination();
00846 PBoolean Cancel();
00847 void Abort();
00848
00849 virtual PBoolean OnReceivedResponse(SIP_PDU & response);
00850 virtual PBoolean OnCompleted(SIP_PDU & response);
00851
00852 OpalTransport & GetTransport() const { return m_transport; }
00853 SIPConnection * GetConnection() const { return m_connection; }
00854 PString GetInterface() const { return m_localInterface; }
00855
00856 static PString GenerateCallID();
00857
00858 protected:
00859 bool SendPDU(SIP_PDU & pdu);
00860 bool ResendCANCEL();
00861 void SetParameters(const SIPParameters & params);
00862 void SetContact(const SIPURL & uri);
00863
00864 PDECLARE_NOTIFIER(PTimer, SIPTransaction, OnRetry);
00865 PDECLARE_NOTIFIER(PTimer, SIPTransaction, OnTimeout);
00866
00867 enum States {
00868 NotStarted,
00869 Trying,
00870 Proceeding,
00871 Cancelling,
00872 Completed,
00873 Terminated_Success,
00874 Terminated_Timeout,
00875 Terminated_RetriesExceeded,
00876 Terminated_TransportError,
00877 Terminated_Cancelled,
00878 Terminated_Aborted,
00879 NumStates
00880 };
00881 virtual void SetTerminated(States newState);
00882
00883 SIPEndPoint & m_endpoint;
00884 OpalTransport & m_transport;
00885 PSafePtr<SIPConnection> m_connection;
00886 PTimeInterval m_retryTimeoutMin;
00887 PTimeInterval m_retryTimeoutMax;
00888
00889 States m_state;
00890 unsigned m_retry;
00891 PTimer m_retryTimer;
00892 PTimer m_completionTimer;
00893 PSyncPoint m_terminated;
00894
00895 PString m_localInterface;
00896 OpalTransportAddress m_remoteAddress;
00897 };
00898
00899
00900 #define OPAL_PROXY_PARAM "OPAL-proxy"
00901 #define OPAL_LOCAL_ID_PARAM "OPAL-local-id"
00902
00903
00905
00906
00912 class SIPInvite : public SIPTransaction
00913 {
00914 PCLASSINFO(SIPInvite, SIPTransaction);
00915 public:
00916 SIPInvite(
00917 SIPConnection & connection,
00918 const OpalRTPSessionManager & sm
00919 );
00920
00921 virtual PBoolean OnReceivedResponse(SIP_PDU & response);
00922
00923 const OpalRTPSessionManager & GetSessionManager() const { return m_rtpSessions; }
00924 OpalRTPSessionManager & GetSessionManager() { return m_rtpSessions; }
00925
00926 protected:
00927 OpalRTPSessionManager m_rtpSessions;
00928 };
00929
00930
00932
00933 class SIPRegister : public SIPTransaction
00934 {
00935 PCLASSINFO(SIPRegister, SIPTransaction);
00936 public:
00937 enum CompatibilityModes {
00938 e_FullyCompliant,
00941 e_CannotRegisterMultipleContacts,
00945 e_CannotRegisterPrivateContacts
00949 };
00950
00952 struct Params : public SIPParameters {
00953 Params()
00954 : m_registrarAddress(m_remoteAddress)
00955 , m_compatibility(SIPRegister::e_FullyCompliant)
00956 { }
00957
00958 Params(const Params & param)
00959 : SIPParameters(param)
00960 , m_registrarAddress(m_remoteAddress)
00961 , m_compatibility(param.m_compatibility)
00962 { }
00963
00964 PCaselessString & m_registrarAddress;
00965 CompatibilityModes m_compatibility;
00966 };
00967
00968 SIPRegister(
00969 SIPEndPoint & endpoint,
00970 OpalTransport & transport,
00971 const PString & callId,
00972 unsigned cseq,
00973 const Params & params
00974 );
00975 };
00976
00977
00978 #if PTRACING
00979 ostream & operator<<(ostream & strm, SIPRegister::CompatibilityModes mode);
00980 ostream & operator<<(ostream & strm, const SIPRegister::Params & params);
00981 #endif
00982
00983
00985
00986 class SIPSubscribe : public SIPTransaction
00987 {
00988 PCLASSINFO(SIPSubscribe, SIPTransaction);
00989 public:
00992 enum PredefinedPackages {
00993 MessageSummary,
00994 Presence,
00995 Dialog,
00996
00997 NumPredefinedPackages,
00998
00999 Watcher = 0x8000,
01000
01001 MessageSummaryWatcher = Watcher|MessageSummary,
01002 PresenceWatcher = Watcher|Presence,
01003 DialogWatcher = Watcher|Dialog,
01004
01005 PackageMask = Watcher-1
01006 };
01007 friend PredefinedPackages operator|(PredefinedPackages p1, PredefinedPackages p2) { return (PredefinedPackages)((int)p1|(int)p2); }
01008
01009 class EventPackage : public PCaselessString
01010 {
01011 PCLASSINFO(EventPackage, PCaselessString);
01012 public:
01013 EventPackage(PredefinedPackages = NumPredefinedPackages);
01014 explicit EventPackage(const PString & str) : PCaselessString(str) { }
01015 explicit EventPackage(const char * str) : PCaselessString(str) { }
01016
01017 EventPackage & operator=(PredefinedPackages pkg);
01018 EventPackage & operator=(const PString & str) { PCaselessString::operator=(str); return *this; }
01019 EventPackage & operator=(const char * str) { PCaselessString::operator=(str); return *this; }
01020
01021 bool operator==(PredefinedPackages pkg) const { return Compare(EventPackage(pkg)) == EqualTo; }
01022 bool operator==(const PString & str) const { return Compare(str) == EqualTo; }
01023 bool operator==(const char * cstr) const { return InternalCompare(0, P_MAX_INDEX, cstr) == EqualTo; }
01024 virtual Comparison InternalCompare(PINDEX offset, PINDEX length, const char * cstr) const;
01025
01026 bool IsWatcher() const;
01027 };
01028
01030 struct SubscriptionStatus {
01031 SIPSubscribeHandler * m_handler;
01032 PString m_addressofRecord;
01033 bool m_wasSubscribing;
01034 bool m_reSubscribing;
01035 SIP_PDU::StatusCodes m_reason;
01036 OpalProductInfo m_productInfo;
01037 void * m_userData;
01038 };
01039
01040 struct NotifyCallbackInfo {
01041 NotifyCallbackInfo(
01042 SIPEndPoint & ep,
01043 OpalTransport & trans,
01044 SIP_PDU & notify,
01045 SIP_PDU & response
01046 );
01047
01048 bool SendResponse(
01049 SIP_PDU::StatusCodes status,
01050 const char * extra = NULL
01051 );
01052
01053 SIPEndPoint & m_endpoint;
01054 OpalTransport & m_transport;
01055 SIP_PDU & m_notify;
01056 SIP_PDU & m_response;
01057 bool m_sendResponse;
01058 };
01059
01060 struct Params : public SIPParameters
01061 {
01062 Params(PredefinedPackages pkg = NumPredefinedPackages)
01063 : m_agentAddress(m_remoteAddress)
01064 , m_eventPackage(pkg)
01065 , m_eventList(false)
01066 { }
01067
01068 Params(const Params & param)
01069 : SIPParameters(param)
01070 , m_agentAddress(m_remoteAddress)
01071 , m_eventPackage(param.m_eventPackage)
01072 , m_eventList(param.m_eventList)
01073 , m_contentType(param.m_contentType)
01074 , m_onSubcribeStatus(param.m_onSubcribeStatus)
01075 , m_onNotify(param.m_onNotify)
01076 { }
01077
01078 PCaselessString & m_agentAddress;
01079 EventPackage m_eventPackage;
01080 bool m_eventList;
01081 PCaselessString m_contentType;
01082
01083 PNotifierTemplate<const SubscriptionStatus &> m_onSubcribeStatus;
01084 PNotifierTemplate<NotifyCallbackInfo &> m_onNotify;
01085 };
01086
01087 SIPSubscribe(
01088 SIPEndPoint & ep,
01089 OpalTransport & trans,
01090 SIPDialogContext & dialog,
01091 const Params & params
01092 );
01093 };
01094
01095
01096 #if PTRACING
01097 ostream & operator<<(ostream & strm, const SIPSubscribe::Params & params);
01098 #endif
01099
01100
01101 typedef SIPSubscribe::EventPackage SIPEventPackage;
01102
01103
01105
01106 class SIPHandler;
01107
01108 class SIPEventPackageHandler
01109 {
01110 public:
01111 virtual ~SIPEventPackageHandler() { }
01112 virtual PCaselessString GetContentType() const = 0;
01113 virtual bool OnReceivedNOTIFY(SIPHandler & handler, SIP_PDU & request) = 0;
01114 virtual PString OnSendNOTIFY(SIPHandler & , const PObject * ) { return PString::Empty(); }
01115 };
01116
01117
01118 typedef PFactory<SIPEventPackageHandler, SIPEventPackage> SIPEventPackageFactory;
01119
01120
01122
01123 class SIPNotify : public SIPTransaction
01124 {
01125 PCLASSINFO(SIPNotify, SIPTransaction);
01126 public:
01127 SIPNotify(
01128 SIPEndPoint & ep,
01129 OpalTransport & trans,
01130 SIPDialogContext & dialog,
01131 const SIPEventPackage & eventPackage,
01132 const PString & state,
01133 const PString & body
01134 );
01135 };
01136
01137
01139
01140 class SIPPublish : public SIPTransaction
01141 {
01142 PCLASSINFO(SIPPublish, SIPTransaction);
01143 public:
01144 SIPPublish(
01145 SIPEndPoint & ep,
01146 OpalTransport & trans,
01147 const PString & id,
01148 const PString & sipIfMatch,
01149 const SIPSubscribe::Params & params,
01150 const PString & body
01151 );
01152 };
01153
01154
01156
01157 class SIPRefer : public SIPTransaction
01158 {
01159 PCLASSINFO(SIPRefer, SIPTransaction);
01160 public:
01161 SIPRefer(
01162 SIPConnection & connection,
01163 const SIPURL & referTo,
01164 const SIPURL & referred_by = SIPURL()
01165 );
01166 };
01167
01168
01170
01171
01172
01173
01174 class SIPReferNotify : public SIPTransaction
01175 {
01176 PCLASSINFO(SIPReferNotify, SIPTransaction);
01177 public:
01178 SIPReferNotify(
01179 SIPConnection & connection,
01180 StatusCodes code
01181 );
01182 };
01183
01184
01186
01187
01188
01189 class SIPMessage : public SIPTransaction
01190 {
01191 PCLASSINFO(SIPMessage, SIPTransaction);
01192 public:
01193 struct Params : public SIPParameters
01194 {
01195 Params()
01196 {
01197 m_expire = 5000;
01198 }
01199
01200 Params(const Params & param)
01201 : SIPParameters(param)
01202 , m_contentType(param.m_contentType)
01203 , m_id(param.m_id)
01204 { }
01205
01206 PCaselessString m_contentType;
01207 PString m_id;
01208 };
01209
01210
01211 public:
01212 SIPMessage(
01213 SIPEndPoint & ep,
01214 OpalTransport & trans,
01215 const Params & params,
01216 const PString & body
01217 );
01218 SIPURL m_localAddress;
01219 };
01220
01221
01223
01224
01225
01226
01227 class SIPAck : public SIP_PDU
01228 {
01229 PCLASSINFO(SIPAck, SIP_PDU);
01230 public:
01231 SIPAck(
01232 SIPTransaction & invite,
01233 SIP_PDU & response
01234 );
01235 };
01236
01237
01239
01240
01241
01242 class SIPOptions : public SIPTransaction
01243 {
01244 PCLASSINFO(SIPOptions, SIPTransaction);
01245
01246 public:
01247 SIPOptions(
01248 SIPEndPoint & ep,
01249 OpalTransport & trans,
01250 const SIPURL & address
01251 );
01252 };
01253
01254
01256
01257
01258
01259 class SIPPing : public SIPTransaction
01260 {
01261 PCLASSINFO(SIPPing, SIPTransaction);
01262
01263 public:
01264 SIPPing(
01265 SIPEndPoint & ep,
01266 OpalTransport & trans,
01267 const SIPURL & address,
01268 const PString & body = PString::Empty()
01269 );
01270 };
01271
01272
01273 #endif // OPAL_SIP
01274
01275 #endif // OPAL_SIP_SIPPDU_H
01276
01277
01278