OPAL Version 3.10.4

- Main Page
- Related Pages
- Namespaces
- Data Structures
- Files

- File List
- Globals

sippdu.h
Go to the documentation of this file.
1 /*
2 * sippdu.h
3 *
4 * Session Initiation Protocol PDU support.
5 *
6 * Open Phone Abstraction Library (OPAL)
7 * Formally known as the Open H323 project.
8 *
9 * Copyright (c) 2002 Equivalence Pty. Ltd.
10 *
11 * The contents of this file are subject to the Mozilla Public License
12 * Version 1.0 (the "License"); you may not use this file except in
13 * compliance with the License. You may obtain a copy of the License at
14 * http://www.mozilla.org/MPL/
15 *
16 * Software distributed under the License is distributed on an "AS IS"
17 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
18 * the License for the specific language governing rights and limitations
19 * under the License.
20 *
21 * The Original Code is Open Phone Abstraction Library.
22 *
23 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
24 *
25 * Contributor(s): ______________________________________.
26 *
27 * $Revision: 26937 $
28 * $Author: rjongbloed $
29 * $Date: 2012-02-06 19:54:19 -0600 (Mon, 06 Feb 2012) $
30 */
31
32 #ifndef OPAL_SIP_SIPPDU_H
33 #define OPAL_SIP_SIPPDU_H
34
35 #ifdef P_USE_PRAGMA
36 #pragma interface
37 #endif
38
39 #include <opal/buildopts.h>
40
41 #if OPAL_SIP
42
43 #include <ptclib/mime.h>
44 #include <ptclib/url.h>
45 #include <ptclib/http.h>
46 #include <sip/sdp.h>
47 #include <opal/rtpconn.h>
48
49
50 class OpalTransport;
51 class OpalTransportAddress;
52 class OpalProductInfo;
53
54 class SIPEndPoint;
55 class SIPConnection;
56 class SIP_PDU;
57 class SIPSubscribeHandler;
58 class SIPDialogContext;
59 class SIPMIMEInfo;
60
61
63 // SIPURL
64
70 class SIPURL : public PURL
71 {
72 PCLASSINFO(SIPURL, PURL);
73 public:
74 SIPURL();
75
76 SIPURL(
77 const PURL & url
78 ) : PURL(url) { }
79 SIPURL & operator=(
80 const PURL & url
81 ) { PURL::operator=(url); return *this; }
82
85 SIPURL(
86 const char * cstr,
87 const char * defaultScheme = NULL
88 );
89 SIPURL & operator=(
90 const char * cstr
91 ) { Parse(cstr); return *this; }
92
95 SIPURL(
96 const PString & str,
97 const char * defaultScheme = NULL
98 );
99 SIPURL & operator=(
100 const PString & str
101 ) { Parse(str); return *this; }
102
112 SIPURL(
113 const PString & name,
114 const OpalTransportAddress & address,
115 WORD listenerPort = 0
116 );
117
118 SIPURL(
119 const OpalTransportAddress & address,
120 WORD listenerPort = 0
121 );
122 SIPURL & operator=(
123 const OpalTransportAddress & address
124 );
125
126 SIPURL(
127 const SIPMIMEInfo & mime,
128 const char * name
129 );
130
139 virtual Comparison Compare(
140 const PObject & obj
141 ) const;
142
146 PString AsQuotedString() const;
147
150 PString GetDisplayName(PBoolean useDefault = true) const;
151
152 void SetDisplayName(const PString & str)
153 {
154 m_displayName = str;
155 }
156
158 const PStringOptions & GetFieldParameters() const { return m_fieldParameters; }
159 PStringOptions & GetFieldParameters() { return m_fieldParameters; }
160
163 OpalTransportAddress GetHostAddress() const;
164
167 void SetHostAddress(const OpalTransportAddress & addr);
168
169 enum UsageContext {
170 ExternalURI,
171 RequestURI,
172 ToURI,
173 FromURI,
174 RouteURI,
175 RedirectURI,
176 ContactURI,
177 RegContactURI,
178 RegisterURI
179 };
180
186 void Sanitise(
187 UsageContext context
188 );
189
195 PBoolean AdjustToDNS(
196 PINDEX entry = 0
197 );
198
200 static PString GenerateTag();
201
203 void SetTag(
204 const PString & tag = PString::Empty(),
205 bool force = false
206 );
207
208 protected:
209 void ParseAsAddress(const PString & name, const OpalTransportAddress & _address, WORD listenerPort = 0);
210
211 // Override from PURL()
212 virtual PBoolean InternalParse(
213 const char * cstr,
214 const char * defaultScheme
215 ) { return ReallyInternalParse(false, cstr, defaultScheme); }
216
217 bool ReallyInternalParse(
218 bool fromField,
219 const char * cstr,
220 const char * defaultScheme
221 );
222
223 PString m_displayName;
224 PStringOptions m_fieldParameters;
225 };
226
227
228 class SIPURLList : public std::list<SIPURL>
229 {
230 public:
231 bool FromString(const PString & str, bool reversed = false);
232 PString ToString() const;
233 };
234
235
236
238 // SIPMIMEInfo
239
270 class SIPMIMEInfo : public PMIMEInfo
271 {
272 PCLASSINFO(SIPMIMEInfo, PMIMEInfo);
273 public:
274 SIPMIMEInfo(bool compactForm = false);
275
276 virtual void PrintOn(ostream & strm) const;
277 virtual bool InternalAddMIME(const PString & fieldName, const PString & fieldValue);
278
279 void SetCompactForm(bool form) { compactForm = form; }
280
281 PCaselessString GetContentType(bool includeParameters = false) const;
282 void SetContentType(const PString & v);
283
284 PCaselessString GetContentEncoding() const;
285 void SetContentEncoding(const PString & v);
286
287 SIPURL GetFrom() const;
288 void SetFrom(const PString & v);
289
290 SIPURL GetPAssertedIdentity() const;
291 void SetPAssertedIdentity(const PString & v);
292
293 SIPURL GetPPreferredIdentity() const;
294 void SetPPreferredIdentity(const PString & v);
295
296 PString GetAccept() const;
297 void SetAccept(const PString & v);
298
299 PString GetAcceptEncoding() const;
300 void SetAcceptEncoding(const PString & v);
301
302 PString GetAcceptLanguage() const;
303 void SetAcceptLanguage(const PString & v);
304
305 PString GetAllow() const;
306 unsigned GetAllowBitMask() const;
307 void SetAllow(const PString & v);
308
309 PString GetCallID() const;
310 void SetCallID(const PString & v);
311
312 SIPURL GetContact() const;
313 bool GetContacts(SIPURLList & contacts) const;
314 void SetContact(const PString & v);
315
316 PString GetSubject() const;
317 void SetSubject(const PString & v);
318
319 SIPURL GetTo() const;
320 void SetTo(const PString & v);
321
322 PString GetVia() const;
323 void SetVia(const PString & v);
324
325 bool GetViaList(PStringList & v) const;
326 void SetViaList(const PStringList & v);
327
328 PString GetFirstVia() const;
329 OpalTransportAddress GetViaReceivedAddress() const;
330
331 SIPURL GetReferTo() const;
332 void SetReferTo(const PString & r);
333
334 SIPURL GetReferredBy() const;
335 void SetReferredBy(const PString & r);
336
337 PINDEX GetContentLength() const;
338 void SetContentLength(PINDEX v);
339 PBoolean IsContentLengthPresent() const;
340
341 PString GetCSeq() const;
342 void SetCSeq(const PString & v);
343
344 PString GetDate() const;
345 void SetDate(const PString & v);
346 void SetDate(const PTime & t);
347 void SetDate(void); // set to current date
348
349 unsigned GetExpires(unsigned dflt = UINT_MAX) const;// returns default value if not found
350 void SetExpires(unsigned v);
351
352 PINDEX GetMaxForwards() const;
353 void SetMaxForwards(PINDEX v);
354
355 PINDEX GetMinExpires() const;
356 void SetMinExpires(PINDEX v);
357
358 PString GetProxyAuthenticate() const;
359 void SetProxyAuthenticate(const PString & v);
360
361 PString GetRoute() const;
362 bool GetRoute(SIPURLList & proxies) const;
363 void SetRoute(const PString & v);
364 void SetRoute(const SIPURLList & proxies);
365
366 PString GetRecordRoute() const;
367 bool GetRecordRoute(SIPURLList & proxies, bool reversed) const;
368 void SetRecordRoute(const PString & v);
369 void SetRecordRoute(const SIPURLList & proxies);
370
371 unsigned GetCSeqIndex() const { return GetCSeq().AsUnsigned(); }
372
373 PStringSet GetRequire() const;
374 void SetRequire(const PStringSet & v);
375 void AddRequire(const PString & v);
376
377 PStringSet GetSupported() const;
378 void SetSupported(const PStringSet & v);
379 void AddSupported(const PString & v);
380
381 PStringSet GetUnsupported() const;
382 void SetUnsupported(const PStringSet & v);
383 void AddUnsupported(const PString & v);
384
385 PString GetEvent() const;
386 void SetEvent(const PString & v);
387
388 PCaselessString GetSubscriptionState(PStringToString & info) const;
389 void SetSubscriptionState(const PString & v);
390
391 PString GetUserAgent() const;
392 void SetUserAgent(const PString & v);
393
394 PString GetOrganization() const;
395 void SetOrganization(const PString & v);
396
397 void GetProductInfo(OpalProductInfo & info) const;
398 void SetProductInfo(const PString & ua, const OpalProductInfo & info);
399
400 PString GetWWWAuthenticate() const;
401 void SetWWWAuthenticate(const PString & v);
402
403 PString GetSIPIfMatch() const;
404 void SetSIPIfMatch(const PString & v);
405
406 PString GetSIPETag() const;
407 void SetSIPETag(const PString & v);
408
409 void GetAlertInfo(PString & info, int & appearance);
410 void SetAlertInfo(const PString & info, int appearance);
411
412 PString GetCallInfo() const;
413
414 PString GetAllowEvents() const;
415 void SetAllowEvents(const PString & v);
416
419 PString GetFieldParameter(
420 const PString & fieldName,
421 const PString & paramName,
422 const PString & defaultValue = PString::Empty()
423 ) const { return ExtractFieldParameter((*this)(fieldName), paramName, defaultValue); }
424
429 void SetFieldParameter(
430 const PString & fieldName,
431 const PString & paramName,
432 const PString & newValue
433 ) { SetAt(fieldName, InsertFieldParameter((*this)(fieldName), paramName, newValue)); }
434
437 static PString ExtractFieldParameter(
438 const PString & fieldValue,
439 const PString & paramName,
440 const PString & defaultValue = PString::Empty()
441 );
442
447 static PString InsertFieldParameter(
448 const PString & fieldValue,
449 const PString & paramName,
450 const PString & newValue
451 );
452
453 protected:
454 PStringSet GetTokenSet(const char * field) const;
455 void AddTokenSet(const char * field, const PString & token);
456 void SetTokenSet(const char * field, const PStringSet & tokens);
457
459 bool compactForm;
460 };
461
462
464 // SIPAuthentication
465
466 typedef PHTTPClientAuthentication SIPAuthentication;
467
468 class SIPAuthenticator : public PHTTPClientAuthentication::AuthObject
469 {
470 public:
471 SIPAuthenticator(SIP_PDU & pdu);
472 virtual PMIMEInfo & GetMIME();
473 virtual PString GetURI();
474 virtual PString GetEntityBody();
475 virtual PString GetMethod();
476
477 protected:
478 SIP_PDU & m_pdu;
479 };
480
481
482
484 // SIP_PDU
485
491 class SIP_PDU : public PSafeObject
492 {
493 PCLASSINFO(SIP_PDU, PSafeObject);
494 public:
495 enum Methods {
496 Method_INVITE,
497 Method_ACK,
498 Method_OPTIONS,
499 Method_BYE,
500 Method_CANCEL,
501 Method_REGISTER,
502 Method_SUBSCRIBE,
503 Method_NOTIFY,
504 Method_REFER,
505 Method_MESSAGE,
506 Method_INFO,
507 Method_PING,
508 Method_PUBLISH,
509 Method_PRACK,
510 NumMethods
511 };
512
513 enum StatusCodes {
514 IllegalStatusCode,
515 Local_TransportError,
516 Local_BadTransportAddress,
517 Local_Timeout,
518
519 Information_Trying = 100,
520 Information_Ringing = 180,
521 Information_CallForwarded = 181,
522 Information_Queued = 182,
523 Information_Session_Progress = 183,
524
525 Successful_OK = 200,
526 Successful_Accepted = 202,
527
528 Redirection_MultipleChoices = 300,
529 Redirection_MovedPermanently = 301,
530 Redirection_MovedTemporarily = 302,
531 Redirection_UseProxy = 305,
532 Redirection_AlternativeService = 380,
533
534 Failure_BadRequest = 400,
535 Failure_UnAuthorised = 401,
536 Failure_PaymentRequired = 402,
537 Failure_Forbidden = 403,
538 Failure_NotFound = 404,
539 Failure_MethodNotAllowed = 405,
540 Failure_NotAcceptable = 406,
541 Failure_ProxyAuthenticationRequired = 407,
542 Failure_RequestTimeout = 408,
543 Failure_Conflict = 409,
544 Failure_Gone = 410,
545 Failure_LengthRequired = 411,
546 Failure_RequestEntityTooLarge = 413,
547 Failure_RequestURITooLong = 414,
548 Failure_UnsupportedMediaType = 415,
549 Failure_UnsupportedURIScheme = 416,
550 Failure_BadExtension = 420,
551 Failure_ExtensionRequired = 421,
552 Failure_IntervalTooBrief = 423,
553 Failure_TemporarilyUnavailable = 480,
554 Failure_TransactionDoesNotExist = 481,
555 Failure_LoopDetected = 482,
556 Failure_TooManyHops = 483,
557 Failure_AddressIncomplete = 484,
558 Failure_Ambiguous = 485,
559 Failure_BusyHere = 486,
560 Failure_RequestTerminated = 487,
561 Failure_NotAcceptableHere = 488,
562 Failure_BadEvent = 489,
563 Failure_RequestPending = 491,
564 Failure_Undecipherable = 493,
565
566 Failure_InternalServerError = 500,
567 Failure_NotImplemented = 501,
568 Failure_BadGateway = 502,
569 Failure_ServiceUnavailable = 503,
570 Failure_ServerTimeout = 504,
571 Failure_SIPVersionNotSupported = 505,
572 Failure_MessageTooLarge = 513,
573
574 GlobalFailure_BusyEverywhere = 600,
575 GlobalFailure_Decline = 603,
576 GlobalFailure_DoesNotExistAnywhere = 604,
577 GlobalFailure_NotAcceptable = 606,
578
579 MaxStatusCode = 699
580 };
581
582 static const char * GetStatusCodeDescription(int code);
583 friend ostream & operator<<(ostream & strm, StatusCodes status);
584
585 SIP_PDU(
586 Methods method = SIP_PDU::NumMethods
587 );
588
592 SIP_PDU(
593 const SIP_PDU & request,
594 StatusCodes code,
595 const SDPSessionDescription * sdp = NULL
596 );
597
598 SIP_PDU(const SIP_PDU &);
599 SIP_PDU & operator=(const SIP_PDU &);
600 ~SIP_PDU();
601
602 void PrintOn(
603 ostream & strm
604 ) const;
605
606 void InitialiseHeaders(
607 const SIPURL & dest,
608 const SIPURL & to,
609 const SIPURL & from,
610 const PString & callID,
611 unsigned cseq,
612 const PString & via
613 );
614 void InitialiseHeaders(
615 SIPDialogContext & dialog,
616 const PString & via = PString::Empty(),
617 unsigned cseq = 0
618 );
619 void InitialiseHeaders(
620 SIPConnection & connection,
621 const OpalTransport & transport,
622 unsigned cseq = 0
623 );
624 void InitialiseHeaders(
625 const SIP_PDU & request
626 );
627
632 bool SetRoute(const SIPURLList & routeSet);
633 bool SetRoute(const SIPURL & proxy);
634
637 void SetAllow(unsigned bitmask);
638
641 void AdjustVia(OpalTransport & transport);
642
643 PString CreateVia(
644 SIPEndPoint & endpoint,
645 const OpalTransport & transport,
646 SIPConnection * connection = NULL
647 );
648
651 SIP_PDU::StatusCodes Read(
652 OpalTransport & transport
653 );
654
657 PBoolean Write(
658 OpalTransport & transport,
659 const OpalTransportAddress & remoteAddress = OpalTransportAddress(),
660 const PString & localInterface = PString::Empty()
661 );
662
665 bool SendResponse(
666 OpalTransport & transport,
667 StatusCodes code,
668 SIPEndPoint * endpoint = NULL
669 ) const;
670 bool SendResponse(
671 OpalTransport & transport,
672 SIP_PDU & response,
673 SIPEndPoint * endpoint = NULL
674 ) const;
675
679 PString Build();
680
681 PString GetTransactionID() const;
682
683 Methods GetMethod() const { return m_method; }
684 StatusCodes GetStatusCode () const { return m_statusCode; }
685 void SetStatusCode (StatusCodes c) { m_statusCode = c; }
686 const SIPURL & GetURI() const { return m_uri; }
687 void SetURI(const SIPURL & newuri) { m_uri = newuri; }
688 unsigned GetVersionMajor() const { return m_versionMajor; }
689 unsigned GetVersionMinor() const { return m_versionMinor; }
690 void SetCSeq(unsigned cseq);
691 const PString & GetEntityBody() const { return m_entityBody; }
692 void SetEntityBody(const PString & body) { m_entityBody = body; }
693 void SetEntityBody();
694 const PString & GetInfo() const { return m_info; }
695 void SetInfo(const PString & info) { m_info = info; }
696 const SIPMIMEInfo & GetMIME() const { return m_mime; }
697 SIPMIMEInfo & GetMIME() { return m_mime; }
698 SDPSessionDescription * GetSDP(const OpalMediaFormatList & masterList);
699 void SetSDP(SDPSessionDescription * sdp);
700
701 protected:
702 Methods m_method; // Request type, ==NumMethods for Response
703 StatusCodes m_statusCode;
704 SIPURL m_uri; // display name & URI, no tag
705 unsigned m_versionMajor;
706 unsigned m_versionMinor;
707 PString m_info;
708 SIPMIMEInfo m_mime;
709 PString m_entityBody;
710
711 SDPSessionDescription * m_SDP;
712
713 mutable PString m_transactionID;
714 };
715
716
717 PQUEUE(SIP_PDU_Queue, SIP_PDU);
718
719
720 #if PTRACING
721 ostream & operator<<(ostream & strm, SIP_PDU::Methods method);
722 #endif
723
724
726 // SIPDialogContext
727
730 class SIPDialogContext
731 {
732 public:
733 SIPDialogContext();
734 SIPDialogContext(const SIPMIMEInfo & mime);
735
736 PString AsString() const;
737 bool FromString(
738 const PString & str
739 );
740
741 const PString & GetCallID() const { return m_callId; }
742 void SetCallID(const PString & id) { m_callId = id; }
743
744 const SIPURL & GetRequestURI() const { return m_requestURI; }
745 void SetRequestURI(const SIPURL & url) { m_requestURI = url; }
746
747 const PString & GetLocalTag() const { return m_localTag; }
748 void SetLocalTag(const PString & tag) { m_localTag = tag; }
749
750 const SIPURL & GetLocalURI() const { return m_localURI; }
751 void SetLocalURI(const SIPURL & url);
752
753 const PString & GetRemoteTag() const { return m_remoteTag; }
754 void SetRemoteTag(const PString & tag) { m_remoteTag = tag; }
755
756 const SIPURL & GetRemoteURI() const { return m_remoteURI; }
757 void SetRemoteURI(const SIPURL & url);
758
759 const SIPURLList & GetRouteSet() const { return m_routeSet; }
760 void SetRouteSet(const PString & str) { m_routeSet.FromString(str); }
761
762 const SIPURL & GetProxy() const { return m_proxy; }
763 void SetProxy(const SIPURL & proxy, bool addToRouteSet);
764
765 void Update(OpalTransport & transport, const SIP_PDU & response);
766
767 unsigned GetNextCSeq();
768 void IncrementCSeq(unsigned inc) { m_lastSentCSeq += inc; }
769
770 bool IsDuplicateCSeq(unsigned sequenceNumber);
771
772 bool IsEstablished() const
773 {
774 return !m_callId.IsEmpty() &&
775 !m_requestURI.IsEmpty() &&
776 !m_localTag.IsEmpty() &&
777 !m_remoteTag.IsEmpty();
778 }
779
780 OpalTransportAddress GetRemoteTransportAddress() const;
781
782 void SetForking(bool f) { m_forking = f; }
783
784 protected:
785 PString m_callId;
786 SIPURL m_requestURI;
787 SIPURL m_localURI;
788 PString m_localTag;
789 SIPURL m_remoteURI;
790 PString m_remoteTag;
791 SIPURLList m_routeSet;
792 unsigned m_lastSentCSeq;
793 unsigned m_lastReceivedCSeq;
794 OpalTransportAddress m_externalTransportAddress;
795 bool m_forking;
796 SIPURL m_proxy;
797 };
798
799
801
802 struct SIPParameters
803 {
804 SIPParameters(
805 const PString & aor = PString::Empty(),
806 const PString & remote = PString::Empty()
807 );
808
809 void Normalise(
810 const PString & defaultUser,
811 const PTimeInterval & defaultExpire
812 );
813
814 PCaselessString m_remoteAddress;
815 PCaselessString m_localAddress;
816 PCaselessString m_proxyAddress;
817 PCaselessString m_addressOfRecord;
818 PCaselessString m_contactAddress;
819 SIPMIMEInfo m_mime;
820 PString m_authID;
821 PString m_password;
822 PString m_realm;
823 unsigned m_expire;
824 unsigned m_restoreTime;
825 PTimeInterval m_minRetryTime;
826 PTimeInterval m_maxRetryTime;
827 void * m_userData;
828 };
829
830
831 #if PTRACING
832 ostream & operator<<(ostream & strm, const SIPParameters & params);
833 #endif
834
835
837 // SIPTransaction
838
849 class SIPTransaction : public SIP_PDU
850 {
851 PCLASSINFO(SIPTransaction, SIP_PDU);
852 public:
853 SIPTransaction(
854 Methods method,
855 SIPEndPoint & endpoint,
856 OpalTransport & transport
857 );
861 SIPTransaction(
862 Methods method,
863 SIPConnection & connection
864 );
865 ~SIPTransaction();
866
867 /* Under some circumstances a new transaction with all the same parameters
868 but different ID needs to be created, e.g. when get authentication error. */
869 virtual SIPTransaction * CreateDuplicate() const = 0;
870
871 PBoolean Start();
872 bool IsTrying() const { return m_state == Trying; }
873 bool IsProceeding() const { return m_state == Proceeding; }
874 bool IsInProgress() const { return m_state == Trying || m_state == Proceeding; }
875 bool IsFailed() const { return m_state > Terminated_Success; }
876 bool IsCompleted() const { return m_state >= Completed; }
877 bool IsCanceled() const { return m_state == Cancelling || m_state == Terminated_Cancelled || m_state == Terminated_Aborted; }
878 bool IsTerminated() const { return m_state >= Terminated_Success; }
879
880 void WaitForCompletion();
881 PBoolean Cancel();
882 void Abort();
883
884 virtual PBoolean OnReceivedResponse(SIP_PDU & response);
885 virtual PBoolean OnCompleted(SIP_PDU & response);
886
887 OpalTransport & GetTransport() const { return m_transport; }
888 SIPConnection * GetConnection() const { return m_connection; }
889 PString GetInterface() const { return m_localInterface; }
890 void SetInterface(const PString & localIf) { m_localInterface = localIf; }
891
892 static PString GenerateCallID();
893
894 protected:
895 bool SendPDU(SIP_PDU & pdu);
896 bool ResendCANCEL();
897 void SetParameters(const SIPParameters & params);
898
899 PDECLARE_NOTIFIER(PTimer, SIPTransaction, OnRetry);
900 PDECLARE_NOTIFIER(PTimer, SIPTransaction, OnTimeout);
901
902 enum States {
903 NotStarted,
904 Trying,
905 Proceeding,
906 Cancelling,
907 Completed,
908 Terminated_Success,
909 Terminated_Timeout,
910 Terminated_RetriesExceeded,
911 Terminated_TransportError,
912 Terminated_Cancelled,
913 Terminated_Aborted,
914 NumStates
915 };
916 virtual void SetTerminated(States newState);
917
918 SIPEndPoint & m_endpoint;
919 OpalTransport & m_transport;
920 PSafePtr<SIPConnection> m_connection;
921 PTimeInterval m_retryTimeoutMin;
922 PTimeInterval m_retryTimeoutMax;
923
924 States m_state;
925 unsigned m_retry;
926 PTimer m_retryTimer;
927 PTimer m_completionTimer;
928 PSyncPoint m_completed;
929
930 PString m_localInterface;
931 OpalTransportAddress m_remoteAddress;
932 };
933
934
935 #define OPAL_PROXY_PARAM "OPAL-proxy"
936 #define OPAL_LOCAL_ID_PARAM "OPAL-local-id"
937
938
940 // SIPResponse
941
944 class SIPResponse : public SIPTransaction
945 {
946 PCLASSINFO(SIPResponse, SIPTransaction);
947 public:
948 SIPResponse(
949 SIPEndPoint & endpoint,
950 StatusCodes code
951 );
952
953 virtual SIPTransaction * CreateDuplicate() const;
954
955 bool Send(OpalTransport & transport, const SIP_PDU & command);
956 };
957
958
960 // SIPInvite
961
967 class SIPInvite : public SIPTransaction
968 {
969 PCLASSINFO(SIPInvite, SIPTransaction);
970 public:
971 SIPInvite(
972 SIPConnection & connection,
973 const OpalRTPSessionManager & sm
974 );
975
976 virtual SIPTransaction * CreateDuplicate() const;
977
978 virtual PBoolean OnReceivedResponse(SIP_PDU & response);
979
980 const OpalRTPSessionManager & GetSessionManager() const { return m_rtpSessions; }
981 OpalRTPSessionManager & GetSessionManager() { return m_rtpSessions; }
982
983 protected:
984 OpalRTPSessionManager m_rtpSessions;
985 };
986
987
989
990 /* This is the ACK request sent when receiving a response to an outgoing
991 * INVITE.
992 */
993 class SIPAck : public SIP_PDU
994 {
995 PCLASSINFO(SIPAck, SIP_PDU);
996 public:
997 SIPAck(
998 SIPTransaction & invite,
999 SIP_PDU & response
1000 );
1001
1002 virtual SIPTransaction * CreateDuplicate() const;
1003 };
1004
1005
1007
1008 /* This is a BYE request
1009 */
1010 class SIPBye : public SIPTransaction
1011 {
1012 PCLASSINFO(SIPBye, SIPTransaction);
1013
1014 public:
1015 SIPBye(
1016 SIPEndPoint & ep,
1017 OpalTransport & trans,
1018 SIPDialogContext dialog
1019 );
1020 SIPBye(
1021 SIPConnection & conn
1022 );
1023
1024 virtual SIPTransaction * CreateDuplicate() const;
1025 };
1026
1027
1029
1030 class SIPRegister : public SIPTransaction
1031 {
1032 PCLASSINFO(SIPRegister, SIPTransaction);
1033 public:
1034 enum CompatibilityModes {
1035 e_FullyCompliant,
1038 e_CannotRegisterMultipleContacts,
1042 e_CannotRegisterPrivateContacts,
1046 e_HasApplicationLayerGateway
1050 };
1051
1053 struct Params : public SIPParameters {
1054 Params()
1055 : m_registrarAddress(m_remoteAddress)
1056 , m_compatibility(SIPRegister::e_FullyCompliant)
1057 { }
1058
1059 Params(const Params & param)
1060 : SIPParameters(param)
1061 , m_registrarAddress(m_remoteAddress)
1062 , m_compatibility(param.m_compatibility)
1063 { }
1064
1065 PCaselessString & m_registrarAddress; // For backward compatibility
1066 CompatibilityModes m_compatibility;
1067 };
1068
1069 SIPRegister(
1070 SIPEndPoint & endpoint,
1071 OpalTransport & transport,
1072 const PString & callId,
1073 unsigned cseq,
1074 const Params & params
1075 );
1076
1077 virtual SIPTransaction * CreateDuplicate() const;
1078 };
1079
1080
1081 #if PTRACING
1082 ostream & operator<<(ostream & strm, SIPRegister::CompatibilityModes mode);
1083 ostream & operator<<(ostream & strm, const SIPRegister::Params & params);
1084 #endif
1085
1086
1088
1089 class SIPSubscribe : public SIPTransaction
1090 {
1091 PCLASSINFO(SIPSubscribe, SIPTransaction);
1092 public:
1095 enum PredefinedPackages {
1096 MessageSummary,
1097 Presence,
1098 Dialog,
1099
1100 NumPredefinedPackages,
1101
1102 Watcher = 0x8000,
1103
1104 MessageSummaryWatcher = Watcher|MessageSummary,
1105 PresenceWatcher = Watcher|Presence,
1106 DialogWatcher = Watcher|Dialog,
1107
1108 PackageMask = Watcher-1
1109 };
1110 friend PredefinedPackages operator|(PredefinedPackages p1, PredefinedPackages p2) { return (PredefinedPackages)((int)p1|(int)p2); }
1111
1112 class EventPackage : public PCaselessString
1113 {
1114 PCLASSINFO(EventPackage, PCaselessString);
1115 public:
1116 EventPackage(PredefinedPackages = NumPredefinedPackages);
1117 explicit EventPackage(const PString & str) : PCaselessString(str) { }
1118 explicit EventPackage(const char * str) : PCaselessString(str) { }
1119
1120 EventPackage & operator=(PredefinedPackages pkg);
1121 EventPackage & operator=(const PString & str) { PCaselessString::operator=(str); return *this; }
1122 EventPackage & operator=(const char * str) { PCaselessString::operator=(str); return *this; }
1123
1124 bool operator==(PredefinedPackages pkg) const { return Compare(EventPackage(pkg)) == EqualTo; }
1125 bool operator==(const PString & str) const { return Compare(str) == EqualTo; }
1126 bool operator==(const char * cstr) const { return InternalCompare(0, P_MAX_INDEX, cstr) == EqualTo; }
1127 virtual Comparison InternalCompare(PINDEX offset, PINDEX length, const char * cstr) const;
1128
1129 bool IsWatcher() const;
1130 };
1131
1133 struct SubscriptionStatus {
1134 SIPSubscribeHandler * m_handler;
1135 PString m_addressofRecord;
1136 bool m_wasSubscribing;
1137 bool m_reSubscribing;
1138 SIP_PDU::StatusCodes m_reason;
1139 OpalProductInfo m_productInfo;
1140 void * m_userData;
1141 };
1142
1143 struct NotifyCallbackInfo {
1144 NotifyCallbackInfo(
1145 SIPEndPoint & ep,
1146 OpalTransport & trans,
1147 SIP_PDU & notify,
1148 SIP_PDU & response
1149 );
1150
1151 bool SendResponse(
1152 SIP_PDU::StatusCodes status,
1153 const char * extra = NULL
1154 );
1155
1156 SIPEndPoint & m_endpoint;
1157 OpalTransport & m_transport;
1158 SIP_PDU & m_notify;
1159 SIP_PDU & m_response;
1160 bool m_sendResponse;
1161 };
1162
1163 struct Params : public SIPParameters
1164 {
1165 Params(PredefinedPackages pkg = NumPredefinedPackages)
1166 : m_agentAddress(m_remoteAddress)
1167 , m_eventPackage(pkg)
1168 , m_eventList(false)
1169 { }
1170
1171 Params(const Params & param)
1172 : SIPParameters(param)
1173 , m_agentAddress(m_remoteAddress)
1174 , m_eventPackage(param.m_eventPackage)
1175 , m_eventList(param.m_eventList)
1176 , m_contentType(param.m_contentType)
1177 , m_onSubcribeStatus(param.m_onSubcribeStatus)
1178 , m_onNotify(param.m_onNotify)
1179 { }
1180
1181 PCaselessString & m_agentAddress; // For backward compatibility
1182 EventPackage m_eventPackage;
1183 bool m_eventList; // Enable RFC4662
1184 PCaselessString m_contentType; // May be \n separated list of types
1185
1186 PNotifierTemplate<const SubscriptionStatus &> m_onSubcribeStatus;
1187 PNotifierTemplate<NotifyCallbackInfo &> m_onNotify;
1188 };
1189
1190 SIPSubscribe(
1191 SIPEndPoint & ep,
1192 OpalTransport & trans,
1193 SIPDialogContext & dialog,
1194 const Params & params
1195 );
1196
1197 virtual SIPTransaction * CreateDuplicate() const;
1198 };
1199
1200
1201 #if PTRACING
1202 ostream & operator<<(ostream & strm, const SIPSubscribe::Params & params);
1203 #endif
1204
1205
1206 typedef SIPSubscribe::EventPackage SIPEventPackage;
1207
1208
1210
1211 class SIPHandler;
1212
1213 class SIPEventPackageHandler
1214 {
1215 public:
1216 virtual ~SIPEventPackageHandler() { }
1217 virtual PCaselessString GetContentType() const = 0;
1218 virtual bool ValidateContentType(const PString & type, const SIPMIMEInfo & mime);
1219 virtual bool OnReceivedNOTIFY(SIPHandler & handler, SIP_PDU & request) = 0;
1220 virtual PString OnSendNOTIFY(SIPHandler & /*handler*/, const PObject * /*body*/) { return PString::Empty(); }
1221 };
1222
1223
1224 typedef PFactory<SIPEventPackageHandler, SIPEventPackage> SIPEventPackageFactory;
1225
1226
1228
1229 class SIPNotify : public SIPTransaction
1230 {
1231 PCLASSINFO(SIPNotify, SIPTransaction);
1232 public:
1233 SIPNotify(
1234 SIPEndPoint & ep,
1235 OpalTransport & trans,
1236 SIPDialogContext & dialog,
1237 const SIPEventPackage & eventPackage,
1238 const PString & state,
1239 const PString & body
1240 );
1241
1242 virtual SIPTransaction * CreateDuplicate() const;
1243 };
1244
1245
1247
1248 class SIPPublish : public SIPTransaction
1249 {
1250 PCLASSINFO(SIPPublish, SIPTransaction);
1251 public:
1252 SIPPublish(
1253 SIPEndPoint & ep,
1254 OpalTransport & trans,
1255 const PString & id,
1256 const PString & sipIfMatch,
1257 const SIPSubscribe::Params & params,
1258 const PString & body
1259 );
1260
1261 virtual SIPTransaction * CreateDuplicate() const;
1262 };
1263
1264
1266
1267 class SIPRefer : public SIPTransaction
1268 {
1269 PCLASSINFO(SIPRefer, SIPTransaction);
1270 public:
1271 SIPRefer(
1272 SIPConnection & connection,
1273 const SIPURL & referTo,
1274 const SIPURL & referred_by,
1275 bool referSub
1276 );
1277
1278 virtual SIPTransaction * CreateDuplicate() const;
1279 };
1280
1281
1283
1284 /* This is not a generic NOTIFY PDU, but the minimal one
1285 * that gets sent when receiving a REFER
1286 */
1287 class SIPReferNotify : public SIPTransaction
1288 {
1289 PCLASSINFO(SIPReferNotify, SIPTransaction);
1290 public:
1291 SIPReferNotify(
1292 SIPConnection & connection,
1293 StatusCodes code
1294 );
1295
1296 virtual SIPTransaction * CreateDuplicate() const;
1297 };
1298
1299
1301
1302 /* This is a MESSAGE PDU, with a body
1303 */
1304 class SIPMessage : public SIPTransaction
1305 {
1306 PCLASSINFO(SIPMessage, SIPTransaction);
1307 public:
1308 struct Params : public SIPParameters
1309 {
1310 Params()
1311 : m_contentType("text/plain;charset=UTF-8")
1312 {
1313 m_expire = 5000;
1314 }
1315
1316 PCaselessString m_contentType;
1317 PString m_id;
1318 PString m_body;
1319 PAtomicInteger::IntegerType m_messageId;
1320 };
1321
1322 SIPMessage(
1323 SIPEndPoint & ep,
1324 OpalTransport & trans,
1325 const Params & params
1326 );
1327 SIPMessage(
1328 SIPConnection & connection,
1329 const Params & params
1330 );
1331
1332 virtual SIPTransaction * CreateDuplicate() const;
1333
1334 const SIPURL & GetLocalAddress() const { return m_localAddress; }
1335
1336 private:
1337 void Construct(const Params & params);
1338
1339 SIPURL m_localAddress;
1340 };
1341
1342
1344
1345 /* This is an OPTIONS request
1346 */
1347 class SIPOptions : public SIPTransaction
1348 {
1349 PCLASSINFO(SIPOptions, SIPTransaction);
1350
1351 public:
1352 struct Params : public SIPParameters
1353 {
1354 Params()
1355 : m_acceptContent("application/sdp, application/media_control+xml, application/dtmf, application/dtmf-relay")
1356 {
1357 }
1358
1359 PCaselessString m_acceptContent;
1360 PCaselessString m_contentType;
1361 PString m_body;
1362 };
1363
1364 SIPOptions(
1365 SIPEndPoint & ep,
1366 OpalTransport & trans,
1367 const PString & id,
1368 const Params & params
1369 );
1370 SIPOptions(
1371 SIPConnection & conn,
1372 const Params & params
1373 );
1374
1375 virtual SIPTransaction * CreateDuplicate() const;
1376
1377 protected:
1378 void Construct(const Params & params);
1379 };
1380
1381
1383
1384 /* This is an INFO request
1385 */
1386 class SIPInfo : public SIPTransaction
1387 {
1388 PCLASSINFO(SIPInfo, SIPTransaction);
1389
1390 public:
1391 struct Params
1392 {
1393 Params(const PString & contentType = PString::Empty(),
1394 const PString & body = PString::Empty())
1395 : m_contentType(contentType)
1396 , m_body(body)
1397 {
1398 }
1399
1400 PCaselessString m_contentType;
1401 PString m_body;
1402 };
1403
1404 SIPInfo(
1405 SIPConnection & conn,
1406 const Params & params
1407 );
1408
1409 virtual SIPTransaction * CreateDuplicate() const;
1410 };
1411
1412
1414
1415 /* This is a PING PDU, with a body
1416 */
1417 class SIPPing : public SIPTransaction
1418 {
1419 PCLASSINFO(SIPPing, SIPTransaction);
1420
1421 public:
1422 SIPPing(
1423 SIPEndPoint & ep,
1424 OpalTransport & trans,
1425 const SIPURL & address
1426 );
1427
1428 virtual SIPTransaction * CreateDuplicate() const;
1429 };
1430
1431
1433
1434 /* This is a PRACK PDU
1435 */
1436 class SIPPrack : public SIPTransaction
1437 {
1438 PCLASSINFO(SIPPrack, SIPTransaction);
1439
1440 public:
1441 SIPPrack(
1442 SIPConnection & conn,
1443 const PString & rack
1444 );
1445
1446 virtual SIPTransaction * CreateDuplicate() const;
1447 };
1448
1449
1450 #endif // OPAL_SIP
1451
1452 #endif // OPAL_SIP_SIPPDU_H
1453
1454
1455 // End of File ///////////////////////////////////////////////////////////////