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
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 #ifndef __OPAL_SIPPDU_H
00164 #define __OPAL_SIPPDU_H
00165
00166 #ifdef P_USE_PRAGMA
00167 #pragma interface
00168 #endif
00169
00170
00171 #include <ptclib/mime.h>
00172 #include <ptclib/url.h>
00173 #include <sip/sdp.h>
00174
00175
00176 class OpalTransport;
00177 class OpalTransportAddress;
00178
00179 class SIPEndPoint;
00180 class SIPConnection;
00181 class SIP_PDU;
00182
00183
00185
00186
00192 class SIPURL : public PURL
00193 {
00194 PCLASSINFO(SIPURL, PURL);
00195 public:
00196 SIPURL();
00197
00200 SIPURL(
00201 const char * cstr,
00202 const char * defaultScheme = NULL
00203 );
00204
00207 SIPURL(
00208 const PString & str,
00209 const char * defaultScheme = NULL
00210 );
00211
00219 SIPURL(
00220 const PString & name,
00221 const OpalTransportAddress & address,
00222 WORD listenerPort = 0
00223 );
00224
00228 PString AsQuotedString() const;
00229
00232 PString GetDisplayName() const;
00233
00234 void SetDisplayName(const PString & str)
00235 { displayName = str; }
00236
00237 OpalTransportAddress GetHostAddress() const;
00238
00242 void AdjustForRequestURI();
00243
00244 protected:
00263 virtual BOOL InternalParse(
00264 const char * cstr,
00265 const char * defaultScheme
00266 );
00267
00268 PString displayName;
00269 };
00270
00271
00273
00274
00305 class SIPMIMEInfo : public PMIMEInfo
00306 {
00307 PCLASSINFO(SIPMIMEInfo, PMIMEInfo);
00308 public:
00309 SIPMIMEInfo(BOOL compactForm = FALSE);
00310
00311 void SetForm(BOOL v) { compactForm = v; }
00312
00313 PString GetContentType() const;
00314 void SetContentType(const PString & v);
00315
00316 PString GetContentEncoding() const;
00317 void SetContentEncoding(const PString & v);
00318
00319 PString GetFrom() const;
00320 void SetFrom(const PString & v);
00321
00322 PString GetAccept() const;
00323 void SetAccept(const PString & v);
00324
00325 PString GetAcceptEncoding() const;
00326 void SetAcceptEncoding(const PString & v);
00327
00328 PString GetAcceptLanguage() const;
00329 void SetAcceptLanguage(const PString & v);
00330
00331 PString GetAllow() const;
00332 void SetAllow(const PString & v);
00333
00334 PString GetCallID() const;
00335 void SetCallID(const PString & v);
00336
00337 PString GetContact() const;
00338 void SetContact(const PString & v);
00339 void SetContact(const SIPURL & url);
00340
00341 PString GetSubject() const;
00342 void SetSubject(const PString & v);
00343
00344 PString GetTo() const;
00345 void SetTo(const PString & v);
00346
00347 PString GetVia() const;
00348 void SetVia(const PString & v);
00349
00350 PStringList GetViaList() const;
00351 void SetViaList(const PStringList & v);
00352
00353 PString GetReferTo() const;
00354 void SetReferTo(const PString & r);
00355
00356 PINDEX GetContentLength() const;
00357 void SetContentLength(PINDEX v);
00358 BOOL IsContentLengthPresent() const;
00359
00360 PString GetCSeq() const;
00361 void SetCSeq(const PString & v);
00362
00363 PString GetDate() const;
00364 void SetDate(const PString & v);
00365 void SetDate(const PTime & t);
00366 void SetDate(void);
00367
00368 unsigned GetExpires(unsigned dflt = UINT_MAX) const;
00369 void SetExpires(unsigned v);
00370
00371 PINDEX GetMaxForwards() const;
00372 void SetMaxForwards(PINDEX v);
00373
00374 PINDEX GetMinExpires() const;
00375 void SetMinExpires(PINDEX v);
00376
00377 PString GetProxyAuthenticate() const;
00378 void SetProxyAuthenticate(const PString & v);
00379
00380 PStringList GetRoute() const;
00381 void SetRoute(const PStringList & v);
00382
00383 PStringList GetRecordRoute() const;
00384 void SetRecordRoute(const PStringList & v);
00385
00386 unsigned GetCSeqIndex() const { return GetCSeq().AsUnsigned(); }
00387
00388 PString GetSupported() const;
00389 void SetSupported(const PString & v);
00390
00391 PString GetUnsupported() const;
00392 void SetUnsupported(const PString & v);
00393
00394 PString GetEvent() const;
00395 void SetEvent(const PString & v);
00396
00397 PString GetSubscriptionState() const;
00398 void SetSubscriptionState(const PString & v);
00399
00400 PString GetUserAgent() const;
00401 void SetUserAgent(const SIPEndPoint & sipep);
00402
00403 PString GetWWWAuthenticate() const;
00404 void SetWWWAuthenticate(const PString & v);
00405
00406
00409 PString GetFieldParameter(const PString &,
00410 const PString &);
00411
00416 void SetFieldParameter(const PString &,
00417 PString &,
00418 const PString &);
00419
00422 BOOL HasFieldParameter(const PString &,
00423 const PString &);
00424
00425 protected:
00428 PStringList GetRouteList(const char * name) const;
00429
00433 void SetRouteList(const char * name, const PStringList & v);
00434
00437 PString GetFullOrCompact(const char * fullForm, char compactForm) const;
00438
00440 BOOL compactForm;
00441 };
00442
00443
00445
00446
00447 class SIPAuthentication : public PObject
00448 {
00449 PCLASSINFO(SIPAuthentication, PObject);
00450 public:
00451 SIPAuthentication(
00452 const PString & username = PString::Empty(),
00453 const PString & password = PString::Empty()
00454 );
00455
00456 BOOL Parse(
00457 const PCaselessString & auth,
00458 BOOL proxy
00459 );
00460
00461 BOOL IsValid() const;
00462
00463 BOOL Authorise(
00464 SIP_PDU & pdu
00465 ) const;
00466
00467 enum Algorithm {
00468 Algorithm_MD5,
00469 NumAlgorithms
00470 };
00471
00472 BOOL IsProxy() const { return isProxy; }
00473 const PString & GetAuthRealm() const { return authRealm; }
00474 const PString & GetUsername() const { return username; }
00475 const PString & GetPassword() const { return password; }
00476 const PString & GetNonce() const { return nonce; }
00477 Algorithm GetAlgorithm() const { return algorithm; }
00478 const PString & GetOpaque() const { return opaque; }
00479
00480 void SetUsername(const PString & user) { username = user; }
00481 void SetPassword(const PString & pass) { password = pass; }
00482 void SetAuthRealm(const PString & r) { authRealm = r; }
00483
00484 protected:
00485 BOOL isProxy;
00486 PString authRealm;
00487 PString username;
00488 PString password;
00489 PString nonce;
00490 Algorithm algorithm;
00491 PString opaque;
00492
00493 BOOL qopAuth;
00494 BOOL qopAuthInt;
00495 PString cnonce;
00496 mutable PAtomicInteger nonceCount;
00497 };
00498
00499
00501
00502
00508 class SIP_PDU : public PObject
00509 {
00510 PCLASSINFO(SIP_PDU, PObject);
00511 public:
00512 enum Methods {
00513 Method_INVITE,
00514 Method_ACK,
00515 Method_OPTIONS,
00516 Method_BYE,
00517 Method_CANCEL,
00518 Method_REGISTER,
00519 Method_SUBSCRIBE,
00520 Method_NOTIFY,
00521 Method_REFER,
00522 Method_MESSAGE,
00523 NumMethods
00524 };
00525
00526 enum StatusCodes {
00527 IllegalStatusCode,
00528
00529 Information_Trying = 100,
00530 Information_Ringing = 180,
00531 Information_CallForwarded = 181,
00532 Information_Queued = 182,
00533 Information_Session_Progress = 183,
00534
00535 Successful_OK = 200,
00536 Successful_Accepted = 202,
00537
00538 Redirection_MultipleChoices = 300,
00539 Redirection_MovedPermanently = 301,
00540 Redirection_MovedTemporarily = 302,
00541 Redirection_UseProxy = 305,
00542 Redirection_AlternativeService = 380,
00543
00544 Failure_BadRequest = 400,
00545 Failure_UnAuthorised = 401,
00546 Failure_PaymentRequired = 402,
00547 Failure_Forbidden = 403,
00548 Failure_NotFound = 404,
00549 Failure_MethodNotAllowed = 405,
00550 Failure_NotAcceptable = 406,
00551 Failure_ProxyAuthenticationRequired = 407,
00552 Failure_RequestTimeout = 408,
00553 Failure_Conflict = 409,
00554 Failure_Gone = 410,
00555 Failure_LengthRequired = 411,
00556 Failure_RequestEntityTooLarge = 413,
00557 Failure_RequestURITooLong = 414,
00558 Failure_UnsupportedMediaType = 415,
00559 Failure_UnsupportedURIScheme = 416,
00560 Failure_BadExtension = 420,
00561 Failure_ExtensionRequired = 421,
00562 Failure_IntervalTooBrief = 423,
00563 Failure_TemporarilyUnavailable = 480,
00564 Failure_TransactionDoesNotExist = 481,
00565 Failure_LoopDetected = 482,
00566 Failure_TooManyHops = 483,
00567 Failure_AddressIncomplete = 484,
00568 Failure_Ambiguous = 485,
00569 Failure_BusyHere = 486,
00570 Failure_RequestTerminated = 487,
00571 Failure_NotAcceptableHere = 488,
00572 Failure_BadEvent = 489,
00573 Failure_RequestPending = 491,
00574 Failure_Undecipherable = 493,
00575
00576 Failure_InternalServerError = 500,
00577 Failure_NotImplemented = 501,
00578 Failure_BadGateway = 502,
00579 Failure_ServiceUnavailable = 503,
00580 Failure_ServerTimeout = 504,
00581 Failure_SIPVersionNotSupported = 505,
00582 Failure_MessageTooLarge = 513,
00583
00584 GlobalFailure_BusyEverywhere = 600,
00585 GlobalFailure_Decline = 603,
00586 GlobalFailure_DoesNotExistAnywhere = 604,
00587 GlobalFailure_NotAcceptable = 606,
00588
00589 MaxStatusCode = 699
00590 };
00591
00592 static const char * GetStatusCodeDescription (int code);
00593
00594 enum {
00595 MaxSize = 65535
00596 };
00597
00598 SIP_PDU();
00599
00602 SIP_PDU(
00603 Methods method,
00604 const SIPURL & dest,
00605 const PString & to,
00606 const PString & from,
00607 const PString & callID,
00608 unsigned cseq,
00609 const OpalTransportAddress & via
00610 );
00613 SIP_PDU(
00614 Methods method,
00615 SIPConnection & connection,
00616 const OpalTransport & transport
00617 );
00618
00622 SIP_PDU(
00623 const SIP_PDU & request,
00624 StatusCodes code,
00625 const char * contact = NULL,
00626 const char * extra = NULL
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 Construct(
00637 Methods method
00638 );
00639 void Construct(
00640 Methods method,
00641 const SIPURL & dest,
00642 const PString & to,
00643 const PString & from,
00644 const PString & callID,
00645 unsigned cseq,
00646 const OpalTransportAddress & via
00647 );
00648 void Construct(
00649 Methods method,
00650 SIPConnection & connection,
00651 const OpalTransport & transport
00652 );
00653
00658 BOOL SetRoute(SIPConnection & connection);
00659
00662 void SetAllow(void);
00663
00666 void AdjustVia(OpalTransport & transport);
00667
00671 OpalTransportAddress GetViaAddress(OpalEndPoint &);
00672
00676 OpalTransportAddress GetSendAddress(SIPConnection &);
00677
00680 BOOL Read(
00681 OpalTransport & transport
00682 );
00683
00686 BOOL Write(
00687 OpalTransport & transport
00688 );
00689
00690 PString GetTransactionID() const;
00691
00692 Methods GetMethod() const { return method; }
00693 StatusCodes GetStatusCode () const { return statusCode; }
00694 const SIPURL & GetURI() const { return uri; }
00695 unsigned GetVersionMajor() const { return versionMajor; }
00696 unsigned GetVersionMinor() const { return versionMinor; }
00697 const PString & GetEntityBody() const { return entityBody; }
00698 const PString & GetInfo() const { return info; }
00699 const SIPMIMEInfo & GetMIME() const { return mime; }
00700 SIPMIMEInfo & GetMIME() { return mime; }
00701 BOOL HasSDP() const { return sdp != NULL; }
00702 SDPSessionDescription & GetSDP() const { return *PAssertNULL(sdp); }
00703 void SetSDP(SDPSessionDescription * s) { sdp = s; }
00704 void SetSDP(const SDPSessionDescription & s) { sdp = new SDPSessionDescription(s); }
00705
00706 protected:
00707
00708 Methods method;
00709 StatusCodes statusCode;
00710 SIPURL uri;
00711 unsigned versionMajor;
00712 unsigned versionMinor;
00713 PString info;
00714 SIPMIMEInfo mime;
00715 PString entityBody;
00716
00717 SDPSessionDescription * sdp;
00718 };
00719
00720
00721 PQUEUE(SIP_PDU_Queue, SIP_PDU);
00722
00723
00725
00726
00737 class SIPTransaction : public SIP_PDU
00738 {
00739 PCLASSINFO(SIPTransaction, SIP_PDU);
00740 public:
00741 SIPTransaction(
00742 SIPEndPoint & endpoint,
00743 OpalTransport & transport
00744 );
00748 SIPTransaction(
00749 SIPConnection & connection,
00750 OpalTransport & transport,
00751 Methods method = NumMethods
00752 );
00753 ~SIPTransaction();
00754
00755 BOOL Start();
00756 BOOL IsInProgress() const { return state == Trying && state == Proceeding; }
00757 BOOL IsFailed() const { return state > Terminated_Success; }
00758 BOOL IsFinished() { return finished.Wait(0); }
00759 void Wait();
00760 BOOL SendCANCEL();
00761
00762 virtual BOOL OnReceivedResponse(SIP_PDU & response);
00763 virtual BOOL OnCompleted(SIP_PDU & response);
00764
00765 OpalTransport & GetTransport() const { return transport; }
00766 SIPConnection * GetConnection() const { return connection; }
00767
00768 const OpalTransportAddress & GetLocalAddress() const { return localAddress; }
00769
00770 protected:
00771 void Construct();
00772 BOOL ResendCANCEL();
00773
00774 PDECLARE_NOTIFIER(PTimer, SIPTransaction, OnRetry);
00775 PDECLARE_NOTIFIER(PTimer, SIPTransaction, OnTimeout);
00776
00777 enum States {
00778 NotStarted,
00779 Trying,
00780 Proceeding,
00781 Cancelling,
00782 Completed,
00783 Terminated_Success,
00784 Terminated_Timeout,
00785 Terminated_RetriesExceeded,
00786 Terminated_TransportError,
00787 Terminated_Cancelled,
00788 NumStates
00789 };
00790 void SetTerminated(States newState);
00791
00792 SIPEndPoint & endpoint;
00793 OpalTransport & transport;
00794 SIPConnection * connection;
00795
00796 States state;
00797 unsigned retry;
00798 PTimer retryTimer;
00799 PTimer completionTimer;
00800
00801 PSyncPoint finished;
00802 PTimedMutex mutex;
00803
00804 OpalTransportAddress localAddress;
00805 };
00806
00807
00808 PLIST(SIPTransactionList, SIPTransaction);
00809 PDICTIONARY(SIPTransactionDict, PString, SIPTransaction);
00810
00811
00813
00814
00820 class SIPInvite : public SIPTransaction
00821 {
00822 PCLASSINFO(SIPInvite, SIPTransaction);
00823 public:
00824 SIPInvite(
00825 SIPConnection & connection,
00826 OpalTransport & transport
00827 );
00828 SIPInvite(
00829 SIPConnection & connection,
00830 OpalTransport & transport,
00831 RTP_SessionManager & sm
00832 );
00833
00834 virtual BOOL OnReceivedResponse(SIP_PDU & response);
00835
00836 RTP_SessionManager & GetSessionManager() { return rtpSessions; }
00837
00838 protected:
00839 RTP_SessionManager rtpSessions;
00840 };
00841
00842
00844
00845 class SIPRegister : public SIPTransaction
00846 {
00847 PCLASSINFO(SIPRegister, SIPTransaction);
00848 public:
00849 SIPRegister(
00850 SIPEndPoint & endpoint,
00851 OpalTransport & transport,
00852 const SIPURL & address,
00853 const PString & id,
00854 unsigned expires
00855 );
00856 };
00857
00858
00860
00861 class SIPMWISubscribe : public SIPTransaction
00862 {
00863 PCLASSINFO(SIPMWISubscribe, SIPTransaction);
00864 public:
00867 enum MWIType {
00868
00869 VoiceMessage,
00870 FaxMessage,
00871 PagerMessage,
00872 MultimediaMessage,
00873 TextMessage,
00874 None
00875 };
00876
00877 SIPMWISubscribe(
00878 SIPEndPoint & endpoint,
00879 OpalTransport & transport,
00880 const SIPURL & address,
00881 const PString & id,
00882 unsigned expires
00883 );
00884 };
00885
00886
00888
00889 class SIPRefer : public SIPTransaction
00890 {
00891 PCLASSINFO(SIPRefer, SIPTransaction);
00892 public:
00893 SIPRefer(
00894 SIPConnection & connection,
00895 OpalTransport & transport,
00896 const PString & refer
00897 );
00898 };
00899
00900
00902
00903
00904
00905
00906 class SIPReferNotify : public SIPTransaction
00907 {
00908 PCLASSINFO(SIPReferNotify, SIPTransaction);
00909 public:
00910 SIPReferNotify(
00911 SIPConnection & connection,
00912 OpalTransport & transport,
00913 StatusCodes code
00914 );
00915 };
00916
00917
00919
00920
00921
00922 class SIPMessage : public SIPTransaction
00923 {
00924 PCLASSINFO(SIPMessage, SIPTransaction);
00925
00926 public:
00927 SIPMessage(
00928 SIPEndPoint & ep,
00929 OpalTransport & trans,
00930 const SIPURL & address,
00931 const PString & body
00932 );
00933 };
00934
00935
00937
00938
00939
00940
00941 class SIPAck : public SIP_PDU
00942 {
00943 PCLASSINFO(SIPAck, SIP_PDU);
00944 public:
00945
00946 SIPAck(
00947 SIPEndPoint & ep,
00948 SIPTransaction & invite,
00949 SIP_PDU & response);
00950
00951
00952 SIPAck(
00953 SIPTransaction & invite);
00954
00955 protected:
00956 void Construct();
00957
00958 SIPTransaction & transaction;
00959 };
00960
00961
00963
00964
00965
00966 class SIPOptions : public SIPTransaction
00967 {
00968 PCLASSINFO(SIPOptions, SIPTransaction);
00969
00970 public:
00971 SIPOptions(
00972 SIPEndPoint & ep,
00973 OpalTransport & trans,
00974 const SIPURL & address
00975 );
00976 };
00977
00978
00979 #endif // __OPAL_SIPPDU_H
00980
00981
00982