h323neg.h

Go to the documentation of this file.
00001 /*
00002  * h323neg.h
00003  *
00004  * H.323 protocol handler
00005  *
00006  * Open H323 Library
00007  *
00008  * Copyright (c) 1998-2001 Equivalence Pty. Ltd.
00009  *
00010  * The contents of this file are subject to the Mozilla Public License
00011  * Version 1.0 (the "License"); you may not use this file except in
00012  * compliance with the License. You may obtain a copy of the License at
00013  * http://www.mozilla.org/MPL/
00014  *
00015  * Software distributed under the License is distributed on an "AS IS"
00016  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
00017  * the License for the specific language governing rights and limitations
00018  * under the License.
00019  *
00020  * The Original Code is Open H323 Library.
00021  *
00022  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
00023  *
00024  * Portions of this code were written with the assisance of funding from
00025  * Vovida Networks, Inc. http://www.vovida.com.
00026  *
00027  * Contributor(s): ______________________________________.
00028  *
00029  * $Log: h323neg.h,v $
00030  * Revision 2.9  2007/05/23 00:25:55  csoutheren
00031  * Don't increment TCS sequence number if h245InSetup ignored
00032  *
00033  * Revision 2.8  2007/04/10 05:15:53  rjongbloed
00034  * Fixed issue with use of static C string variables in DLL environment,
00035  *   must use functional interface for correct initialisation.
00036  *
00037  * Revision 2.7  2002/11/10 11:33:16  robertj
00038  * Updated to OpenH323 v1.10.3
00039  *
00040  * Revision 2.6  2002/09/16 02:52:34  robertj
00041  * Added #define so can select if #pragma interface/implementation is used on
00042  *   platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan.
00043  *
00044  * Revision 2.5  2002/09/04 06:01:47  robertj
00045  * Updated to OpenH323 v1.9.6
00046  *
00047  * Revision 2.4  2002/07/01 04:56:30  robertj
00048  * Updated to OpenH323 v1.9.1
00049  *
00050  * Revision 2.3  2002/01/14 06:35:57  robertj
00051  * Updated to OpenH323 v1.7.9
00052  *
00053  * Revision 2.2  2001/10/05 00:22:13  robertj
00054  * Updated to PWLib 1.2.0 and OpenH323 1.7.0
00055  *
00056  * Revision 2.1  2001/08/13 05:10:39  robertj
00057  * Updates from OpenH323 v1.6.0 release.
00058  *
00059  * Revision 2.0  2001/07/27 15:48:24  robertj
00060  * Conversion of OpenH323 to Open Phone Abstraction Library (OPAL)
00061  *
00062  * Revision 1.34  2002/09/16 01:14:15  robertj
00063  * Added #define so can select if #pragma interface/implementation is used on
00064  *   platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan.
00065  *
00066  * Revision 1.33  2002/09/03 06:19:36  robertj
00067  * Normalised the multi-include header prevention ifdef/define symbol.
00068  *
00069  * Revision 1.32  2002/08/05 10:03:47  robertj
00070  * Cosmetic changes to normalise the usage of pragma interface/implementation.
00071  *
00072  * Revision 1.31  2002/06/26 08:51:16  robertj
00073  * Fixed deadlock if logical channel is closed via H.245 at exactly same
00074  *   time as being closed locally due to a channel I/O error.
00075  *
00076  * Revision 1.30  2002/05/03 03:08:35  robertj
00077  * Added replacementFor field in OLC when resolving conflicting channels.
00078  *
00079  * Revision 1.29  2002/01/09 00:21:36  robertj
00080  * Changes to support outgoing H.245 RequstModeChange.
00081  *
00082  * Revision 1.28  2002/01/01 23:32:30  craigs
00083  * Added HandleAck and StartRequest implementations for T.38
00084  * thanks to Vyacheslav Frolov
00085  *
00086  * Revision 1.27  2002/01/01 23:21:30  craigs
00087  * Added virtual keyword to many functions
00088  *
00089  * Revision 1.26  2001/09/12 01:54:45  robertj
00090  * Added virtual keyword to function in logical channel management.
00091  *
00092  * Revision 1.25  2001/08/06 03:08:11  robertj
00093  * Fission of h323.h to h323ep.h & h323con.h, h323.h now just includes files.
00094  *
00095  * Revision 1.24  2001/05/30 23:34:54  robertj
00096  * Added functions to send TCS=0 for transmitter side pause.
00097  *
00098  * Revision 1.23  2001/03/16 07:11:38  robertj
00099  * Added logical channel open function version without locking.
00100  *
00101  * Revision 1.22  2001/03/14 22:05:24  robertj
00102  * Changed H245NegLogicalChannel::Release() to be virtual protected rather than private.
00103  *
00104  * Revision 1.21  2001/03/14 03:20:25  robertj
00105  * Fixed possible nested mutex deadlock in logical channel negotiator.
00106  *
00107  * Revision 1.20  2001/03/06 04:44:46  robertj
00108  * Fixed problem where could send capability set twice. This should not be
00109  *   a problem except when talking to another broken stack, eg Cisco routers.
00110  *
00111  * Revision 1.19  2001/02/09 05:16:24  robertj
00112  * Added #pragma interface for GNU C++.
00113  *
00114  * Revision 1.18  2000/08/21 12:37:14  robertj
00115  * Fixed race condition if close call just as slow start media channels are opening, part 2.
00116  *
00117  * Revision 1.17  2000/07/14 08:59:56  robertj
00118  * Fixed race condition in closing connection and explicit close logical channel.
00119  *
00120  * Revision 1.16  2000/07/10 16:00:14  robertj
00121  * Added TCS=0 support.
00122  * Fixed bug where negotiations hang if not fast start and tunnelled but remot does not tunnel.
00123  *
00124  * Revision 1.15  2000/05/22 07:32:51  craigs
00125  * Fixed problem with ohphone silence detection hanging
00126  *
00127  * Revision 1.14  2000/05/16 08:13:32  robertj
00128  * Added function to find channel by session ID, supporting H323Connection::FindChannel() with mutex.
00129  *
00130  * Revision 1.13  2000/05/11 04:16:35  robertj
00131  * Fixed missing timeout (and typo!) in bidirectional open logical channel.
00132  *
00133  * Revision 1.12  2000/05/02 04:32:24  robertj
00134  * Fixed copyright notice comment.
00135  *
00136  * Revision 1.11  2000/04/10 17:50:53  robertj
00137  * Fixed yet another race condition needing mutex in logical channels management class.
00138  *
00139  * Revision 1.10  2000/04/05 03:17:30  robertj
00140  * Added more RTP statistics gathering and H.245 round trip delay calculation.
00141  *
00142  * Revision 1.9  2000/03/25 02:19:50  robertj
00143  * Fixed missing mutex call in some logical channels structure access.
00144  *
00145  * Revision 1.8  1999/11/06 11:58:38  robertj
00146  * Changed clean up to delete logical channels before channel destructor is called.
00147  *
00148  * Revision 1.7  1999/11/06 11:00:08  robertj
00149  * Fixed race condition in explicit channel close and connection close.
00150  *
00151  * Revision 1.6  1999/11/06 05:37:44  robertj
00152  * Complete rewrite of termination of connection to avoid numerous race conditions.
00153  *
00154  * Revision 1.5  1999/10/14 12:05:03  robertj
00155  * Fixed deadlock possibilities in clearing calls.
00156  *
00157  * Revision 1.4  1999/09/21 14:03:03  robertj
00158  * Fixed incorrect PTRACING test
00159  *
00160  * Revision 1.3  1999/09/08 04:05:48  robertj
00161  * Added support for video capabilities & codec, still needs the actual codec itself!
00162  *
00163  * Revision 1.2  1999/08/31 12:34:18  robertj
00164  * Added gatekeeper support.
00165  *
00166  * Revision 1.1  1999/08/25 05:07:49  robertj
00167  * File fission (critical mass reached).
00168  *
00169  */
00170 
00171 #ifndef __OPAL_H323NEG_H
00172 #define __OPAL_H323NEG_H
00173 
00174 #ifdef P_USE_PRAGMA
00175 #pragma interface
00176 #endif
00177 
00178 
00179 #include <h323/h323pdu.h>
00180 #include <h323/channels.h>
00181 
00182 
00183 class H323EndPoint;
00184 class H323Connection;
00185 
00186 
00188 
00191 class H245Negotiator : public PObject
00192 {
00193   PCLASSINFO(H245Negotiator, PObject);
00194 
00195   public:
00196     H245Negotiator(H323EndPoint & endpoint, H323Connection & connection);
00197 
00198   protected:
00199     PDECLARE_NOTIFIER(PTimer, H245Negotiator, HandleTimeout);
00200 
00201     H323EndPoint   & endpoint;
00202     H323Connection & connection;
00203     PTimer           replyTimer;
00204     PMutex           mutex;
00205 };
00206 
00207 
00210 class H245NegMasterSlaveDetermination : public H245Negotiator
00211 {
00212   PCLASSINFO(H245NegMasterSlaveDetermination, H245Negotiator);
00213 
00214   public:
00215     H245NegMasterSlaveDetermination(H323EndPoint & endpoint, H323Connection & connection);
00216 
00217     BOOL Start(BOOL renegotiate);
00218     void Stop();
00219     BOOL HandleIncoming(const H245_MasterSlaveDetermination & pdu);
00220     BOOL HandleAck(const H245_MasterSlaveDeterminationAck & pdu);
00221     BOOL HandleReject(const H245_MasterSlaveDeterminationReject & pdu);
00222     BOOL HandleRelease(const H245_MasterSlaveDeterminationRelease & pdu);
00223     void HandleTimeout(PTimer &, INT);
00224 
00225     BOOL IsMaster() const     { return status == e_DeterminedMaster; }
00226     BOOL IsDetermined() const { return state == e_Idle && status != e_Indeterminate; }
00227 
00228   protected:
00229     BOOL Restart();
00230 
00231     enum States {
00232       e_Idle, e_Outgoing, e_Incoming,
00233       e_NumStates
00234     } state;
00235 #if PTRACING
00236     static const char * GetStateName(States s);
00237     friend ostream & operator<<(ostream & o, States s) { return o << GetStateName(s); }
00238 #endif
00239 
00240     DWORD    determinationNumber;
00241     unsigned retryCount;
00242 
00243     enum MasterSlaveStatus {
00244       e_Indeterminate, e_DeterminedMaster, e_DeterminedSlave,
00245       e_NumStatuses
00246     } status;
00247 #if PTRACING
00248     static const char * GetStatusName(MasterSlaveStatus s);
00249     friend ostream & operator<<(ostream & o , MasterSlaveStatus s) { return o << GetStatusName(s); }
00250 #endif
00251 };
00252 
00253 
00256 class H245NegTerminalCapabilitySet : public H245Negotiator
00257 {
00258   PCLASSINFO(H245NegTerminalCapabilitySet, H245Negotiator);
00259 
00260   public:
00261     H245NegTerminalCapabilitySet(H323EndPoint & endpoint, H323Connection & connection);
00262 
00263     BOOL Start(BOOL renegotiate, BOOL empty = FALSE);
00264     void Stop(BOOL dec = FALSE);
00265     BOOL HandleIncoming(const H245_TerminalCapabilitySet & pdu);
00266     BOOL HandleAck(const H245_TerminalCapabilitySetAck & pdu);
00267     BOOL HandleReject(const H245_TerminalCapabilitySetReject & pdu);
00268     BOOL HandleRelease(const H245_TerminalCapabilitySetRelease & pdu);
00269     void HandleTimeout(PTimer &, INT);
00270 
00271     BOOL HasSentCapabilities() const { return state == e_Sent; }
00272     BOOL HasReceivedCapabilities() const { return receivedCapabilites; }
00273 
00274   protected:
00275     enum States {
00276       e_Idle, e_InProgress, e_Sent,
00277       e_NumStates
00278     } state;
00279 #if PTRACING
00280     static const char * GetStateName(States s);
00281     friend ostream & operator<<(ostream & o, States s) { return o << GetStateName(s); }
00282 #endif
00283 
00284     unsigned inSequenceNumber;
00285     unsigned outSequenceNumber;
00286 
00287     BOOL receivedCapabilites;
00288 };
00289 
00290 
00293 class H245NegLogicalChannel : public H245Negotiator
00294 {
00295   PCLASSINFO(H245NegLogicalChannel, H245Negotiator);
00296 
00297   public:
00298     H245NegLogicalChannel(H323EndPoint & endpoint,
00299                           H323Connection & connection,
00300                           const H323ChannelNumber & channelNumber);
00301     H245NegLogicalChannel(H323EndPoint & endpoint,
00302                           H323Connection & connection,
00303                           H323Channel & channel);
00304     ~H245NegLogicalChannel();
00305 
00306     virtual BOOL Open(
00307       const H323Capability & capability,
00308       unsigned sessionID,
00309       unsigned replacementFor = 0
00310     );
00311     virtual BOOL Close();
00312     virtual BOOL HandleOpen(const H245_OpenLogicalChannel & pdu);
00313     virtual BOOL HandleOpenAck(const H245_OpenLogicalChannelAck & pdu);
00314     virtual BOOL HandleOpenConfirm(const H245_OpenLogicalChannelConfirm & pdu);
00315     virtual BOOL HandleReject(const H245_OpenLogicalChannelReject & pdu);
00316     virtual BOOL HandleClose(const H245_CloseLogicalChannel & pdu);
00317     virtual BOOL HandleCloseAck(const H245_CloseLogicalChannelAck & pdu);
00318     virtual BOOL HandleRequestClose(const H245_RequestChannelClose & pdu);
00319     virtual BOOL HandleRequestCloseAck(const H245_RequestChannelCloseAck & pdu);
00320     virtual BOOL HandleRequestCloseReject(const H245_RequestChannelCloseReject & pdu);
00321     virtual BOOL HandleRequestCloseRelease(const H245_RequestChannelCloseRelease & pdu);
00322     virtual void HandleTimeout(PTimer &, INT);
00323 
00324     H323Channel * GetChannel();
00325 
00326 
00327   protected:
00328     virtual BOOL OpenWhileLocked(
00329       const H323Capability & capability,
00330       unsigned sessionID,
00331       unsigned replacementFor = 0
00332     );
00333     virtual BOOL CloseWhileLocked();
00334     virtual void Release();
00335 
00336 
00337     H323Channel * channel;
00338 
00339     H323ChannelNumber channelNumber;
00340 
00341     enum States {
00342       e_Released,
00343       e_AwaitingEstablishment,
00344       e_Established,
00345       e_AwaitingRelease,
00346       e_AwaitingConfirmation,
00347       e_AwaitingResponse,
00348       e_NumStates
00349     } state;
00350 #if PTRACING
00351     static const char * GetStateName(States s);
00352     friend ostream & operator<<(ostream & o, States s) { return o << GetStateName(s); }
00353 #endif
00354 
00355 
00356   friend class H245NegLogicalChannels;
00357 };
00358 
00359 
00360 PDICTIONARY(H245LogicalChannelDict, H323ChannelNumber, H245NegLogicalChannel);
00361 
00364 class H245NegLogicalChannels : public H245Negotiator
00365 {
00366   PCLASSINFO(H245NegLogicalChannels, H245Negotiator);
00367 
00368   public:
00369     H245NegLogicalChannels(H323EndPoint & endpoint, H323Connection & connection);
00370 
00371     virtual void Add(H323Channel & channel);
00372 
00373     virtual BOOL Open(
00374       const H323Capability & capability,
00375       unsigned sessionID,
00376       unsigned replacementFor = 0
00377     );
00378     virtual BOOL Close(unsigned channelNumber, BOOL fromRemote);
00379     virtual BOOL HandleOpen(const H245_OpenLogicalChannel & pdu);
00380     virtual BOOL HandleOpenAck(const H245_OpenLogicalChannelAck & pdu);
00381     virtual BOOL HandleOpenConfirm(const H245_OpenLogicalChannelConfirm & pdu);
00382     virtual BOOL HandleReject(const H245_OpenLogicalChannelReject & pdu);
00383     virtual BOOL HandleClose(const H245_CloseLogicalChannel & pdu);
00384     virtual BOOL HandleCloseAck(const H245_CloseLogicalChannelAck & pdu);
00385     virtual BOOL HandleRequestClose(const H245_RequestChannelClose & pdu);
00386     virtual BOOL HandleRequestCloseAck(const H245_RequestChannelCloseAck & pdu);
00387     virtual BOOL HandleRequestCloseReject(const H245_RequestChannelCloseReject & pdu);
00388     virtual BOOL HandleRequestCloseRelease(const H245_RequestChannelCloseRelease & pdu);
00389 
00390     H323ChannelNumber GetNextChannelNumber();
00391     PINDEX GetSize() const { return channels.GetSize(); }
00392     H323Channel * GetChannelAt(PINDEX i);
00393     H323Channel * FindChannel(unsigned channelNumber, BOOL fromRemote);
00394     H245NegLogicalChannel & GetNegLogicalChannelAt(PINDEX i);
00395     H245NegLogicalChannel * FindNegLogicalChannel(unsigned channelNumber, BOOL fromRemote);
00396     H323Channel * FindChannelBySession(unsigned rtpSessionId, BOOL fromRemote);
00397     void RemoveAll();
00398 
00399   protected:
00400     H323ChannelNumber      lastChannelNumber;
00401     H245LogicalChannelDict channels;
00402 };
00403 
00404 
00407 class H245NegRequestMode : public H245Negotiator
00408 {
00409   PCLASSINFO(H245NegRequestMode, H245Negotiator);
00410 
00411   public:
00412     H245NegRequestMode(H323EndPoint & endpoint, H323Connection & connection);
00413 
00414     virtual BOOL StartRequest(const PString & newModes);
00415     virtual BOOL StartRequest(const H245_ArrayOf_ModeDescription & newModes);
00416     virtual BOOL HandleRequest(const H245_RequestMode & pdu);
00417     virtual BOOL HandleAck(const H245_RequestModeAck & pdu);
00418     virtual BOOL HandleReject(const H245_RequestModeReject & pdu);
00419     virtual BOOL HandleRelease(const H245_RequestModeRelease & pdu);
00420     virtual void HandleTimeout(PTimer &, INT);
00421 
00422   protected:
00423     BOOL awaitingResponse;
00424     unsigned inSequenceNumber;
00425     unsigned outSequenceNumber;
00426 };
00427 
00428 
00431 class H245NegRoundTripDelay : public H245Negotiator
00432 {
00433   PCLASSINFO(H245NegRoundTripDelay, H245Negotiator);
00434 
00435   public:
00436     H245NegRoundTripDelay(H323EndPoint & endpoint, H323Connection & connection);
00437 
00438     BOOL StartRequest();
00439     BOOL HandleRequest(const H245_RoundTripDelayRequest & pdu);
00440     BOOL HandleResponse(const H245_RoundTripDelayResponse & pdu);
00441     void HandleTimeout(PTimer &, INT);
00442 
00443     PTimeInterval GetRoundTripDelay() const { return roundTripTime; }
00444     BOOL IsRemoteOffline() const { return retryCount == 0; }
00445 
00446   protected:
00447     BOOL          awaitingResponse;
00448     unsigned      sequenceNumber;
00449     PTimeInterval tripStartTime;
00450     PTimeInterval roundTripTime;
00451     unsigned      retryCount;
00452 };
00453 
00454 
00455 #endif // __OPAL_H323NEG_H
00456 
00457 

Generated on Fri Mar 7 06:33:31 2008 for OPAL by  doxygen 1.5.1