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