Fixed issue with use of static C string variables in DLL environment,
[opal.git] / include / h323 / h323neg.h
blobe1c7014b2e7cd24d2b7ac440f836b0fd04936063
1 /*
2 * h323neg.h
4 * H.323 protocol handler
6 * Open H323 Library
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
18 * under the License.
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): ______________________________________.
29 * $Log$
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
171 #ifdef P_USE_PRAGMA
172 #pragma interface
173 #endif
176 #include <h323/h323pdu.h>
177 #include <h323/channels.h>
180 class H323EndPoint;
181 class H323Connection;
184 ///////////////////////////////////////////////////////////////////////////////
186 /**Base class for doing H245 negotiations
188 class H245Negotiator : public PObject
190 PCLASSINFO(H245Negotiator, PObject);
192 public:
193 H245Negotiator(H323EndPoint & endpoint, H323Connection & connection);
195 protected:
196 PDECLARE_NOTIFIER(PTimer, H245Negotiator, HandleTimeout);
198 H323EndPoint & endpoint;
199 H323Connection & connection;
200 PTimer replyTimer;
201 PMutex mutex;
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);
211 public:
212 H245NegMasterSlaveDetermination(H323EndPoint & endpoint, H323Connection & connection);
214 BOOL Start(BOOL renegotiate);
215 void Stop();
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; }
225 protected:
226 BOOL Restart();
228 enum States {
229 e_Idle, e_Outgoing, e_Incoming,
230 e_NumStates
231 } state;
232 #if PTRACING
233 static const char * GetStateName(States s);
234 friend ostream & operator<<(ostream & o, States s) { return o << GetStateName(s); }
235 #endif
237 DWORD determinationNumber;
238 unsigned retryCount;
240 enum MasterSlaveStatus {
241 e_Indeterminate, e_DeterminedMaster, e_DeterminedSlave,
242 e_NumStatuses
243 } status;
244 #if PTRACING
245 static const char * GetStatusName(MasterSlaveStatus s);
246 friend ostream & operator<<(ostream & o , MasterSlaveStatus s) { return o << GetStatusName(s); }
247 #endif
251 /**Exchange capabilities on a H245 connection as per H245 section 8.3
253 class H245NegTerminalCapabilitySet : public H245Negotiator
255 PCLASSINFO(H245NegTerminalCapabilitySet, H245Negotiator);
257 public:
258 H245NegTerminalCapabilitySet(H323EndPoint & endpoint, H323Connection & connection);
260 BOOL Start(BOOL renegotiate, BOOL empty = FALSE);
261 void Stop();
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; }
271 protected:
272 enum States {
273 e_Idle, e_InProgress, e_Sent,
274 e_NumStates
275 } state;
276 #if PTRACING
277 static const char * GetStateName(States s);
278 friend ostream & operator<<(ostream & o, States s) { return o << GetStateName(s); }
279 #endif
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);
294 public:
295 H245NegLogicalChannel(H323EndPoint & endpoint,
296 H323Connection & connection,
297 const H323ChannelNumber & channelNumber);
298 H245NegLogicalChannel(H323EndPoint & endpoint,
299 H323Connection & connection,
300 H323Channel & channel);
301 ~H245NegLogicalChannel();
303 virtual BOOL Open(
304 const H323Capability & capability,
305 unsigned sessionID,
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();
324 protected:
325 virtual BOOL OpenWhileLocked(
326 const H323Capability & capability,
327 unsigned sessionID,
328 unsigned replacementFor = 0
330 virtual BOOL CloseWhileLocked();
331 virtual void Release();
334 H323Channel * channel;
336 H323ChannelNumber channelNumber;
338 enum States {
339 e_Released,
340 e_AwaitingEstablishment,
341 e_Established,
342 e_AwaitingRelease,
343 e_AwaitingConfirmation,
344 e_AwaitingResponse,
345 e_NumStates
346 } state;
347 #if PTRACING
348 static const char * GetStateName(States s);
349 friend ostream & operator<<(ostream & o, States s) { return o << GetStateName(s); }
350 #endif
353 friend class H245NegLogicalChannels;
357 PDICTIONARY(H245LogicalChannelDict, H323ChannelNumber, H245NegLogicalChannel);
359 /**Dictionary of all Logical Channels
361 class H245NegLogicalChannels : public H245Negotiator
363 PCLASSINFO(H245NegLogicalChannels, H245Negotiator);
365 public:
366 H245NegLogicalChannels(H323EndPoint & endpoint, H323Connection & connection);
368 virtual void Add(H323Channel & channel);
370 virtual BOOL Open(
371 const H323Capability & capability,
372 unsigned sessionID,
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);
394 void RemoveAll();
396 protected:
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);
408 public:
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);
419 protected:
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);
432 public:
433 H245NegRoundTripDelay(H323EndPoint & endpoint, H323Connection & connection);
435 BOOL StartRequest();
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; }
443 protected:
444 BOOL awaitingResponse;
445 unsigned sequenceNumber;
446 PTimeInterval tripStartTime;
447 PTimeInterval roundTripTime;
448 unsigned retryCount;
452 #endif // __OPAL_H323NEG_H
455 /////////////////////////////////////////////////////////////////////////////