home *** CD-ROM | disk | FTP | other *** search
/ ftp.muug.mb.ca / 2014.06.ftp.muug.mb.ca.tar / ftp.muug.mb.ca / pub / openh323.tar.gz / openh323.tar / openh323 / include / h323neg.h < prev    next >
C/C++ Source or Header  |  2002-09-15  |  14KB  |  424 lines

  1. /*
  2.  * h323neg.h
  3.  *
  4.  * H.323 protocol handler
  5.  *
  6.  * Open H323 Library
  7.  *
  8.  * Copyright (c) 1998-2000 Equivalence Pty. Ltd.
  9.  *
  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/
  14.  *
  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.
  19.  *
  20.  * The Original Code is Open H323 Library.
  21.  *
  22.  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
  23.  *
  24.  * Portions of this code were written with the assisance of funding from
  25.  * Vovida Networks, Inc. http://www.vovida.com.
  26.  *
  27.  * Contributor(s): ______________________________________.
  28.  *
  29.  * $Log: h323neg.h,v $
  30.  * Revision 1.34  2002/09/16 01:14:15  robertj
  31.  * Added #define so can select if #pragma interface/implementation is used on
  32.  *   platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan.
  33.  *
  34.  * Revision 1.33  2002/09/03 06:19:36  robertj
  35.  * Normalised the multi-include header prevention ifdef/define symbol.
  36.  *
  37.  * Revision 1.32  2002/08/05 10:03:47  robertj
  38.  * Cosmetic changes to normalise the usage of pragma interface/implementation.
  39.  *
  40.  * Revision 1.31  2002/06/26 08:51:16  robertj
  41.  * Fixed deadlock if logical channel is closed via H.245 at exactly same
  42.  *   time as being closed locally due to a channel I/O error.
  43.  *
  44.  * Revision 1.30  2002/05/03 03:08:35  robertj
  45.  * Added replacementFor field in OLC when resolving conflicting channels.
  46.  *
  47.  * Revision 1.29  2002/01/09 00:21:36  robertj
  48.  * Changes to support outgoing H.245 RequstModeChange.
  49.  *
  50.  * Revision 1.28  2002/01/01 23:32:30  craigs
  51.  * Added HandleAck and StartRequest implementations for T.38
  52.  * thanks to Vyacheslav Frolov
  53.  *
  54.  * Revision 1.27  2002/01/01 23:21:30  craigs
  55.  * Added virtual keyword to many functions
  56.  *
  57.  * Revision 1.26  2001/09/12 01:54:45  robertj
  58.  * Added virtual keyword to function in logical channel management.
  59.  *
  60.  * Revision 1.25  2001/08/06 03:08:11  robertj
  61.  * Fission of h323.h to h323ep.h & h323con.h, h323.h now just includes files.
  62.  *
  63.  * Revision 1.24  2001/05/30 23:34:54  robertj
  64.  * Added functions to send TCS=0 for transmitter side pause.
  65.  *
  66.  * Revision 1.23  2001/03/16 07:11:38  robertj
  67.  * Added logical channel open function version without locking.
  68.  *
  69.  * Revision 1.22  2001/03/14 22:05:24  robertj
  70.  * Changed H245NegLogicalChannel::Release() to be virtual protected rather than private.
  71.  *
  72.  * Revision 1.21  2001/03/14 03:20:25  robertj
  73.  * Fixed possible nested mutex deadlock in logical channel negotiator.
  74.  *
  75.  * Revision 1.20  2001/03/06 04:44:46  robertj
  76.  * Fixed problem where could send capability set twice. This should not be
  77.  *   a problem except when talking to another broken stack, eg Cisco routers.
  78.  *
  79.  * Revision 1.19  2001/02/09 05:16:24  robertj
  80.  * Added #pragma interface for GNU C++.
  81.  *
  82.  * Revision 1.18  2000/08/21 12:37:14  robertj
  83.  * Fixed race condition if close call just as slow start media channels are opening, part 2.
  84.  *
  85.  * Revision 1.17  2000/07/14 08:59:56  robertj
  86.  * Fixed race condition in closing connection and explicit close logical channel.
  87.  *
  88.  * Revision 1.16  2000/07/10 16:00:14  robertj
  89.  * Added TCS=0 support.
  90.  * Fixed bug where negotiations hang if not fast start and tunnelled but remot does not tunnel.
  91.  *
  92.  * Revision 1.15  2000/05/22 07:32:51  craigs
  93.  * Fixed problem with ohphone silence detection hanging
  94.  *
  95.  * Revision 1.14  2000/05/16 08:13:32  robertj
  96.  * Added function to find channel by session ID, supporting H323Connection::FindChannel() with mutex.
  97.  *
  98.  * Revision 1.13  2000/05/11 04:16:35  robertj
  99.  * Fixed missing timeout (and typo!) in bidirectional open logical channel.
  100.  *
  101.  * Revision 1.12  2000/05/02 04:32:24  robertj
  102.  * Fixed copyright notice comment.
  103.  *
  104.  * Revision 1.11  2000/04/10 17:50:53  robertj
  105.  * Fixed yet another race condition needing mutex in logical channels management class.
  106.  *
  107.  * Revision 1.10  2000/04/05 03:17:30  robertj
  108.  * Added more RTP statistics gathering and H.245 round trip delay calculation.
  109.  *
  110.  * Revision 1.9  2000/03/25 02:19:50  robertj
  111.  * Fixed missing mutex call in some logical channels structure access.
  112.  *
  113.  * Revision 1.8  1999/11/06 11:58:38  robertj
  114.  * Changed clean up to delete logical channels before channel destructor is called.
  115.  *
  116.  * Revision 1.7  1999/11/06 11:00:08  robertj
  117.  * Fixed race condition in explicit channel close and connection close.
  118.  *
  119.  * Revision 1.6  1999/11/06 05:37:44  robertj
  120.  * Complete rewrite of termination of connection to avoid numerous race conditions.
  121.  *
  122.  * Revision 1.5  1999/10/14 12:05:03  robertj
  123.  * Fixed deadlock possibilities in clearing calls.
  124.  *
  125.  * Revision 1.4  1999/09/21 14:03:03  robertj
  126.  * Fixed incorrect PTRACING test
  127.  *
  128.  * Revision 1.3  1999/09/08 04:05:48  robertj
  129.  * Added support for video capabilities & codec, still needs the actual codec itself!
  130.  *
  131.  * Revision 1.2  1999/08/31 12:34:18  robertj
  132.  * Added gatekeeper support.
  133.  *
  134.  * Revision 1.1  1999/08/25 05:07:49  robertj
  135.  * File fission (critical mass reached).
  136.  *
  137.  */
  138.  
  139. #ifndef __OPAL_H323NEG_H
  140. #define __OPAL_H323NEG_H
  141.  
  142. #ifdef P_USE_PRAGMA
  143. #pragma interface
  144. #endif
  145.  
  146.  
  147. #include "h323pdu.h"
  148. #include "channels.h"
  149.  
  150.  
  151.  
  152. ///////////////////////////////////////////////////////////////////////////////
  153.  
  154. /**Base class for doing H245 negotiations
  155.  */
  156. class H245Negotiator : public PObject
  157. {
  158.   PCLASSINFO(H245Negotiator, PObject);
  159.  
  160.   public:
  161.     H245Negotiator(H323EndPoint & endpoint, H323Connection & connection);
  162.  
  163.   protected:
  164.     PDECLARE_NOTIFIER(PTimer, H245Negotiator, HandleTimeout);
  165.  
  166.     H323EndPoint   & endpoint;
  167.     H323Connection & connection;
  168.     PTimer           replyTimer;
  169.     PMutex           mutex;
  170. };
  171.  
  172.  
  173. /**Determine the master and slave on a H245 connection as per H245 section 8.2
  174.  */
  175. class H245NegMasterSlaveDetermination : public H245Negotiator
  176. {
  177.   PCLASSINFO(H245NegMasterSlaveDetermination, H245Negotiator);
  178.  
  179.   public:
  180.     H245NegMasterSlaveDetermination(H323EndPoint & endpoint, H323Connection & connection);
  181.  
  182.     BOOL Start(BOOL renegotiate);
  183.     void Stop();
  184.     BOOL HandleIncoming(const H245_MasterSlaveDetermination & pdu);
  185.     BOOL HandleAck(const H245_MasterSlaveDeterminationAck & pdu);
  186.     BOOL HandleReject(const H245_MasterSlaveDeterminationReject & pdu);
  187.     BOOL HandleRelease(const H245_MasterSlaveDeterminationRelease & pdu);
  188.     void HandleTimeout(PTimer &, INT);
  189.  
  190.     BOOL IsMaster() const     { return status == e_DeterminedMaster; }
  191.     BOOL IsDetermined() const { return state == e_Idle && status != e_Indeterminate; }
  192.  
  193.   protected:
  194.     BOOL Restart();
  195.  
  196.     enum States {
  197.       e_Idle, e_Outgoing, e_Incoming,
  198.       e_NumStates
  199.     } state;
  200. #if PTRACING
  201.     static const char * const StateNames[e_NumStates];
  202.     friend ostream & operator<<(ostream & o, States s) { return o << StateNames[s]; }
  203. #endif
  204.  
  205.     DWORD    determinationNumber;
  206.     unsigned retryCount;
  207.  
  208.     enum MasterSlaveStatus {
  209.       e_Indeterminate, e_DeterminedMaster, e_DeterminedSlave,
  210.       e_NumStatuses
  211.     } status;
  212. #if PTRACING
  213.     static const char * const StatusNames[e_NumStatuses];
  214.     friend ostream & operator<<(ostream & o , MasterSlaveStatus s) { return o << StatusNames[s]; }
  215. #endif
  216. };
  217.  
  218.  
  219. /**Exchange capabilities on a H245 connection as per H245 section 8.3
  220.  */
  221. class H245NegTerminalCapabilitySet : public H245Negotiator
  222. {
  223.   PCLASSINFO(H245NegTerminalCapabilitySet, H245Negotiator);
  224.  
  225.   public:
  226.     H245NegTerminalCapabilitySet(H323EndPoint & endpoint, H323Connection & connection);
  227.  
  228.     BOOL Start(BOOL renegotiate, BOOL empty = FALSE);
  229.     void Stop();
  230.     BOOL HandleIncoming(const H245_TerminalCapabilitySet & pdu);
  231.     BOOL HandleAck(const H245_TerminalCapabilitySetAck & pdu);
  232.     BOOL HandleReject(const H245_TerminalCapabilitySetReject & pdu);
  233.     BOOL HandleRelease(const H245_TerminalCapabilitySetRelease & pdu);
  234.     void HandleTimeout(PTimer &, INT);
  235.  
  236.     BOOL HasSentCapabilities() const { return state == e_Sent; }
  237.     BOOL HasReceivedCapabilities() const { return receivedCapabilites; }
  238.  
  239.   protected:
  240.     enum States {
  241.       e_Idle, e_InProgress, e_Sent,
  242.       e_NumStates
  243.     } state;
  244. #if PTRACING
  245.     static const char * const StateNames[e_NumStates];
  246.     friend ostream & operator<<(ostream & o, States s) { return o << StateNames[s]; }
  247. #endif
  248.  
  249.     unsigned inSequenceNumber;
  250.     unsigned outSequenceNumber;
  251.  
  252.     BOOL receivedCapabilites;
  253. };
  254.  
  255.  
  256. /**Logical Channel signalling on a H245 connection as per H245 section 8.4
  257.  */
  258. class H245NegLogicalChannel : public H245Negotiator
  259. {
  260.   PCLASSINFO(H245NegLogicalChannel, H245Negotiator);
  261.  
  262.   public:
  263.     H245NegLogicalChannel(H323EndPoint & endpoint,
  264.                           H323Connection & connection,
  265.                           const H323ChannelNumber & channelNumber);
  266.     H245NegLogicalChannel(H323EndPoint & endpoint,
  267.                           H323Connection & connection,
  268.                           H323Channel & channel);
  269.     ~H245NegLogicalChannel();
  270.  
  271.     virtual BOOL Open(
  272.       const H323Capability & capability,
  273.       unsigned sessionID,
  274.       unsigned replacementFor = 0
  275.     );
  276.     virtual BOOL Close();
  277.     virtual BOOL HandleOpen(const H245_OpenLogicalChannel & pdu);
  278.     virtual BOOL HandleOpenAck(const H245_OpenLogicalChannelAck & pdu);
  279.     virtual BOOL HandleOpenConfirm(const H245_OpenLogicalChannelConfirm & pdu);
  280.     virtual BOOL HandleReject(const H245_OpenLogicalChannelReject & pdu);
  281.     virtual BOOL HandleClose(const H245_CloseLogicalChannel & pdu);
  282.     virtual BOOL HandleCloseAck(const H245_CloseLogicalChannelAck & pdu);
  283.     virtual BOOL HandleRequestClose(const H245_RequestChannelClose & pdu);
  284.     virtual BOOL HandleRequestCloseAck(const H245_RequestChannelCloseAck & pdu);
  285.     virtual BOOL HandleRequestCloseReject(const H245_RequestChannelCloseReject & pdu);
  286.     virtual BOOL HandleRequestCloseRelease(const H245_RequestChannelCloseRelease & pdu);
  287.     virtual void HandleTimeout(PTimer &, INT);
  288.  
  289.     H323Channel * GetChannel();
  290.  
  291.  
  292.   protected:
  293.     virtual BOOL OpenWhileLocked(
  294.       const H323Capability & capability,
  295.       unsigned sessionID,
  296.       unsigned replacementFor = 0
  297.     );
  298.     virtual BOOL CloseWhileLocked();
  299.     virtual void Release();
  300.  
  301.  
  302.     H323Channel * channel;
  303.  
  304.     H323ChannelNumber channelNumber;
  305.  
  306.     enum States {
  307.       e_Released,
  308.       e_AwaitingEstablishment,
  309.       e_Established,
  310.       e_AwaitingRelease,
  311.       e_AwaitingConfirmation,
  312.       e_AwaitingResponse,
  313.       e_NumStates
  314.     } state;
  315. #if PTRACING
  316.     static const char * const StateNames[e_NumStates];
  317.     friend ostream & operator<<(ostream & o, States s) { return o << StateNames[s]; }
  318. #endif
  319.  
  320.  
  321.   friend class H245NegLogicalChannels;
  322. };
  323.  
  324.  
  325. PDICTIONARY(H245LogicalChannelDict, H323ChannelNumber, H245NegLogicalChannel);
  326.  
  327. /**Dictionary of all Logical Channels
  328.  */
  329. class H245NegLogicalChannels : public H245Negotiator
  330. {
  331.   PCLASSINFO(H245NegLogicalChannels, H245Negotiator);
  332.  
  333.   public:
  334.     H245NegLogicalChannels(H323EndPoint & endpoint, H323Connection & connection);
  335.  
  336.     virtual void Add(H323Channel & channel);
  337.  
  338.     virtual BOOL Open(
  339.       const H323Capability & capability,
  340.       unsigned sessionID,
  341.       unsigned replacementFor = 0
  342.     );
  343.     virtual BOOL Close(unsigned channelNumber, BOOL fromRemote);
  344.     virtual BOOL HandleOpen(const H245_OpenLogicalChannel & pdu);
  345.     virtual BOOL HandleOpenAck(const H245_OpenLogicalChannelAck & pdu);
  346.     virtual BOOL HandleOpenConfirm(const H245_OpenLogicalChannelConfirm & pdu);
  347.     virtual BOOL HandleReject(const H245_OpenLogicalChannelReject & pdu);
  348.     virtual BOOL HandleClose(const H245_CloseLogicalChannel & pdu);
  349.     virtual BOOL HandleCloseAck(const H245_CloseLogicalChannelAck & pdu);
  350.     virtual BOOL HandleRequestClose(const H245_RequestChannelClose & pdu);
  351.     virtual BOOL HandleRequestCloseAck(const H245_RequestChannelCloseAck & pdu);
  352.     virtual BOOL HandleRequestCloseReject(const H245_RequestChannelCloseReject & pdu);
  353.     virtual BOOL HandleRequestCloseRelease(const H245_RequestChannelCloseRelease & pdu);
  354.  
  355.     H323ChannelNumber GetNextChannelNumber();
  356.     PINDEX GetSize() const { return channels.GetSize(); }
  357.     H323Channel * GetChannelAt(PINDEX i);
  358.     H323Channel * FindChannel(unsigned channelNumber, BOOL fromRemote);
  359.     H245NegLogicalChannel & GetNegLogicalChannelAt(PINDEX i);
  360.     H245NegLogicalChannel * FindNegLogicalChannel(unsigned channelNumber, BOOL fromRemote);
  361.     H323Channel * FindChannelBySession(unsigned rtpSessionId, BOOL fromRemote);
  362.     void RemoveAll();
  363.  
  364.   protected:
  365.     H323ChannelNumber      lastChannelNumber;
  366.     H245LogicalChannelDict channels;
  367. };
  368.  
  369.  
  370. /**Request mode change as per H245 section 8.9
  371.  */
  372. class H245NegRequestMode : public H245Negotiator
  373. {
  374.   PCLASSINFO(H245NegRequestMode, H245Negotiator);
  375.  
  376.   public:
  377.     H245NegRequestMode(H323EndPoint & endpoint, H323Connection & connection);
  378.  
  379.     virtual BOOL StartRequest(const PString & newModes);
  380.     virtual BOOL StartRequest(const H245_ArrayOf_ModeDescription & newModes);
  381.     virtual BOOL HandleRequest(const H245_RequestMode & pdu);
  382.     virtual BOOL HandleAck(const H245_RequestModeAck & pdu);
  383.     virtual BOOL HandleReject(const H245_RequestModeReject & pdu);
  384.     virtual BOOL HandleRelease(const H245_RequestModeRelease & pdu);
  385.     virtual void HandleTimeout(PTimer &, INT);
  386.  
  387.   protected:
  388.     BOOL awaitingResponse;
  389.     unsigned inSequenceNumber;
  390.     unsigned outSequenceNumber;
  391. };
  392.  
  393.  
  394. /**Request mode change as per H245 section 8.9
  395.  */
  396. class H245NegRoundTripDelay : public H245Negotiator
  397. {
  398.   PCLASSINFO(H245NegRoundTripDelay, H245Negotiator);
  399.  
  400.   public:
  401.     H245NegRoundTripDelay(H323EndPoint & endpoint, H323Connection & connection);
  402.  
  403.     BOOL StartRequest();
  404.     BOOL HandleRequest(const H245_RoundTripDelayRequest & pdu);
  405.     BOOL HandleResponse(const H245_RoundTripDelayResponse & pdu);
  406.     void HandleTimeout(PTimer &, INT);
  407.  
  408.     PTimeInterval GetRoundTripDelay() const { return roundTripTime; }
  409.     BOOL IsRemoteOffline() const { return retryCount == 0; }
  410.  
  411.   protected:
  412.     BOOL          awaitingResponse;
  413.     unsigned      sequenceNumber;
  414.     PTimeInterval tripStartTime;
  415.     PTimeInterval roundTripTime;
  416.     unsigned      retryCount;
  417. };
  418.  
  419.  
  420. #endif // __OPAL_H323NEG_H
  421.  
  422.  
  423. /////////////////////////////////////////////////////////////////////////////
  424.