Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

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-2000 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 1.34  2002/09/16 01:14:15  robertj
00031  * Added #define so can select if #pragma interface/implementation is used on
00032  *   platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan.
00033  *
00034  * Revision 1.33  2002/09/03 06:19:36  robertj
00035  * Normalised the multi-include header prevention ifdef/define symbol.
00036  *
00037  * Revision 1.32  2002/08/05 10:03:47  robertj
00038  * Cosmetic changes to normalise the usage of pragma interface/implementation.
00039  *
00040  * Revision 1.31  2002/06/26 08:51:16  robertj
00041  * Fixed deadlock if logical channel is closed via H.245 at exactly same
00042  *   time as being closed locally due to a channel I/O error.
00043  *
00044  * Revision 1.30  2002/05/03 03:08:35  robertj
00045  * Added replacementFor field in OLC when resolving conflicting channels.
00046  *
00047  * Revision 1.29  2002/01/09 00:21:36  robertj
00048  * Changes to support outgoing H.245 RequstModeChange.
00049  *
00050  * Revision 1.28  2002/01/01 23:32:30  craigs
00051  * Added HandleAck and StartRequest implementations for T.38
00052  * thanks to Vyacheslav Frolov
00053  *
00054  * Revision 1.27  2002/01/01 23:21:30  craigs
00055  * Added virtual keyword to many functions
00056  *
00057  * Revision 1.26  2001/09/12 01:54:45  robertj
00058  * Added virtual keyword to function in logical channel management.
00059  *
00060  * Revision 1.25  2001/08/06 03:08:11  robertj
00061  * Fission of h323.h to h323ep.h & h323con.h, h323.h now just includes files.
00062  *
00063  * Revision 1.24  2001/05/30 23:34:54  robertj
00064  * Added functions to send TCS=0 for transmitter side pause.
00065  *
00066  * Revision 1.23  2001/03/16 07:11:38  robertj
00067  * Added logical channel open function version without locking.
00068  *
00069  * Revision 1.22  2001/03/14 22:05:24  robertj
00070  * Changed H245NegLogicalChannel::Release() to be virtual protected rather than private.
00071  *
00072  * Revision 1.21  2001/03/14 03:20:25  robertj
00073  * Fixed possible nested mutex deadlock in logical channel negotiator.
00074  *
00075  * Revision 1.20  2001/03/06 04:44:46  robertj
00076  * Fixed problem where could send capability set twice. This should not be
00077  *   a problem except when talking to another broken stack, eg Cisco routers.
00078  *
00079  * Revision 1.19  2001/02/09 05:16:24  robertj
00080  * Added #pragma interface for GNU C++.
00081  *
00082  * Revision 1.18  2000/08/21 12:37:14  robertj
00083  * Fixed race condition if close call just as slow start media channels are opening, part 2.
00084  *
00085  * Revision 1.17  2000/07/14 08:59:56  robertj
00086  * Fixed race condition in closing connection and explicit close logical channel.
00087  *
00088  * Revision 1.16  2000/07/10 16:00:14  robertj
00089  * Added TCS=0 support.
00090  * Fixed bug where negotiations hang if not fast start and tunnelled but remot does not tunnel.
00091  *
00092  * Revision 1.15  2000/05/22 07:32:51  craigs
00093  * Fixed problem with ohphone silence detection hanging
00094  *
00095  * Revision 1.14  2000/05/16 08:13:32  robertj
00096  * Added function to find channel by session ID, supporting H323Connection::FindChannel() with mutex.
00097  *
00098  * Revision 1.13  2000/05/11 04:16:35  robertj
00099  * Fixed missing timeout (and typo!) in bidirectional open logical channel.
00100  *
00101  * Revision 1.12  2000/05/02 04:32:24  robertj
00102  * Fixed copyright notice comment.
00103  *
00104  * Revision 1.11  2000/04/10 17:50:53  robertj
00105  * Fixed yet another race condition needing mutex in logical channels management class.
00106  *
00107  * Revision 1.10  2000/04/05 03:17:30  robertj
00108  * Added more RTP statistics gathering and H.245 round trip delay calculation.
00109  *
00110  * Revision 1.9  2000/03/25 02:19:50  robertj
00111  * Fixed missing mutex call in some logical channels structure access.
00112  *
00113  * Revision 1.8  1999/11/06 11:58:38  robertj
00114  * Changed clean up to delete logical channels before channel destructor is called.
00115  *
00116  * Revision 1.7  1999/11/06 11:00:08  robertj
00117  * Fixed race condition in explicit channel close and connection close.
00118  *
00119  * Revision 1.6  1999/11/06 05:37:44  robertj
00120  * Complete rewrite of termination of connection to avoid numerous race conditions.
00121  *
00122  * Revision 1.5  1999/10/14 12:05:03  robertj
00123  * Fixed deadlock possibilities in clearing calls.
00124  *
00125  * Revision 1.4  1999/09/21 14:03:03  robertj
00126  * Fixed incorrect PTRACING test
00127  *
00128  * Revision 1.3  1999/09/08 04:05:48  robertj
00129  * Added support for video capabilities & codec, still needs the actual codec itself!
00130  *
00131  * Revision 1.2  1999/08/31 12:34:18  robertj
00132  * Added gatekeeper support.
00133  *
00134  * Revision 1.1  1999/08/25 05:07:49  robertj
00135  * File fission (critical mass reached).
00136  *
00137  */
00138 
00139 #ifndef __OPAL_H323NEG_H
00140 #define __OPAL_H323NEG_H
00141 
00142 #ifdef P_USE_PRAGMA
00143 #pragma interface
00144 #endif
00145 
00146 
00147 #include "h323pdu.h"
00148 #include "channels.h"
00149 
00150 
00151 
00153 
00156 class H245Negotiator : public PObject
00157 {
00158   PCLASSINFO(H245Negotiator, PObject);
00159 
00160   public:
00161     H245Negotiator(H323EndPoint & endpoint, H323Connection & connection);
00162 
00163   protected:
00164     PDECLARE_NOTIFIER(PTimer, H245Negotiator, HandleTimeout);
00165 
00166     H323EndPoint   & endpoint;
00167     H323Connection & connection;
00168     PTimer           replyTimer;
00169     PMutex           mutex;
00170 };
00171 
00172 
00175 class H245NegMasterSlaveDetermination : public H245Negotiator
00176 {
00177   PCLASSINFO(H245NegMasterSlaveDetermination, H245Negotiator);
00178 
00179   public:
00180     H245NegMasterSlaveDetermination(H323EndPoint & endpoint, H323Connection & connection);
00181 
00182     BOOL Start(BOOL renegotiate);
00183     void Stop();
00184     BOOL HandleIncoming(const H245_MasterSlaveDetermination & pdu);
00185     BOOL HandleAck(const H245_MasterSlaveDeterminationAck & pdu);
00186     BOOL HandleReject(const H245_MasterSlaveDeterminationReject & pdu);
00187     BOOL HandleRelease(const H245_MasterSlaveDeterminationRelease & pdu);
00188     void HandleTimeout(PTimer &, INT);
00189 
00190     BOOL IsMaster() const     { return status == e_DeterminedMaster; }
00191     BOOL IsDetermined() const { return state == e_Idle && status != e_Indeterminate; }
00192 
00193   protected:
00194     BOOL Restart();
00195 
00196     enum States {
00197       e_Idle, e_Outgoing, e_Incoming,
00198       e_NumStates
00199     } state;
00200 #if PTRACING
00201     static const char * const StateNames[e_NumStates];
00202     friend ostream & operator<<(ostream & o, States s) { return o << StateNames[s]; }
00203 #endif
00204 
00205     DWORD    determinationNumber;
00206     unsigned retryCount;
00207 
00208     enum MasterSlaveStatus {
00209       e_Indeterminate, e_DeterminedMaster, e_DeterminedSlave,
00210       e_NumStatuses
00211     } status;
00212 #if PTRACING
00213     static const char * const StatusNames[e_NumStatuses];
00214     friend ostream & operator<<(ostream & o , MasterSlaveStatus s) { return o << StatusNames[s]; }
00215 #endif
00216 };
00217 
00218 
00221 class H245NegTerminalCapabilitySet : public H245Negotiator
00222 {
00223   PCLASSINFO(H245NegTerminalCapabilitySet, H245Negotiator);
00224 
00225   public:
00226     H245NegTerminalCapabilitySet(H323EndPoint & endpoint, H323Connection & connection);
00227 
00228     BOOL Start(BOOL renegotiate, BOOL empty = FALSE);
00229     void Stop();
00230     BOOL HandleIncoming(const H245_TerminalCapabilitySet & pdu);
00231     BOOL HandleAck(const H245_TerminalCapabilitySetAck & pdu);
00232     BOOL HandleReject(const H245_TerminalCapabilitySetReject & pdu);
00233     BOOL HandleRelease(const H245_TerminalCapabilitySetRelease & pdu);
00234     void HandleTimeout(PTimer &, INT);
00235 
00236     BOOL HasSentCapabilities() const { return state == e_Sent; }
00237     BOOL HasReceivedCapabilities() const { return receivedCapabilites; }
00238 
00239   protected:
00240     enum States {
00241       e_Idle, e_InProgress, e_Sent,
00242       e_NumStates
00243     } state;
00244 #if PTRACING
00245     static const char * const StateNames[e_NumStates];
00246     friend ostream & operator<<(ostream & o, States s) { return o << StateNames[s]; }
00247 #endif
00248 
00249     unsigned inSequenceNumber;
00250     unsigned outSequenceNumber;
00251 
00252     BOOL receivedCapabilites;
00253 };
00254 
00255 
00258 class H245NegLogicalChannel : public H245Negotiator
00259 {
00260   PCLASSINFO(H245NegLogicalChannel, H245Negotiator);
00261 
00262   public:
00263     H245NegLogicalChannel(H323EndPoint & endpoint,
00264                           H323Connection & connection,
00265                           const H323ChannelNumber & channelNumber);
00266     H245NegLogicalChannel(H323EndPoint & endpoint,
00267                           H323Connection & connection,
00268                           H323Channel & channel);
00269     ~H245NegLogicalChannel();
00270 
00271     virtual BOOL Open(
00272       const H323Capability & capability,
00273       unsigned sessionID,
00274       unsigned replacementFor = 0
00275     );
00276     virtual BOOL Close();
00277     virtual BOOL HandleOpen(const H245_OpenLogicalChannel & pdu);
00278     virtual BOOL HandleOpenAck(const H245_OpenLogicalChannelAck & pdu);
00279     virtual BOOL HandleOpenConfirm(const H245_OpenLogicalChannelConfirm & pdu);
00280     virtual BOOL HandleReject(const H245_OpenLogicalChannelReject & pdu);
00281     virtual BOOL HandleClose(const H245_CloseLogicalChannel & pdu);
00282     virtual BOOL HandleCloseAck(const H245_CloseLogicalChannelAck & pdu);
00283     virtual BOOL HandleRequestClose(const H245_RequestChannelClose & pdu);
00284     virtual BOOL HandleRequestCloseAck(const H245_RequestChannelCloseAck & pdu);
00285     virtual BOOL HandleRequestCloseReject(const H245_RequestChannelCloseReject & pdu);
00286     virtual BOOL HandleRequestCloseRelease(const H245_RequestChannelCloseRelease & pdu);
00287     virtual void HandleTimeout(PTimer &, INT);
00288 
00289     H323Channel * GetChannel();
00290 
00291 
00292   protected:
00293     virtual BOOL OpenWhileLocked(
00294       const H323Capability & capability,
00295       unsigned sessionID,
00296       unsigned replacementFor = 0
00297     );
00298     virtual BOOL CloseWhileLocked();
00299     virtual void Release();
00300 
00301 
00302     H323Channel * channel;
00303 
00304     H323ChannelNumber channelNumber;
00305 
00306     enum States {
00307       e_Released,
00308       e_AwaitingEstablishment,
00309       e_Established,
00310       e_AwaitingRelease,
00311       e_AwaitingConfirmation,
00312       e_AwaitingResponse,
00313       e_NumStates
00314     } state;
00315 #if PTRACING
00316     static const char * const StateNames[e_NumStates];
00317     friend ostream & operator<<(ostream & o, States s) { return o << StateNames[s]; }
00318 #endif
00319 
00320 
00321   friend class H245NegLogicalChannels;
00322 };
00323 
00324 
00325 PDICTIONARY(H245LogicalChannelDict, H323ChannelNumber, H245NegLogicalChannel);
00326 
00329 class H245NegLogicalChannels : public H245Negotiator
00330 {
00331   PCLASSINFO(H245NegLogicalChannels, H245Negotiator);
00332 
00333   public:
00334     H245NegLogicalChannels(H323EndPoint & endpoint, H323Connection & connection);
00335 
00336     virtual void Add(H323Channel & channel);
00337 
00338     virtual BOOL Open(
00339       const H323Capability & capability,
00340       unsigned sessionID,
00341       unsigned replacementFor = 0
00342     );
00343     virtual BOOL Close(unsigned channelNumber, BOOL fromRemote);
00344     virtual BOOL HandleOpen(const H245_OpenLogicalChannel & pdu);
00345     virtual BOOL HandleOpenAck(const H245_OpenLogicalChannelAck & pdu);
00346     virtual BOOL HandleOpenConfirm(const H245_OpenLogicalChannelConfirm & pdu);
00347     virtual BOOL HandleReject(const H245_OpenLogicalChannelReject & pdu);
00348     virtual BOOL HandleClose(const H245_CloseLogicalChannel & pdu);
00349     virtual BOOL HandleCloseAck(const H245_CloseLogicalChannelAck & pdu);
00350     virtual BOOL HandleRequestClose(const H245_RequestChannelClose & pdu);
00351     virtual BOOL HandleRequestCloseAck(const H245_RequestChannelCloseAck & pdu);
00352     virtual BOOL HandleRequestCloseReject(const H245_RequestChannelCloseReject & pdu);
00353     virtual BOOL HandleRequestCloseRelease(const H245_RequestChannelCloseRelease & pdu);
00354 
00355     H323ChannelNumber GetNextChannelNumber();
00356     PINDEX GetSize() const { return channels.GetSize(); }
00357     H323Channel * GetChannelAt(PINDEX i);
00358     H323Channel * FindChannel(unsigned channelNumber, BOOL fromRemote);
00359     H245NegLogicalChannel & GetNegLogicalChannelAt(PINDEX i);
00360     H245NegLogicalChannel * FindNegLogicalChannel(unsigned channelNumber, BOOL fromRemote);
00361     H323Channel * FindChannelBySession(unsigned rtpSessionId, BOOL fromRemote);
00362     void RemoveAll();
00363 
00364   protected:
00365     H323ChannelNumber      lastChannelNumber;
00366     H245LogicalChannelDict channels;
00367 };
00368 
00369 
00372 class H245NegRequestMode : public H245Negotiator
00373 {
00374   PCLASSINFO(H245NegRequestMode, H245Negotiator);
00375 
00376   public:
00377     H245NegRequestMode(H323EndPoint & endpoint, H323Connection & connection);
00378 
00379     virtual BOOL StartRequest(const PString & newModes);
00380     virtual BOOL StartRequest(const H245_ArrayOf_ModeDescription & newModes);
00381     virtual BOOL HandleRequest(const H245_RequestMode & pdu);
00382     virtual BOOL HandleAck(const H245_RequestModeAck & pdu);
00383     virtual BOOL HandleReject(const H245_RequestModeReject & pdu);
00384     virtual BOOL HandleRelease(const H245_RequestModeRelease & pdu);
00385     virtual void HandleTimeout(PTimer &, INT);
00386 
00387   protected:
00388     BOOL awaitingResponse;
00389     unsigned inSequenceNumber;
00390     unsigned outSequenceNumber;
00391 };
00392 
00393 
00396 class H245NegRoundTripDelay : public H245Negotiator
00397 {
00398   PCLASSINFO(H245NegRoundTripDelay, H245Negotiator);
00399 
00400   public:
00401     H245NegRoundTripDelay(H323EndPoint & endpoint, H323Connection & connection);
00402 
00403     BOOL StartRequest();
00404     BOOL HandleRequest(const H245_RoundTripDelayRequest & pdu);
00405     BOOL HandleResponse(const H245_RoundTripDelayResponse & pdu);
00406     void HandleTimeout(PTimer &, INT);
00407 
00408     PTimeInterval GetRoundTripDelay() const { return roundTripTime; }
00409     BOOL IsRemoteOffline() const { return retryCount == 0; }
00410 
00411   protected:
00412     BOOL          awaitingResponse;
00413     unsigned      sequenceNumber;
00414     PTimeInterval tripStartTime;
00415     PTimeInterval roundTripTime;
00416     unsigned      retryCount;
00417 };
00418 
00419 
00420 #endif // __OPAL_H323NEG_H
00421 
00422 

Generated on Mon Sep 26 15:44:46 2005 for OpenH323 by  doxygen 1.4.4