4 * H.323 protocol handler
8 * Copyright (c) 1998-2001 Equivalence Pty. Ltd.
10 * The contents of this file are subject to the Mozilla Public License
11 * Version 1.0 (the "License"); you may not use this file except in
12 * compliance with the License. You may obtain a copy of the License at
13 * http://www.mozilla.org/MPL/
15 * Software distributed under the License is distributed on an "AS IS"
16 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17 * the License for the specific language governing rights and limitations
20 * The Original Code is Open H323 Library.
22 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
24 * Portions of this code were written with the assisance of funding from
25 * Vovida Networks, Inc. http://www.vovida.com.
27 * Contributor(s): ______________________________________.
30 * Revision 2.8 2007/04/10 05:15:53 rjongbloed
31 * Fixed issue with use of static C string variables in DLL environment,
32 * must use functional interface for correct initialisation.
34 * Revision 2.7 2002/11/10 11:33:16 robertj
35 * Updated to OpenH323 v1.10.3
37 * Revision 2.6 2002/09/16 02:52:34 robertj
38 * Added #define so can select if #pragma interface/implementation is used on
39 * platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan.
41 * Revision 2.5 2002/09/04 06:01:47 robertj
42 * Updated to OpenH323 v1.9.6
44 * Revision 2.4 2002/07/01 04:56:30 robertj
45 * Updated to OpenH323 v1.9.1
47 * Revision 2.3 2002/01/14 06:35:57 robertj
48 * Updated to OpenH323 v1.7.9
50 * Revision 2.2 2001/10/05 00:22:13 robertj
51 * Updated to PWLib 1.2.0 and OpenH323 1.7.0
53 * Revision 2.1 2001/08/13 05:10:39 robertj
54 * Updates from OpenH323 v1.6.0 release.
56 * Revision 2.0 2001/07/27 15:48:24 robertj
57 * Conversion of OpenH323 to Open Phone Abstraction Library (OPAL)
59 * Revision 1.34 2002/09/16 01:14:15 robertj
60 * Added #define so can select if #pragma interface/implementation is used on
61 * platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan.
63 * Revision 1.33 2002/09/03 06:19:36 robertj
64 * Normalised the multi-include header prevention ifdef/define symbol.
66 * Revision 1.32 2002/08/05 10:03:47 robertj
67 * Cosmetic changes to normalise the usage of pragma interface/implementation.
69 * Revision 1.31 2002/06/26 08:51:16 robertj
70 * Fixed deadlock if logical channel is closed via H.245 at exactly same
71 * time as being closed locally due to a channel I/O error.
73 * Revision 1.30 2002/05/03 03:08:35 robertj
74 * Added replacementFor field in OLC when resolving conflicting channels.
76 * Revision 1.29 2002/01/09 00:21:36 robertj
77 * Changes to support outgoing H.245 RequstModeChange.
79 * Revision 1.28 2002/01/01 23:32:30 craigs
80 * Added HandleAck and StartRequest implementations for T.38
81 * thanks to Vyacheslav Frolov
83 * Revision 1.27 2002/01/01 23:21:30 craigs
84 * Added virtual keyword to many functions
86 * Revision 1.26 2001/09/12 01:54:45 robertj
87 * Added virtual keyword to function in logical channel management.
89 * Revision 1.25 2001/08/06 03:08:11 robertj
90 * Fission of h323.h to h323ep.h & h323con.h, h323.h now just includes files.
92 * Revision 1.24 2001/05/30 23:34:54 robertj
93 * Added functions to send TCS=0 for transmitter side pause.
95 * Revision 1.23 2001/03/16 07:11:38 robertj
96 * Added logical channel open function version without locking.
98 * Revision 1.22 2001/03/14 22:05:24 robertj
99 * Changed H245NegLogicalChannel::Release() to be virtual protected rather than private.
101 * Revision 1.21 2001/03/14 03:20:25 robertj
102 * Fixed possible nested mutex deadlock in logical channel negotiator.
104 * Revision 1.20 2001/03/06 04:44:46 robertj
105 * Fixed problem where could send capability set twice. This should not be
106 * a problem except when talking to another broken stack, eg Cisco routers.
108 * Revision 1.19 2001/02/09 05:16:24 robertj
109 * Added #pragma interface for GNU C++.
111 * Revision 1.18 2000/08/21 12:37:14 robertj
112 * Fixed race condition if close call just as slow start media channels are opening, part 2.
114 * Revision 1.17 2000/07/14 08:59:56 robertj
115 * Fixed race condition in closing connection and explicit close logical channel.
117 * Revision 1.16 2000/07/10 16:00:14 robertj
118 * Added TCS=0 support.
119 * Fixed bug where negotiations hang if not fast start and tunnelled but remot does not tunnel.
121 * Revision 1.15 2000/05/22 07:32:51 craigs
122 * Fixed problem with ohphone silence detection hanging
124 * Revision 1.14 2000/05/16 08:13:32 robertj
125 * Added function to find channel by session ID, supporting H323Connection::FindChannel() with mutex.
127 * Revision 1.13 2000/05/11 04:16:35 robertj
128 * Fixed missing timeout (and typo!) in bidirectional open logical channel.
130 * Revision 1.12 2000/05/02 04:32:24 robertj
131 * Fixed copyright notice comment.
133 * Revision 1.11 2000/04/10 17:50:53 robertj
134 * Fixed yet another race condition needing mutex in logical channels management class.
136 * Revision 1.10 2000/04/05 03:17:30 robertj
137 * Added more RTP statistics gathering and H.245 round trip delay calculation.
139 * Revision 1.9 2000/03/25 02:19:50 robertj
140 * Fixed missing mutex call in some logical channels structure access.
142 * Revision 1.8 1999/11/06 11:58:38 robertj
143 * Changed clean up to delete logical channels before channel destructor is called.
145 * Revision 1.7 1999/11/06 11:00:08 robertj
146 * Fixed race condition in explicit channel close and connection close.
148 * Revision 1.6 1999/11/06 05:37:44 robertj
149 * Complete rewrite of termination of connection to avoid numerous race conditions.
151 * Revision 1.5 1999/10/14 12:05:03 robertj
152 * Fixed deadlock possibilities in clearing calls.
154 * Revision 1.4 1999/09/21 14:03:03 robertj
155 * Fixed incorrect PTRACING test
157 * Revision 1.3 1999/09/08 04:05:48 robertj
158 * Added support for video capabilities & codec, still needs the actual codec itself!
160 * Revision 1.2 1999/08/31 12:34:18 robertj
161 * Added gatekeeper support.
163 * Revision 1.1 1999/08/25 05:07:49 robertj
164 * File fission (critical mass reached).
168 #ifndef __OPAL_H323NEG_H
169 #define __OPAL_H323NEG_H
176 #include <h323/h323pdu.h>
177 #include <h323/channels.h>
181 class H323Connection
;
184 ///////////////////////////////////////////////////////////////////////////////
186 /**Base class for doing H245 negotiations
188 class H245Negotiator
: public PObject
190 PCLASSINFO(H245Negotiator
, PObject
);
193 H245Negotiator(H323EndPoint
& endpoint
, H323Connection
& connection
);
196 PDECLARE_NOTIFIER(PTimer
, H245Negotiator
, HandleTimeout
);
198 H323EndPoint
& endpoint
;
199 H323Connection
& connection
;
205 /**Determine the master and slave on a H245 connection as per H245 section 8.2
207 class H245NegMasterSlaveDetermination
: public H245Negotiator
209 PCLASSINFO(H245NegMasterSlaveDetermination
, H245Negotiator
);
212 H245NegMasterSlaveDetermination(H323EndPoint
& endpoint
, H323Connection
& connection
);
214 BOOL
Start(BOOL renegotiate
);
216 BOOL
HandleIncoming(const H245_MasterSlaveDetermination
& pdu
);
217 BOOL
HandleAck(const H245_MasterSlaveDeterminationAck
& pdu
);
218 BOOL
HandleReject(const H245_MasterSlaveDeterminationReject
& pdu
);
219 BOOL
HandleRelease(const H245_MasterSlaveDeterminationRelease
& pdu
);
220 void HandleTimeout(PTimer
&, INT
);
222 BOOL
IsMaster() const { return status
== e_DeterminedMaster
; }
223 BOOL
IsDetermined() const { return state
== e_Idle
&& status
!= e_Indeterminate
; }
229 e_Idle
, e_Outgoing
, e_Incoming
,
233 static const char * GetStateName(States s
);
234 friend ostream
& operator<<(ostream
& o
, States s
) { return o
<< GetStateName(s
); }
237 DWORD determinationNumber
;
240 enum MasterSlaveStatus
{
241 e_Indeterminate
, e_DeterminedMaster
, e_DeterminedSlave
,
245 static const char * GetStatusName(MasterSlaveStatus s
);
246 friend ostream
& operator<<(ostream
& o
, MasterSlaveStatus s
) { return o
<< GetStatusName(s
); }
251 /**Exchange capabilities on a H245 connection as per H245 section 8.3
253 class H245NegTerminalCapabilitySet
: public H245Negotiator
255 PCLASSINFO(H245NegTerminalCapabilitySet
, H245Negotiator
);
258 H245NegTerminalCapabilitySet(H323EndPoint
& endpoint
, H323Connection
& connection
);
260 BOOL
Start(BOOL renegotiate
, BOOL empty
= FALSE
);
262 BOOL
HandleIncoming(const H245_TerminalCapabilitySet
& pdu
);
263 BOOL
HandleAck(const H245_TerminalCapabilitySetAck
& pdu
);
264 BOOL
HandleReject(const H245_TerminalCapabilitySetReject
& pdu
);
265 BOOL
HandleRelease(const H245_TerminalCapabilitySetRelease
& pdu
);
266 void HandleTimeout(PTimer
&, INT
);
268 BOOL
HasSentCapabilities() const { return state
== e_Sent
; }
269 BOOL
HasReceivedCapabilities() const { return receivedCapabilites
; }
273 e_Idle
, e_InProgress
, e_Sent
,
277 static const char * GetStateName(States s
);
278 friend ostream
& operator<<(ostream
& o
, States s
) { return o
<< GetStateName(s
); }
281 unsigned inSequenceNumber
;
282 unsigned outSequenceNumber
;
284 BOOL receivedCapabilites
;
288 /**Logical Channel signalling on a H245 connection as per H245 section 8.4
290 class H245NegLogicalChannel
: public H245Negotiator
292 PCLASSINFO(H245NegLogicalChannel
, H245Negotiator
);
295 H245NegLogicalChannel(H323EndPoint
& endpoint
,
296 H323Connection
& connection
,
297 const H323ChannelNumber
& channelNumber
);
298 H245NegLogicalChannel(H323EndPoint
& endpoint
,
299 H323Connection
& connection
,
300 H323Channel
& channel
);
301 ~H245NegLogicalChannel();
304 const H323Capability
& capability
,
306 unsigned replacementFor
= 0
308 virtual BOOL
Close();
309 virtual BOOL
HandleOpen(const H245_OpenLogicalChannel
& pdu
);
310 virtual BOOL
HandleOpenAck(const H245_OpenLogicalChannelAck
& pdu
);
311 virtual BOOL
HandleOpenConfirm(const H245_OpenLogicalChannelConfirm
& pdu
);
312 virtual BOOL
HandleReject(const H245_OpenLogicalChannelReject
& pdu
);
313 virtual BOOL
HandleClose(const H245_CloseLogicalChannel
& pdu
);
314 virtual BOOL
HandleCloseAck(const H245_CloseLogicalChannelAck
& pdu
);
315 virtual BOOL
HandleRequestClose(const H245_RequestChannelClose
& pdu
);
316 virtual BOOL
HandleRequestCloseAck(const H245_RequestChannelCloseAck
& pdu
);
317 virtual BOOL
HandleRequestCloseReject(const H245_RequestChannelCloseReject
& pdu
);
318 virtual BOOL
HandleRequestCloseRelease(const H245_RequestChannelCloseRelease
& pdu
);
319 virtual void HandleTimeout(PTimer
&, INT
);
321 H323Channel
* GetChannel();
325 virtual BOOL
OpenWhileLocked(
326 const H323Capability
& capability
,
328 unsigned replacementFor
= 0
330 virtual BOOL
CloseWhileLocked();
331 virtual void Release();
334 H323Channel
* channel
;
336 H323ChannelNumber channelNumber
;
340 e_AwaitingEstablishment
,
343 e_AwaitingConfirmation
,
348 static const char * GetStateName(States s
);
349 friend ostream
& operator<<(ostream
& o
, States s
) { return o
<< GetStateName(s
); }
353 friend class H245NegLogicalChannels
;
357 PDICTIONARY(H245LogicalChannelDict
, H323ChannelNumber
, H245NegLogicalChannel
);
359 /**Dictionary of all Logical Channels
361 class H245NegLogicalChannels
: public H245Negotiator
363 PCLASSINFO(H245NegLogicalChannels
, H245Negotiator
);
366 H245NegLogicalChannels(H323EndPoint
& endpoint
, H323Connection
& connection
);
368 virtual void Add(H323Channel
& channel
);
371 const H323Capability
& capability
,
373 unsigned replacementFor
= 0
375 virtual BOOL
Close(unsigned channelNumber
, BOOL fromRemote
);
376 virtual BOOL
HandleOpen(const H245_OpenLogicalChannel
& pdu
);
377 virtual BOOL
HandleOpenAck(const H245_OpenLogicalChannelAck
& pdu
);
378 virtual BOOL
HandleOpenConfirm(const H245_OpenLogicalChannelConfirm
& pdu
);
379 virtual BOOL
HandleReject(const H245_OpenLogicalChannelReject
& pdu
);
380 virtual BOOL
HandleClose(const H245_CloseLogicalChannel
& pdu
);
381 virtual BOOL
HandleCloseAck(const H245_CloseLogicalChannelAck
& pdu
);
382 virtual BOOL
HandleRequestClose(const H245_RequestChannelClose
& pdu
);
383 virtual BOOL
HandleRequestCloseAck(const H245_RequestChannelCloseAck
& pdu
);
384 virtual BOOL
HandleRequestCloseReject(const H245_RequestChannelCloseReject
& pdu
);
385 virtual BOOL
HandleRequestCloseRelease(const H245_RequestChannelCloseRelease
& pdu
);
387 H323ChannelNumber
GetNextChannelNumber();
388 PINDEX
GetSize() const { return channels
.GetSize(); }
389 H323Channel
* GetChannelAt(PINDEX i
);
390 H323Channel
* FindChannel(unsigned channelNumber
, BOOL fromRemote
);
391 H245NegLogicalChannel
& GetNegLogicalChannelAt(PINDEX i
);
392 H245NegLogicalChannel
* FindNegLogicalChannel(unsigned channelNumber
, BOOL fromRemote
);
393 H323Channel
* FindChannelBySession(unsigned rtpSessionId
, BOOL fromRemote
);
397 H323ChannelNumber lastChannelNumber
;
398 H245LogicalChannelDict channels
;
402 /**Request mode change as per H245 section 8.9
404 class H245NegRequestMode
: public H245Negotiator
406 PCLASSINFO(H245NegRequestMode
, H245Negotiator
);
409 H245NegRequestMode(H323EndPoint
& endpoint
, H323Connection
& connection
);
411 virtual BOOL
StartRequest(const PString
& newModes
);
412 virtual BOOL
StartRequest(const H245_ArrayOf_ModeDescription
& newModes
);
413 virtual BOOL
HandleRequest(const H245_RequestMode
& pdu
);
414 virtual BOOL
HandleAck(const H245_RequestModeAck
& pdu
);
415 virtual BOOL
HandleReject(const H245_RequestModeReject
& pdu
);
416 virtual BOOL
HandleRelease(const H245_RequestModeRelease
& pdu
);
417 virtual void HandleTimeout(PTimer
&, INT
);
420 BOOL awaitingResponse
;
421 unsigned inSequenceNumber
;
422 unsigned outSequenceNumber
;
426 /**Request mode change as per H245 section 8.9
428 class H245NegRoundTripDelay
: public H245Negotiator
430 PCLASSINFO(H245NegRoundTripDelay
, H245Negotiator
);
433 H245NegRoundTripDelay(H323EndPoint
& endpoint
, H323Connection
& connection
);
436 BOOL
HandleRequest(const H245_RoundTripDelayRequest
& pdu
);
437 BOOL
HandleResponse(const H245_RoundTripDelayResponse
& pdu
);
438 void HandleTimeout(PTimer
&, INT
);
440 PTimeInterval
GetRoundTripDelay() const { return roundTripTime
; }
441 BOOL
IsRemoteOffline() const { return retryCount
== 0; }
444 BOOL awaitingResponse
;
445 unsigned sequenceNumber
;
446 PTimeInterval tripStartTime
;
447 PTimeInterval roundTripTime
;
452 #endif // __OPAL_H323NEG_H
455 /////////////////////////////////////////////////////////////////////////////