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 <ptclib/pxml.h>
00047 #include <ptclib/threadpool.h>
00048 #include <opal/transports.h>
00049 #include <rtp/rtpconn.h>
00050
00051
00052 class OpalMediaFormatList;
00053 class OpalProductInfo;
00054
00055 class SIPEndPoint;
00056 class SIPConnection;
00057 class SIPHandler;
00058 class SIP_PDU;
00059 class SIPSubscribeHandler;
00060 class SIPDialogContext;
00061 class SIPMIMEInfo;
00062 class SIPTransaction;
00063 class SDPSessionDescription;
00064
00065
00067
00068
00074 class SIPURL : public PURL
00075 {
00076 PCLASSINFO(SIPURL, PURL);
00077 public:
00078 static const WORD DefaultPort;
00079 static const WORD DefaultSecurePort;
00080
00081 SIPURL();
00082
00083 SIPURL(
00084 const PURL & url
00085 ) : PURL(url) { }
00086 SIPURL & operator=(
00087 const PURL & url
00088 ) { PURL::operator=(url); return *this; }
00089
00092 SIPURL(
00093 const char * cstr,
00094 const char * defaultScheme = NULL
00095 );
00096 SIPURL & operator=(
00097 const char * cstr
00098 ) { Parse(cstr); return *this; }
00099
00102 SIPURL(
00103 const PString & str,
00104 const char * defaultScheme = NULL
00105 );
00106 SIPURL & operator=(
00107 const PString & str
00108 ) { Parse(str); return *this; }
00109
00119 SIPURL(
00120 const PString & name,
00121 const OpalTransportAddress & address,
00122 WORD listenerPort = 0,
00123 const char * scheme = NULL
00124 );
00125
00126 SIPURL(
00127 const OpalTransportAddress & address,
00128 WORD listenerPort = 0,
00129 const char * scheme = NULL
00130 );
00131 SIPURL & operator=(
00132 const OpalTransportAddress & address
00133 );
00134
00135 SIPURL(
00136 const SIPMIMEInfo & mime,
00137 const char * name
00138 );
00139
00148 virtual Comparison Compare(
00149 const PObject & obj
00150 ) const;
00151
00155 PString AsQuotedString() const;
00156
00159 PString GetDisplayName(PBoolean useDefault = true) const;
00160
00161 void SetDisplayName(const PString & str)
00162 {
00163 m_displayName = str;
00164 }
00165
00167 const PStringOptions & GetFieldParameters() const { return m_fieldParameters; }
00168 PStringOptions & GetFieldParameters() { return m_fieldParameters; }
00169
00171 PCaselessString GetTransportProto() const;
00172
00178 OpalTransportAddress GetTransportAddress(
00179 PINDEX dnsEntry = P_MAX_INDEX
00180 ) const;
00181
00184 void SetHostAddress(const OpalTransportAddress & addr);
00185
00186 enum UsageContext {
00187 ExternalURI,
00188 RequestURI,
00189 ToURI,
00190 FromURI,
00191 RouteURI,
00192 RedirectURI,
00193 ContactURI,
00194 RegContactURI,
00195 RegisterURI
00196 };
00197
00203 void Sanitise(
00204 UsageContext context
00205 );
00206
00208 static PString GenerateTag();
00209
00211 void SetTag(
00212 const PString & tag = PString::Empty(),
00213 bool force = false
00214 );
00215
00217 PString GetTag() const;
00218
00219 protected:
00220 void ParseAsAddress(
00221 const PString & name,
00222 const OpalTransportAddress & address,
00223 WORD listenerPort,
00224 const char * scheme);
00225
00226
00227 virtual PBoolean InternalParse(
00228 const char * cstr,
00229 const char * defaultScheme
00230 ) { return ReallyInternalParse(false, cstr, defaultScheme); }
00231
00232 bool ReallyInternalParse(
00233 bool fromField,
00234 const char * cstr,
00235 const char * defaultScheme
00236 );
00237 WORD GetDefaultPort() const;
00238
00239 PString m_displayName;
00240 PStringOptions m_fieldParameters;
00241 };
00242
00243
00244 class SIPURLList : public std::list<SIPURL>
00245 {
00246 public:
00247 bool FromString(
00248 const PString & str,
00249 SIPURL::UsageContext context = SIPURL::RouteURI,
00250 bool reversed = false
00251 );
00252 PString ToString() const;
00253 SIPURL FindCompatible(const OpalTransportAddress & addr PTRACE_PARAM(, const char * listType)) const;
00254 friend ostream & operator<<(ostream & strm, const SIPURLList & urls);
00255 };
00256
00257
00258
00260
00261
00292 class SIPMIMEInfo : public PMIMEInfo
00293 {
00294 PCLASSINFO(SIPMIMEInfo, PMIMEInfo);
00295 public:
00296 SIPMIMEInfo(bool compactForm = false);
00297
00298 virtual void PrintOn(ostream & strm) const;
00299 virtual bool InternalAddMIME(const PString & fieldName, const PString & fieldValue);
00300
00301 void SetCompactForm(bool form) { compactForm = form; }
00302
00303 PCaselessString GetContentType(bool includeParameters = false) const;
00304 void SetContentType(const PString & v);
00305
00306 PCaselessString GetContentEncoding() const;
00307 void SetContentEncoding(const PString & v);
00308
00309 SIPURL GetFrom() const;
00310 void SetFrom(const SIPURL & v);
00311
00312 SIPURL GetPAssertedIdentity() const;
00313 void SetPAssertedIdentity(const PString & v);
00314
00315 SIPURL GetPPreferredIdentity() const;
00316 void SetPPreferredIdentity(const PString & v);
00317
00318 PString GetAccept() const;
00319 void SetAccept(const PString & v);
00320
00321 PString GetAcceptEncoding() const;
00322 void SetAcceptEncoding(const PString & v);
00323
00324 PString GetAcceptLanguage() const;
00325 void SetAcceptLanguage(const PString & v);
00326
00327 PString GetAllow() const;
00328 unsigned GetAllowBitMask() const;
00329 void SetAllow(const PString & v);
00330
00331 PString GetCallID() const;
00332 void SetCallID(const PString & v);
00333
00334 SIPURL GetContact() const;
00335 bool GetContacts(SIPURLList & contacts) const;
00336 void SetContact(const PString & v);
00337
00338 PString GetSubject() const;
00339 void SetSubject(const PString & v);
00340
00341 SIPURL GetTo() const;
00342 void SetTo(const SIPURL & v);
00343
00344 PString GetVia() const;
00345 void SetVia(const PString & v);
00346
00347 bool GetViaList(PStringList & v) const;
00348 void SetViaList(const PStringList & v);
00349
00350 PString GetFirstVia() const;
00351 OpalTransportAddress GetViaReceivedAddress() const;
00352
00353 SIPURL GetReferTo() const;
00354 void SetReferTo(const PString & r);
00355
00356 SIPURL GetReferredBy() const;
00357 void SetReferredBy(const PString & r);
00358
00359 PINDEX GetContentLength() const;
00360 void SetContentLength(PINDEX v);
00361 PBoolean IsContentLengthPresent() const;
00362
00363 PString GetCSeq() const;
00364 void SetCSeq(const PString & v);
00365
00366 PString GetDate() const;
00367 void SetDate(const PString & v);
00368 void SetDate(const PTime & t);
00369 void SetDate(void);
00370
00371 unsigned GetExpires(unsigned dflt = UINT_MAX) const;
00372 void SetExpires(unsigned v);
00373
00374 unsigned GetMaxForwards() const;
00375 void SetMaxForwards(PINDEX v);
00376
00377 unsigned GetMinExpires() const;
00378 void SetMinExpires(PINDEX v);
00379
00380 PString GetProxyAuthenticate() const;
00381 void SetProxyAuthenticate(const PString & v);
00382
00383 PString GetRoute() const;
00384 bool GetRoute(SIPURLList & proxies) const;
00385 void SetRoute(const PString & v);
00386 void SetRoute(const SIPURLList & proxies);
00387
00388 PString GetRecordRoute() const;
00389 bool GetRecordRoute(SIPURLList & proxies, bool reversed) const;
00390 void SetRecordRoute(const PString & v);
00391 void SetRecordRoute(const SIPURLList & proxies);
00392
00393 unsigned GetCSeqIndex() const { return GetCSeq().AsUnsigned(); }
00394
00395 PStringSet GetRequire() const;
00396 void SetRequire(const PStringSet & v);
00397 void AddRequire(const PString & v);
00398
00399 PStringSet GetSupported() const;
00400 void SetSupported(const PStringSet & v);
00401 void AddSupported(const PString & v);
00402
00403 PStringSet GetUnsupported() const;
00404 void SetUnsupported(const PStringSet & v);
00405 void AddUnsupported(const PString & v);
00406
00407 PString GetEvent() const;
00408 void SetEvent(const PString & v);
00409
00410 PCaselessString GetSubscriptionState(PStringToString & info) const;
00411 void SetSubscriptionState(const PString & v);
00412
00413 PString GetUserAgent() const;
00414 void SetUserAgent(const PString & v);
00415
00416 PString GetOrganization() const;
00417 void SetOrganization(const PString & v);
00418
00419 void GetProductInfo(OpalProductInfo & info) const;
00420 void SetProductInfo(const PString & ua, const OpalProductInfo & info);
00421
00422 PString GetWWWAuthenticate() const;
00423 void SetWWWAuthenticate(const PString & v);
00424
00425 PString GetSIPIfMatch() const;
00426 void SetSIPIfMatch(const PString & v);
00427
00428 PString GetSIPETag() const;
00429 void SetSIPETag(const PString & v);
00430
00431 void GetAlertInfo(PString & info, int & appearance) const;
00432 void SetAlertInfo(const PString & info, int appearance);
00433
00434 PString GetCallInfo() const;
00435
00436 PString GetAllowEvents() const;
00437 void SetAllowEvents(const PString & v);
00438 void SetAllowEvents(const PStringSet & list);
00439
00442 PString GetFieldParameter(
00443 const PString & fieldName,
00444 const PString & paramName,
00445 const PString & defaultValue = PString::Empty()
00446 ) const { return ExtractFieldParameter((*this)(fieldName), paramName, defaultValue); }
00447
00452 void SetFieldParameter(
00453 const PString & fieldName,
00454 const PString & paramName,
00455 const PString & newValue
00456 ) { SetAt(fieldName, InsertFieldParameter((*this)(fieldName), paramName, newValue)); }
00457
00460 static PString ExtractFieldParameter(
00461 const PString & fieldValue,
00462 const PString & paramName,
00463 const PString & defaultValue = PString::Empty()
00464 );
00465
00470 static PString InsertFieldParameter(
00471 const PString & fieldValue,
00472 const PString & paramName,
00473 const PString & newValue
00474 );
00475
00476 protected:
00477 PStringSet GetTokenSet(const char * field) const;
00478 void AddTokenSet(const char * field, const PString & token);
00479 void SetTokenSet(const char * field, const PStringSet & tokens);
00480
00482 bool compactForm;
00483 };
00484
00485
00487
00488
00489 typedef PHTTPClientAuthentication SIPAuthentication;
00490
00491 class SIPAuthenticator : public PHTTPClientAuthentication::AuthObject
00492 {
00493 public:
00494 SIPAuthenticator(SIP_PDU & pdu);
00495 virtual PMIMEInfo & GetMIME();
00496 virtual PString GetURI();
00497 virtual PString GetEntityBody();
00498 virtual PString GetMethod();
00499
00500 protected:
00501 SIP_PDU & m_pdu;
00502 };
00503
00504
00505
00507
00508
00514 class SIP_PDU : public PSafeObject
00515 {
00516 PCLASSINFO(SIP_PDU, PSafeObject);
00517 public:
00518 enum Methods {
00519 Method_INVITE,
00520 Method_ACK,
00521 Method_OPTIONS,
00522 Method_BYE,
00523 Method_CANCEL,
00524 Method_REGISTER,
00525 Method_SUBSCRIBE,
00526 Method_NOTIFY,
00527 Method_REFER,
00528 Method_MESSAGE,
00529 Method_INFO,
00530 Method_PING,
00531 Method_PUBLISH,
00532 Method_PRACK,
00533 NumMethods
00534 };
00535
00536 enum StatusCodes {
00537 IllegalStatusCode,
00538 Local_TransportError,
00539 Local_BadTransportAddress,
00540 Local_Timeout,
00541 Local_NoCompatibleListener,
00542 Local_CannotMapScheme,
00543 Local_TransportLost,
00544 Local_KeepAlive,
00545 Local_NotAuthenticated,
00546
00547 Information_Trying = 100,
00548 Information_Ringing = 180,
00549 Information_CallForwarded = 181,
00550 Information_Queued = 182,
00551 Information_Session_Progress = 183,
00552
00553 Successful_OK = 200,
00554 Successful_Accepted = 202,
00555
00556 Redirection_MultipleChoices = 300,
00557 Redirection_MovedPermanently = 301,
00558 Redirection_MovedTemporarily = 302,
00559 Redirection_UseProxy = 305,
00560 Redirection_AlternativeService = 380,
00561
00562 Failure_BadRequest = 400,
00563 Failure_UnAuthorised = 401,
00564 Failure_PaymentRequired = 402,
00565 Failure_Forbidden = 403,
00566 Failure_NotFound = 404,
00567 Failure_MethodNotAllowed = 405,
00568 Failure_NotAcceptable = 406,
00569 Failure_ProxyAuthenticationRequired = 407,
00570 Failure_RequestTimeout = 408,
00571 Failure_Conflict = 409,
00572 Failure_Gone = 410,
00573 Failure_LengthRequired = 411,
00574 Failure_RequestEntityTooLarge = 413,
00575 Failure_RequestURITooLong = 414,
00576 Failure_UnsupportedMediaType = 415,
00577 Failure_UnsupportedURIScheme = 416,
00578 Failure_BadExtension = 420,
00579 Failure_ExtensionRequired = 421,
00580 Failure_IntervalTooBrief = 423,
00581 Failure_UnresolvableDestination = 476,
00582 Failure_TemporarilyUnavailable = 480,
00583 Failure_TransactionDoesNotExist = 481,
00584 Failure_LoopDetected = 482,
00585 Failure_TooManyHops = 483,
00586 Failure_AddressIncomplete = 484,
00587 Failure_Ambiguous = 485,
00588 Failure_BusyHere = 486,
00589 Failure_RequestTerminated = 487,
00590 Failure_NotAcceptableHere = 488,
00591 Failure_BadEvent = 489,
00592 Failure_RequestPending = 491,
00593 Failure_Undecipherable = 493,
00594
00595 Failure_InternalServerError = 500,
00596 Failure_NotImplemented = 501,
00597 Failure_BadGateway = 502,
00598 Failure_ServiceUnavailable = 503,
00599 Failure_ServerTimeout = 504,
00600 Failure_SIPVersionNotSupported = 505,
00601 Failure_MessageTooLarge = 513,
00602
00603 GlobalFailure_BusyEverywhere = 600,
00604 GlobalFailure_Decline = 603,
00605 GlobalFailure_DoesNotExistAnywhere = 604,
00606 GlobalFailure_NotAcceptable = 606,
00607
00608 MaxStatusCode = 699
00609 };
00610
00611 static PString GetStatusCodeDescription(int code);
00612 friend ostream & operator<<(ostream & strm, StatusCodes status);
00613
00614 SIP_PDU(
00615 Methods method = SIP_PDU::NumMethods,
00616 const OpalTransportPtr & transport = NULL
00617 );
00618
00622 SIP_PDU(
00623 const SIP_PDU & request,
00624 StatusCodes code,
00625 const SDPSessionDescription * sdp = NULL
00626 );
00627
00628 SIP_PDU(const SIP_PDU &);
00629 SIP_PDU & operator=(const SIP_PDU &);
00630 ~SIP_PDU();
00631
00632 void PrintOn(
00633 ostream & strm
00634 ) const;
00635
00636 void InitialiseHeaders(
00637 const SIPURL & dest,
00638 const SIPURL & to,
00639 const SIPURL & from,
00640 const PString & callID,
00641 unsigned cseq
00642 );
00643 void InitialiseHeaders(
00644 SIPDialogContext & dialog,
00645 unsigned cseq = 0
00646 );
00647 void InitialiseHeaders(
00648 SIPConnection & connection,
00649 unsigned cseq = 0
00650 );
00651 void InitialiseHeaders(
00652 const SIP_PDU & request
00653 );
00654
00659 bool SetRoute(const SIPURLList & routeSet);
00660 bool SetRoute(const SIPURL & proxy);
00661
00664 void SetAllow(unsigned bitmask);
00665
00668 StatusCodes Read();
00669 StatusCodes Parse(
00670 istream & strm,
00671 bool truncated
00672 );
00673
00676 bool Send();
00677
00680 bool SendResponse(
00681 StatusCodes code
00682 );
00683
00687 void Build(PString & pduStr, PINDEX & pduLen);
00688
00689 const PString & GetTransactionID() const { return m_transactionID; }
00690
00691 Methods GetMethod() const { return m_method; }
00692 StatusCodes GetStatusCode () const { return m_statusCode; }
00693 void SetStatusCode (StatusCodes c) { m_statusCode = c; }
00694 const SIPURL & GetURI() const { return m_uri; }
00695 void SetURI(const SIPURL & newuri) { m_uri = newuri; }
00696 unsigned GetVersionMajor() const { return m_versionMajor; }
00697 unsigned GetVersionMinor() const { return m_versionMinor; }
00698 void SetCSeq(unsigned cseq);
00699 const PString & GetEntityBody() const { return m_entityBody; }
00700 void SetEntityBody(const PString & body) { m_entityBody = body; }
00701 void SetEntityBody();
00702 const PString & GetInfo() const { return m_info; }
00703 void SetInfo(const PString & info) { m_info = info; }
00704 const SIPMIMEInfo & GetMIME() const { return m_mime; }
00705 SIPMIMEInfo & GetMIME() { return m_mime; }
00706 SDPSessionDescription * GetSDP() { return m_SDP; }
00707 void SetSDP(SDPSessionDescription * sdp);
00708 bool DecodeSDP(const OpalMediaFormatList & masterList);
00709
00710 const PString & GetExternalTransportAddress() const { return m_externalTransportAddress; }
00711 OpalTransportPtr GetTransport() const { return m_transport; }
00712
00713 protected:
00714 void CalculateVia();
00715 StatusCodes InternalSend(bool canDoTCP);
00716
00717 Methods m_method;
00718 StatusCodes m_statusCode;
00719 SIPURL m_uri;
00720 unsigned m_versionMajor;
00721 unsigned m_versionMinor;
00722 PString m_info;
00723 SIPMIMEInfo m_mime;
00724 PString m_entityBody;
00725 PString m_transactionID;
00726
00727 SDPSessionDescription * m_SDP;
00728
00729 OpalTransportPtr m_transport;
00730 OpalTransportAddress m_viaAddress;
00731 OpalTransportAddress m_externalTransportAddress;
00732 };
00733
00734
00735 PQUEUE(SIP_PDU_Queue, SIP_PDU);
00736
00737
00738 #if PTRACING
00739 ostream & operator<<(ostream & strm, SIP_PDU::Methods method);
00740 #endif
00741
00742
00744
00745
00748 class SIPDialogContext
00749 {
00750 public:
00751 SIPDialogContext();
00752 SIPDialogContext(const SIPMIMEInfo & mime);
00753
00754 PString AsString() const;
00755 bool FromString(
00756 const PString & str
00757 );
00758
00759 const PString & GetCallID() const { return m_callId; }
00760 void SetCallID(const PString & id) { m_callId = id; }
00761
00762 const SIPURL & GetRequestURI() const { return m_requestURI; }
00763 void SetRequestURI(const SIPURL & url);
00764
00765 const PString & GetLocalTag() const { return m_localTag; }
00766 void SetLocalTag(const PString & tag) { m_localTag = tag; }
00767
00768 const SIPURL & GetLocalURI() const { return m_localURI; }
00769 void SetLocalURI(const SIPURL & url);
00770
00771 const PString & GetRemoteTag() const { return m_remoteTag; }
00772 void SetRemoteTag(const PString & tag) { m_remoteTag = tag; }
00773
00774 const SIPURL & GetRemoteURI() const { return m_remoteURI; }
00775 void SetRemoteURI(const SIPURL & url);
00776
00777 const SIPURLList & GetRouteSet() const { return m_routeSet; }
00778 void SetRouteSet(const PString & str) { m_routeSet.FromString(str); }
00779
00780 const SIPURL & GetProxy() const { return m_proxy; }
00781 void SetProxy(const SIPURL & proxy, bool addToRouteSet);
00782
00783 void Update(const SIP_PDU & response);
00784
00785 unsigned GetNextCSeq();
00786 void IncrementCSeq(unsigned inc) { m_lastSentCSeq += inc; }
00787
00788 bool IsDuplicateCSeq(unsigned sequenceNumber);
00789
00790 bool IsEstablished() const
00791 {
00792 return !m_callId.IsEmpty() &&
00793 !m_requestURI.IsEmpty() &&
00794 !m_localTag.IsEmpty() &&
00795 !m_remoteTag.IsEmpty();
00796 }
00797
00798 OpalTransportAddress GetRemoteTransportAddress(PINDEX dnsEntry) const;
00799 const PString & GetInterface() const { return m_interface; }
00800 void SetInterface(const PString & newInterface) { m_interface = newInterface; }
00801
00802 void SetForking(bool f) { m_forking = f; }
00803
00804 protected:
00805 PString m_callId;
00806 SIPURL m_requestURI;
00807 SIPURL m_localURI;
00808 PString m_localTag;
00809 SIPURL m_remoteURI;
00810 PString m_remoteTag;
00811 SIPURLList m_routeSet;
00812 unsigned m_lastSentCSeq;
00813 unsigned m_lastReceivedCSeq;
00814 OpalTransportAddress m_externalTransportAddress;
00815 bool m_forking;
00816 SIPURL m_proxy;
00817 PString m_interface;
00818 };
00819
00820
00822
00823 struct SIPParameters
00824 {
00825 SIPParameters(
00826 const PString & aor = PString::Empty(),
00827 const PString & remote = PString::Empty()
00828 );
00829
00830 bool Normalise(
00831 const PString & defaultUser,
00832 const PTimeInterval & defaultExpire
00833 );
00834
00835 PCaselessString m_remoteAddress;
00836 PCaselessString m_localAddress;
00837 PCaselessString m_proxyAddress;
00838 PCaselessString m_addressOfRecord;
00839 PCaselessString m_contactAddress;
00840 PCaselessString m_interface;
00841 SIPMIMEInfo m_mime;
00842 PString m_authID;
00843 PString m_password;
00844 PString m_realm;
00845 unsigned m_expire;
00846 unsigned m_restoreTime;
00847 PTimeInterval m_minRetryTime;
00848 PTimeInterval m_maxRetryTime;
00849 void * m_userData;
00850 };
00851
00852
00853 #if PTRACING
00854 ostream & operator<<(ostream & strm, const SIPParameters & params);
00855 #endif
00856
00857
00859
00860
00861
00862
00863
00864 class SIPWorkItem : public PObject
00865 {
00866 PCLASSINFO(SIPWorkItem, PObject);
00867 public:
00868 SIPWorkItem(SIPEndPoint & ep, const PString & token);
00869
00870 virtual void Work() = 0;
00871
00872 bool GetTarget(PSafePtr<SIPTransaction> & transaction);
00873 bool GetTarget(PSafePtr<SIPConnection> & connection);
00874 bool GetTarget(PSafePtr<SIPHandler> & handler);
00875
00876 protected:
00877 SIPEndPoint & m_endpoint;
00878 PString m_token;
00879 };
00880
00881
00882 class SIPThreadPool : public PQueuedThreadPool<SIPWorkItem>
00883 {
00884 typedef PQueuedThreadPool<SIPWorkItem> BaseClass;
00885 PCLASSINFO(SIPThreadPool, BaseClass);
00886 public:
00887 SIPThreadPool(unsigned maxWorkers, const char * threadName)
00888 : BaseClass(maxWorkers, 0, threadName, PThread::HighPriority)
00889 {
00890 }
00891 };
00892
00893
00894 template <class Target_T>
00895 class SIPTimeoutWorkItem : public SIPWorkItem
00896 {
00897 PCLASSINFO(SIPTimeoutWorkItem, SIPWorkItem);
00898 public:
00899 typedef void (Target_T::* Callback)();
00900
00901 SIPTimeoutWorkItem(SIPEndPoint & ep, const PString & token, Callback callback)
00902 : SIPWorkItem(ep, token)
00903 , m_callback(callback)
00904 {
00905 }
00906
00907 virtual void Work()
00908 {
00909 PSafePtr<Target_T> target;
00910 if (GetTarget(target)) {
00911 PTRACE_CONTEXT_ID_PUSH_THREAD(target);
00912 (target->*m_callback)();
00913 PTRACE(4, "SIP\tHandled timeout");
00914 }
00915 }
00916
00917 protected:
00918 Callback m_callback;
00919 };
00920
00921
00922 template <class Target_T>
00923 class SIPPoolTimer : public PPoolTimerArg3<SIPTimeoutWorkItem<Target_T>,
00924 SIPEndPoint &,
00925 PString,
00926 void (Target_T::*)(),
00927 SIPWorkItem>
00928 {
00929 typedef SIPTimeoutWorkItem<Target_T> Work_T;
00930 typedef PPoolTimerArg3<Work_T, SIPEndPoint &, PString, void (Target_T::*)(), SIPWorkItem> BaseClass;
00931 PCLASSINFO(SIPPoolTimer, BaseClass);
00932 private:
00933 PString m_token;
00934 public:
00935 SIPPoolTimer(SIPThreadPool & pool, SIPEndPoint & ep, const PString & token, void (Target_T::* callback)())
00936 : BaseClass(pool, ep, token, callback)
00937 , m_token(token)
00938 {
00939 }
00940
00941 virtual const char * GetGroup(const Work_T &) const { return m_token; }
00942
00943 PTIMER_OPERATORS(SIPPoolTimer);
00944 };
00945
00946
00948
00949
00950 class SIPTransactionOwner
00951 {
00952 public:
00953 SIPTransactionOwner(
00954 PSafeObject & object,
00955 SIPEndPoint & endpoint
00956 );
00957 virtual ~SIPTransactionOwner();
00958
00959 virtual PString GetAuthID() const = 0;
00960 virtual PString GetPassword() const { return PString::Empty(); }
00961 virtual unsigned GetAllowedMethods() const;
00962
00963 virtual void OnStartTransaction(SIPTransaction & ) { }
00964 virtual void OnReceivedResponse(SIPTransaction & transaction, SIP_PDU & response);
00965 virtual void OnTransactionFailed(SIPTransaction & transaction);
00966
00967 void FinaliseForking(SIPTransaction & transaction, SIP_PDU & response);
00968 bool CleanPendingTransactions();
00969 void AbortPendingTransactions(bool all = true);
00970
00971 virtual SIP_PDU::StatusCodes StartTransaction(
00972 const OpalTransport::WriteConnectCallback & function
00973 );
00974
00975 SIP_PDU::StatusCodes SwitchTransportProto(const char * proto, OpalTransportPtr * transport);
00976
00977 SIP_PDU::StatusCodes HandleAuthentication(const SIP_PDU & response);
00978
00979 SIPEndPoint & GetEndPoint() const { return m_endpoint; }
00980 OpalTransportAddress GetRemoteTransportAddress() const { return m_dialog.GetRemoteTransportAddress(m_dnsEntry); }
00981 const SIPURL & GetRequestURI() const { return m_dialog.GetRequestURI(); }
00982 const SIPURL & GetRemoteURI() const { return m_dialog.GetRemoteURI(); }
00983 const SIPURL & GetProxy() const { return m_dialog.GetProxy(); }
00984 const PString & GetInterface() const { return m_dialog.GetInterface(); }
00985 void ResetInterface() { m_dialog.SetInterface(PString::Empty()); }
00986 PINDEX GetDNSEntry() const { return m_dnsEntry; }
00987 SIPAuthentication * GetAuthenticator() const { return m_authentication; }
00988 SIPDialogContext & GetDialog() { return m_dialog; }
00989 const SIPDialogContext & GetDialog() const { return m_dialog; }
00990
00991 protected:
00992 PSafeObject & m_object;
00993 SIPEndPoint & m_endpoint;
00994 SIPDialogContext m_dialog;
00995 PINDEX m_dnsEntry;
00996 SIPAuthentication * m_authentication;
00997 unsigned m_authenticateErrors;
00998
00999 PSafeList<SIPTransaction> m_transactions;
01000 PMutex m_forkMutex;
01001
01002 friend class SIPTransaction;
01003 };
01004
01005
01006 class SIPTransactionBase : public SIP_PDU
01007 {
01008 PCLASSINFO(SIPTransactionBase, SIP_PDU);
01009 protected:
01010 SIPTransactionBase(
01011 Methods method
01012 ) : SIP_PDU(method) { }
01013
01014 public:
01015 SIPTransactionBase(
01016 const PString & transactionID
01017 ) { m_transactionID = transactionID; }
01018
01019 Comparison Compare(
01020 const PObject & other
01021 ) const;
01022
01023 virtual bool IsTerminated() const { return true; }
01024 };
01025
01026
01037 class SIPTransaction : public SIPTransactionBase
01038 {
01039 PCLASSINFO(SIPTransaction, SIPTransactionBase);
01040 protected:
01041 SIPTransaction(
01042 Methods method,
01043 SIPTransactionOwner * owner,
01044 OpalTransport * transport,
01045 bool deleteOwner = false
01046 );
01047 public:
01048 ~SIPTransaction();
01049
01050
01051
01052 virtual SIPTransaction * CreateDuplicate() const = 0;
01053
01054 bool Start();
01055 bool IsTrying() const { return m_state == Trying; }
01056 bool IsProceeding() const { return m_state == Proceeding; }
01057 bool IsInProgress() const { return m_state == Trying || m_state == Proceeding; }
01058 bool IsFailed() const { return m_state > Terminated_Success; }
01059 bool IsCompleted() const { return m_state >= Completed; }
01060 bool IsCanceled() const { return m_state == Cancelling || m_state == Terminated_Cancelled || m_state == Terminated_Aborted; }
01061 bool IsTerminated() const { return m_state >= Terminated_Success; }
01062
01063 void WaitForCompletion();
01064 PBoolean Cancel();
01065 void Abort();
01066
01067 virtual PBoolean OnReceivedResponse(SIP_PDU & response);
01068 virtual PBoolean OnCompleted(SIP_PDU & response);
01069
01070 SIPEndPoint & GetEndPoint() const { return m_owner->GetEndPoint(); }
01071 SIPConnection * GetConnection() const;
01072 PString GetInterface() const { return m_localInterface; }
01073
01074 static PString GenerateCallID();
01075
01076 protected:
01077 bool ResendCANCEL();
01078 void SetParameters(const SIPParameters & params);
01079
01080 typedef SIPPoolTimer<SIPTransaction> PoolTimer;
01081
01082 void OnRetry();
01083 void OnTimeout();
01084
01085 P_DECLARE_TRACED_ENUM(States,
01086 NotStarted,
01087 Trying,
01088 Proceeding,
01089 Cancelling,
01090 Completed,
01091 Terminated_Success,
01092 Terminated_Timeout,
01093 Terminated_RetriesExceeded,
01094 Terminated_TransportError,
01095 Terminated_Cancelled,
01096 Terminated_Aborted
01097 );
01098 virtual void SetTerminated(States newState);
01099
01100 SIPTransactionOwner * m_owner;
01101 bool m_deleteOwner;
01102
01103 PTimeInterval m_retryTimeoutMin;
01104 PTimeInterval m_retryTimeoutMax;
01105
01106 States m_state;
01107 unsigned m_retry;
01108 PoolTimer m_retryTimer;
01109 PoolTimer m_completionTimer;
01110 PSyncPoint m_completed;
01111 bool m_pduSizeOK;
01112 PString m_localInterface;
01113
01114 friend class SIPConnection;
01115 };
01116
01117
01118 #define OPAL_PROXY_PARAM "OPAL-proxy"
01119 #define OPAL_LOCAL_ID_PARAM "OPAL-local-id"
01120 #define OPAL_INTERFACE_PARAM "OPAL-interface"
01121
01122
01124
01125
01128 class SIPResponse : public SIPTransaction
01129 {
01130 PCLASSINFO(SIPResponse, SIPTransaction);
01131 public:
01132 SIPResponse(
01133 SIPEndPoint & endpoint,
01134 const SIP_PDU & command,
01135 StatusCodes code
01136 );
01137
01138 virtual SIPTransaction * CreateDuplicate() const;
01139
01140 bool Resend(SIP_PDU & command);
01141 };
01142
01143
01145
01146
01152 class SIPInvite : public SIPTransaction
01153 {
01154 PCLASSINFO(SIPInvite, SIPTransaction);
01155 public:
01156 SIPInvite(
01157 SIPConnection & connection,
01158 OpalTransport * transport = NULL
01159 );
01160
01161 virtual SIPTransaction * CreateDuplicate() const;
01162
01163 virtual PBoolean OnReceivedResponse(SIP_PDU & response);
01164
01165 mutable OpalRTPConnection::SessionMap m_sessions;
01166 };
01167
01168
01170
01171
01172
01173
01174 class SIPAck : public SIP_PDU
01175 {
01176 PCLASSINFO(SIPAck, SIP_PDU);
01177 public:
01178 SIPAck(
01179 const SIPTransaction & invite,
01180 const SIP_PDU & response
01181 );
01182
01183 virtual SIPTransaction * CreateDuplicate() const;
01184 };
01185
01186
01188
01189
01190
01191 class SIPBye : public SIPTransaction
01192 {
01193 PCLASSINFO(SIPBye, SIPTransaction);
01194 public:
01195 SIPBye(
01196 SIPEndPoint & endpoint,
01197 SIPDialogContext & dialog
01198 );
01199 SIPBye(
01200 SIPConnection & conn
01201 );
01202
01203 virtual SIPTransaction * CreateDuplicate() const;
01204 };
01205
01206
01208
01209 class SIPRegister : public SIPTransaction
01210 {
01211 PCLASSINFO(SIPRegister, SIPTransaction);
01212 public:
01213 P_DECLARE_TRACED_ENUM(CompatibilityModes,
01214 e_FullyCompliant,
01217 e_CannotRegisterMultipleContacts,
01221 e_CannotRegisterPrivateContacts,
01225 e_HasApplicationLayerGateway,
01229 e_RFC5626
01232 );
01233
01235 struct Params : public SIPParameters {
01236 Params()
01237 : m_registrarAddress(m_remoteAddress)
01238 , m_compatibility(SIPRegister::e_FullyCompliant)
01239 , m_instanceId(NULL)
01240 { }
01241
01242 Params(const Params & param)
01243 : SIPParameters(param)
01244 , m_registrarAddress(m_remoteAddress)
01245 , m_compatibility(param.m_compatibility)
01246 , m_instanceId(param.m_instanceId)
01247 { }
01248
01249 PCaselessString & m_registrarAddress;
01250 CompatibilityModes m_compatibility;
01251 PGloballyUniqueID m_instanceId;
01252 };
01253
01254 SIPRegister(
01255 SIPTransactionOwner & owner,
01256 OpalTransport & transport,
01257 const PString & callId,
01258 unsigned cseq,
01259 const Params & params
01260 );
01261
01262 virtual SIPTransaction * CreateDuplicate() const;
01263 };
01264
01265
01266 #if PTRACING
01267 ostream & operator<<(ostream & strm, SIPRegister::CompatibilityModes mode);
01268 ostream & operator<<(ostream & strm, const SIPRegister::Params & params);
01269 #endif
01270
01271
01273
01274 class SIPSubscribe : public SIPTransaction
01275 {
01276 PCLASSINFO(SIPSubscribe, SIPTransaction);
01277 public:
01280 enum PredefinedPackages {
01281 MessageSummary,
01282 Presence,
01283 Dialog,
01284 Reg,
01285 Conference,
01286
01287 NumPredefinedPackages,
01288
01289 Watcher = 0x8000,
01290
01291 MessageSummaryWatcher = Watcher|MessageSummary,
01292 PresenceWatcher = Watcher|Presence,
01293 DialogWatcher = Watcher|Dialog,
01294
01295 PackageMask = Watcher-1
01296 };
01297 friend PredefinedPackages operator|(PredefinedPackages p1, PredefinedPackages p2) { return (PredefinedPackages)((int)p1|(int)p2); }
01298
01299 class EventPackage : public PCaselessString
01300 {
01301 PCLASSINFO(EventPackage, PCaselessString);
01302 public:
01303 EventPackage(PredefinedPackages = NumPredefinedPackages);
01304 explicit EventPackage(const PString & str) : PCaselessString(str) { }
01305 explicit EventPackage(const char * str) : PCaselessString(str) { }
01306
01307 EventPackage & operator=(PredefinedPackages pkg);
01308 EventPackage & operator=(const PString & str) { PCaselessString::operator=(str); return *this; }
01309 EventPackage & operator=(const char * str) { PCaselessString::operator=(str); return *this; }
01310
01311 bool operator==(PredefinedPackages pkg) const { return Compare(EventPackage(pkg)) == EqualTo; }
01312 bool operator==(const PString & str) const { return Compare(str) == EqualTo; }
01313 bool operator==(const char * cstr) const { return InternalCompare(0, P_MAX_INDEX, cstr) == EqualTo; }
01314 virtual Comparison InternalCompare(PINDEX offset, PINDEX length, const char * cstr) const;
01315
01316 bool IsWatcher() const;
01317 };
01318
01320 struct SubscriptionStatus {
01321 SIPSubscribeHandler * m_handler;
01322 PString m_addressofRecord;
01323 bool m_wasSubscribing;
01324 bool m_reSubscribing;
01325 SIP_PDU::StatusCodes m_reason;
01326 OpalProductInfo m_productInfo;
01327 void * m_userData;
01328 };
01329
01330 struct NotifyCallbackInfo {
01331 NotifyCallbackInfo(
01332 SIPSubscribeHandler & handler,
01333 SIPEndPoint & ep,
01334 SIP_PDU & request,
01335 SIP_PDU & response
01336 );
01337
01338 #if P_EXPAT
01339 bool LoadAndValidate(
01340 PXML & xml,
01341 const PXML::ValidationInfo * validator,
01342 PXML::Options options = PXML::WithNS
01343 );
01344 #endif
01345
01346 bool SendResponse(
01347 SIP_PDU::StatusCodes status = SIP_PDU::Successful_OK,
01348 const char * extra = NULL
01349 );
01350
01351 SIPSubscribeHandler & m_handler;
01352 SIPEndPoint & m_endpoint;
01353 SIP_PDU & m_request;
01354 SIP_PDU & m_response;
01355 bool m_sendResponse;
01356 };
01357
01358 struct Params : public SIPParameters
01359 {
01360 Params(PredefinedPackages pkg = NumPredefinedPackages)
01361 : m_agentAddress(m_remoteAddress)
01362 , m_eventPackage(pkg)
01363 , m_eventList(false)
01364 { }
01365
01366 Params(const Params & param)
01367 : SIPParameters(param)
01368 , m_agentAddress(m_remoteAddress)
01369 , m_eventPackage(param.m_eventPackage)
01370 , m_eventList(param.m_eventList)
01371 , m_contentType(param.m_contentType)
01372 , m_onSubcribeStatus(param.m_onSubcribeStatus)
01373 , m_onNotify(param.m_onNotify)
01374 { }
01375
01376 PCaselessString & m_agentAddress;
01377 EventPackage m_eventPackage;
01378 bool m_eventList;
01379 PCaselessString m_contentType;
01380
01381 PNotifierTemplate<const SubscriptionStatus &> m_onSubcribeStatus;
01382 PNotifierTemplate<NotifyCallbackInfo &> m_onNotify;
01383 };
01384
01385 SIPSubscribe(
01386 SIPTransactionOwner & owner,
01387 OpalTransport & transport,
01388 SIPDialogContext & dialog,
01389 const Params & params
01390 );
01391
01392 virtual SIPTransaction * CreateDuplicate() const;
01393 };
01394
01395
01396 #if PTRACING
01397 ostream & operator<<(ostream & strm, const SIPSubscribe::Params & params);
01398 #endif
01399
01400
01401 typedef SIPSubscribe::EventPackage SIPEventPackage;
01402
01403
01405
01406 class SIPHandler;
01407
01408 class SIPEventPackageHandler : public PObject
01409 {
01410 unsigned m_expectedSequenceNumber;
01411
01412 public:
01413 SIPEventPackageHandler() : m_expectedSequenceNumber(UINT_MAX) { }
01414
01415 virtual ~SIPEventPackageHandler() { }
01416 virtual PCaselessString GetContentType() const = 0;
01417 virtual bool ValidateContentType(const PString & type, const SIPMIMEInfo & mime);
01418 virtual bool ValidateNotificationSequence(SIPSubscribeHandler & handler, unsigned newSequenceNumber, bool fullUpdate);
01419 virtual void OnReceivedNOTIFY(SIPSubscribe::NotifyCallbackInfo & notifyInfo) = 0;
01420 virtual PString OnSendNOTIFY(SIPHandler & , const PObject * ) { return PString::Empty(); }
01421
01422 P_REMOVE_VIRTUAL(bool, OnReceivedNOTIFY(SIPHandler &, SIP_PDU &), false);
01423 };
01424
01425
01426 typedef PFactory<SIPEventPackageHandler, SIPEventPackage> SIPEventPackageFactory;
01427
01428
01430
01431 class SIPNotify : public SIPTransaction
01432 {
01433 PCLASSINFO(SIPNotify, SIPTransaction);
01434 public:
01435 SIPNotify(
01436 SIPTransactionOwner & owner,
01437 OpalTransport & transport,
01438 SIPDialogContext & dialog,
01439 const SIPEventPackage & eventPackage,
01440 const PString & state,
01441 const PString & body
01442 );
01443
01444 virtual SIPTransaction * CreateDuplicate() const;
01445 };
01446
01447
01449
01450 class SIPPublish : public SIPTransaction
01451 {
01452 PCLASSINFO(SIPPublish, SIPTransaction);
01453 public:
01454 SIPPublish(
01455 SIPTransactionOwner & owner,
01456 OpalTransport & transport,
01457 const PString & id,
01458 const PString & sipIfMatch,
01459 const SIPSubscribe::Params & params,
01460 const PString & body
01461 );
01462
01463 virtual SIPTransaction * CreateDuplicate() const;
01464 };
01465
01466
01468
01469 class SIPRefer : public SIPTransaction
01470 {
01471 PCLASSINFO(SIPRefer, SIPTransaction);
01472 public:
01473 SIPRefer(
01474 SIPConnection & connection,
01475 const SIPURL & referTo,
01476 const SIPURL & referred_by,
01477 bool referSub
01478 );
01479
01480 virtual SIPTransaction * CreateDuplicate() const;
01481 };
01482
01483
01485
01486
01487
01488
01489 class SIPReferNotify : public SIPTransaction
01490 {
01491 PCLASSINFO(SIPReferNotify, SIPTransaction);
01492 public:
01493 SIPReferNotify(
01494 SIPConnection & connection,
01495 StatusCodes code
01496 );
01497
01498 virtual SIPTransaction * CreateDuplicate() const;
01499 };
01500
01501
01503
01504
01505
01506 class SIPMessage : public SIPTransaction
01507 {
01508 PCLASSINFO(SIPMessage, SIPTransaction);
01509 public:
01510 struct Params : public SIPParameters
01511 {
01512 Params()
01513 : m_contentType("text/plain;charset=UTF-8")
01514 {
01515 m_expire = 3600;
01516 }
01517
01518 PCaselessString m_contentType;
01519 PString m_id;
01520 PString m_body;
01521 PAtomicInteger::IntegerType m_messageId;
01522 };
01523
01524 SIPMessage(
01525 SIPTransactionOwner & owner,
01526 OpalTransport & transport,
01527 const Params & params
01528 );
01529 SIPMessage(
01530 SIPConnection & connection,
01531 const Params & params
01532 );
01533
01534 virtual SIPTransaction * CreateDuplicate() const;
01535
01536 const Params & GetParameters() const { return m_parameters; }
01537 const SIPURL & GetLocalAddress() const { return m_localAddress; }
01538
01539 private:
01540 void Construct(const Params & params);
01541
01542 Params m_parameters;
01543 SIPURL m_localAddress;
01544 };
01545
01546
01548
01549
01550
01551 class SIPOptions : public SIPTransaction
01552 {
01553 PCLASSINFO(SIPOptions, SIPTransaction);
01554
01555 public:
01556 struct Params : public SIPParameters
01557 {
01558 Params()
01559 : m_acceptContent("application/sdp, application/media_control+xml, application/dtmf, application/dtmf-relay")
01560 {
01561 }
01562
01563 PCaselessString m_acceptContent;
01564 PCaselessString m_contentType;
01565 PString m_body;
01566 };
01567
01568 SIPOptions(
01569 SIPEndPoint & endpoint,
01570 const Params & params
01571 );
01572 SIPOptions(
01573 SIPConnection & conn,
01574 const Params & params
01575 );
01576
01577 virtual SIPTransaction * CreateDuplicate() const;
01578
01579 protected:
01580 void Construct(const Params & params);
01581 };
01582
01583
01585
01586
01587
01588 class SIPInfo : public SIPTransaction
01589 {
01590 PCLASSINFO(SIPInfo, SIPTransaction);
01591
01592 public:
01593 struct Params
01594 {
01595 Params(const PString & contentType = PString::Empty(),
01596 const PString & body = PString::Empty())
01597 : m_contentType(contentType)
01598 , m_body(body)
01599 {
01600 }
01601
01602 PCaselessString m_contentType;
01603 PString m_body;
01604 };
01605
01606 SIPInfo(
01607 SIPConnection & conn,
01608 const Params & params
01609 );
01610
01611 virtual SIPTransaction * CreateDuplicate() const;
01612 };
01613
01614
01616
01617
01618
01619 class SIPPing : public SIPTransaction
01620 {
01621 PCLASSINFO(SIPPing, SIPTransaction);
01622
01623 public:
01624 SIPPing(
01625 SIPTransactionOwner & owner,
01626 OpalTransport & transport,
01627 const SIPURL & address
01628 );
01629
01630 virtual SIPTransaction * CreateDuplicate() const;
01631 };
01632
01633
01635
01636
01637
01638 class SIPPrack : public SIPTransaction
01639 {
01640 PCLASSINFO(SIPPrack, SIPTransaction);
01641
01642 public:
01643 SIPPrack(
01644 SIPConnection & conn,
01645 OpalTransport & transport,
01646 const PString & rack
01647 );
01648
01649 virtual SIPTransaction * CreateDuplicate() const;
01650 };
01651
01652
01653 #endif // OPAL_SIP
01654
01655 #endif // OPAL_SIP_SIPPDU_H
01656
01657
01658