windows-nt/Source/XPSP1/NT/net/rras/ip/nath323/cbridge.h
2020-09-26 16:20:57 +08:00

1458 lines
28 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1998 - 2000 Microsoft Corporation
Module Name:
cbridge.cpp
Abstract:
Contains the call bridge class declaration.
Associated Q931 and H245 protocol stack related classes
and constants are also declared here.
Revision History:
1. created
Byrisetty Rajeev (rajeevb) 12-Jun-1998
2. moved several inline functions to q931.cpp, h245.cpp
(rajeevb, 21-Aug-1998)
--*/
#ifndef __h323ics_call_bridge_h
#define __h323ics_call_bridge_h
/*---------------------------------------------------
DESIGN OVERVIEW:
The CALL_BRIDGE completely describes an H.323 call being proxied. The
proxy receives a call from the source and then originates a call
to the destination. Each of these calls is represented by an H323_STATE.
PDUs received on one call are processed and passed on to the other call.
A source leads an H.323 call with Q.931. The SETUP PDU contains info for
the proxy to locate the destination. The two end points exchange their
H.245 channel addresses at this stage. This portion of the call is
encapsulated in Q931_INFO. *The proxy must replace any end-point address
and port with its own address and port to protect internal corporate
addresses and retain control of the multi-layered H.323 call setup*.
The H.245 channel is used to exchange end-point capabilities. This
information is of no significance today (in future, security exchanges
etc. may be done). H245_INFO represents an H.245 channel end-point. We
merely pass on the source/destination PDUs.
The H.245 channel is used to maintain (open, close) logical channels.
The logical channel messages exchange end-point address and port to
send audio/video media to. These addresses/ports are replaced with the
proxy's address/ports. Each logical channel is represented by a
LOGICAL_CHANNEL instance. An H245_INFO instance contains an array of
LOGICAL_CHANNELs which were originated from the corresponding client
end-point. Hence, all of the logical channel related state is contained
in a single LOGICAL_CHANNEL instance (unlike two instances for the
Q931_INFO and H245_INFO which have a SOURCE and DEST instance).
Audio/video media are sent in RTP streams (with RTCP for control info).
The proxy uses NAT to forward these packets after replacing the
source and destination address/port.
CLASS HIERARCHY :
The Q931_INFO and H323_INFO classes need to make overlapped calls to
accept connections, send and receive data. The OVERLAPPED_PROCESSOR
provides call back methods to the event manager and completely
encapsulates the socket representing a connection. Both Q931_INFO and
H323_INFO are derived from it and pass themselves as OVERLAPPED_PROCESSOR
to the event manager while registering callbacks.
When making an overlapped call, a context is also passed in. This context
enables the caller to retrieve relevant information when the corresponding
callback is received. The EVENT_MANAGER_CONTEXT provides the base class
abstraction for the callback context. Q931/H245 Source/Dest instances
derive their own contexts from this base class (for storing their state).
The Q931_INFO and H323_INFO classes need to create and cancel timers. The
TIMER_PROCESSOR provides call back methods to the event manager and
helper methods for this.
Both SOURCE and DEST versions are derived from the base classes for
Q931_INFO, H245_INFO and H323_STATE. While the states and transitions
for H.245 (for the proxy) are more or less symmetric, those for Q.931
are quite different. A SOURCE_H323_STATE contains a SOURCE_Q931_INFO and
a SOURCE_H245_INFO (similarly for the DEST version).
A CALL_BRIDGE contains a SOURCE_H323_STATE and a DEST_H323_STATE. Hence
all the Q931, H245 and generic data is stored in a single memory block for
the CALL_BRIDGE. Additional memory is needed for the LOGICAL_CHANNEL_ARRAY
(one per H245_INFO instance) and each of the LOGICAL_CHANNEL instances. There
might be a better way to allocate this memory to reduce memory allocations/freeing.
A single critical section protects all accesses to a CALL_BRIDGE and
is acquired inside the CALL_BRIDGE method being called. The CALL_BRIDGE
also destroys itself when it is appropriate and releases the critical
section before doing so (The CALL_BRIDGE cannot get called at such a point)
SCALABILITY ISSUES :
1. We currently use a single critical section per instance of the CALL_BRIDGE.
This is clearly not scalable to a large number of connections. We plan
to use dynamic critical sections for this. This involves using a pool of
critical sections and a critical section from the pool is assigned to
a CALL_BRIDGE instance dynamically.
2. We currently need 4 ports (RTP/RTCP send/receive) for each of the two
calls being bridged in a CALL_BRIDGE for a total of 8 ports per
proxied call. This also means that we would need a socket for each of
the ports to actually reserve the port. The following approaches will
make this scalable -
* AjayCh is talking with NKSrin for an IOCTL to the TCP/IP stack for
reserving a pool of ports at a time (just like memory). This would
thus preclude any need for keeeping a socket open just for reserving
a port and reduce the number of calls needed to do so.
* The TCP/IP stack treats ports as global objects and would make the
reserved port unavailable on ALL interfaces. However, a port can be
reused several times as long as it satisfies the unique 5tuple
requirement for sockets
(protocol, src addr, src port, dest addr, dest port). We can reuse
the allocated port in the following ways -
** for each interface on the machine.
** for each different remote end-point address/port pairs
---------------------------------------------------*/
/*---------------------------------------------------
NOTES:
1. Typically, constructors are avoided and replaced by Init fns as
they can return error codes.
2. The attempt is to convert all error codes to HRESULTs as early in
the execution as possible.
3. Separate heaps are used for different classes. This reduces heap
contention as well as fragmentation. This is done by over-riding
new/delete.
4. inline fns are used where
- a virtual fn is not needed
- amount of code is small AND/OR
- number of calls to the fn is few (1-2).
since some inline fn definitions involve calling other inline
functions, there are several dependencies among the classes
declared below. This forces declaration of all these classes
in a single header file.
5. We need to count all outstanding overlapped calls and make sure
there are none before destroying a CALL_BRIDGE instance (to avoid
avs when the event manager calls back and to release the associated
contexts). We try to keep track of all this inside the CALL_BRIDGE
centrally.
6. We try to maintain the abstraction of two separate calls being bridged
as far as possible. As a convention, methods processing PDUs/messages
directly received from a socket start with "Handle". These methods pass
on the received PDU/message to the "other" H245 or Q931 instance (for the
bridged call). The "other" methods which process these start with
"Process". They decide whether or not the PDU/message must be sent to
the other end-point.
7. NAT has problems with unidirectional redirects. If a unidirectional
redirect X is setup and we later try to setup a unidirectional redirect
Y in the reverse direction that shares all the parameters of X, NAT
exhibits undefined behaviour. This is solved by the following steps -
* We only setup unidirectional redirects. Thus, RTCP requires 2
separate redirects.
* Logical channel signaling only exchanges addresses/ports to receive
media on. We exploit that by using different ports for sending and
receiving media.
8. We have tried to restrict the use of virtual functions and use inline
functions wherever possible. Proliferation of short virtual fns can
result in performance problems.
9. Overlapped callbacks pass in H245, Q931 pdus that were read along
with the corresponding context. We follow a flexible convention for
freeing them -
* if the callback or any called method frees them or reuses
them for sending out the opposite end, it sets them to null.
* if not set to null on return, the event manager which called the
callback frees these.
10. Currently all state transitions are in code (ex.
if current state == b1, current state = b2 etc.). Its usually
better to do this in data (ex. an array {current state, new state}).
However, I haven't been able to figure out an appropriate model for
this so far.
11. Commenting doesn't have the NT standard blocks explaining each fn,
parameters, return code etc. I have instead, written a small block of
comments at the top of the function when appropriate. I have also tried
to comment logical blocks of code.
---------------------------------------------------*/
#include "sockinfo.h"
#include "q931info.h"
#include "logchan.h"
#include "h245info.h"
#include "ipnatapi.h"
// Call state description - one side of a call
class H323_STATE
{
public:
inline
H323_STATE (
void
);
// initialize when a tcp connection is established on a listening
// interface
inline
void
Init (
IN CALL_BRIDGE &CallBridge,
IN Q931_INFO &Q931Info,
IN H245_INFO &H245Info,
IN BOOL fIsSource // source call state iff TRUE
);
inline
CALL_BRIDGE &
GetCallBridge (
void
);
inline
BOOL
IsSourceCall (
void
);
inline
Q931_INFO &
GetQ931Info (
void
);
inline
H245_INFO &
GetH245Info (
void
);
inline
H323_STATE &
GetOtherH323State (
void
);
protected:
// it belongs to this call bridge
CALL_BRIDGE *m_pCallBridge;
// TRUE iff its the source call state
BOOL m_fIsSourceCall;
// contains the Q931 tcp info, timeout, remote end info
Q931_INFO *m_pQ931Info;
// contains the H.245 tcp info, timeout, remote end info
H245_INFO *m_pH245Info;
};
/*++
Routine Description:
Constructor for H323_STATE class
Arguments:
None
Return Values:
None
Notes:
--*/
inline
H323_STATE::H323_STATE (
void
)
: m_pCallBridge (
NULL
),
m_fIsSourceCall (
FALSE
),
m_pQ931Info(
NULL
),
m_pH245Info(
NULL)
{
} // H323_STATE::H323_STATE
inline
void
H323_STATE::Init (
IN CALL_BRIDGE &CallBridge,
IN Q931_INFO &Q931Info,
IN H245_INFO &H245Info,
IN BOOL fIsSource
)
/*++
Routine Description:
Initializes an instance of H323_STATE class
Arguments:
CallBridge -- parent call-bridge
Q931Info -- contained Q931 information
H245Info -- contained H245 information
fIsSource -- TRUE if this is source call state, FALSE otherwise
Return Values:
None
Notes:
--*/
{
_ASSERTE(NULL == m_pCallBridge);
_ASSERTE(NULL == m_pQ931Info);
_ASSERTE(NULL == m_pH245Info);
m_pCallBridge = &CallBridge;
m_pQ931Info = &Q931Info;
m_pH245Info = &H245Info;
m_fIsSourceCall = fIsSource;
} // H323_STATE::Init
inline
CALL_BRIDGE &
H323_STATE::GetCallBridge (
void
)
/*++
Routine Description:
Accessor method
Arguments:
None
Return Values:
Reference to the parent call-bridge
Notes:
--*/
{
_ASSERTE(NULL != m_pCallBridge);
return *m_pCallBridge;
} // H323_STATE::GetCallBridge
inline
BOOL
H323_STATE::IsSourceCall (
void
)
/*++
Routine Description:
Accessor method
Arguments:
None
Return Values:
Indication of whether this is a source
call state, or destination call state
Notes:
--*/
{
return m_fIsSourceCall;
} // H323_STATE::IsSourceCall
inline
Q931_INFO &
H323_STATE::GetQ931Info (
void
)
/*++
Routine Description:
Accessor method
Arguments:
None
Return Values:
Reference to the contained Q.931 information
Notes:
--*/
{
_ASSERTE(NULL != m_pQ931Info);
return *m_pQ931Info;
} // H323_STATE::GetQ931Info
inline
H245_INFO &
H323_STATE::GetH245Info (
void
)
/*++
Routine Description:
Accessor method
Arguments:
None
Return Values:
Reference to the contained H.245 information
Notes:
--*/
{
_ASSERTE(NULL != m_pH245Info);
return *m_pH245Info;
} // H323_STATE::GetH245Info
// Source call state description - one side of a call
class SOURCE_H323_STATE :
public H323_STATE
{
public:
// initialize when a tcp connection is established on a listening
// interface
inline
void
Init (
IN CALL_BRIDGE &CallBridge
);
inline
SOURCE_Q931_INFO &
GetSourceQ931Info (
void
);
inline
SOURCE_H245_INFO &
GetSourceH245Info (
void
);
inline
DEST_H323_STATE &
GetDestH323State (
void
);
protected:
// contains the source Q931 tcp info, timeout, remote end info
SOURCE_Q931_INFO m_SourceQ931Info;
// contains the H.245 tcp info, timeout, remote end info
SOURCE_H245_INFO m_SourceH245Info;
};
inline
void
SOURCE_H323_STATE::Init (
IN CALL_BRIDGE &CallBridge
)
/*++
Routine Description:
Initialize H323 state when a tcp connection is established
on a listening interface
Arguments:
CallBridge -- "parent" call-bridge
Return Values:
None
Notes:
--*/
{
m_SourceQ931Info.Init(*this);
m_SourceH245Info.Init(*this);
H323_STATE::Init(
CallBridge,
m_SourceQ931Info,
m_SourceH245Info,
TRUE
);
} // SOURCE_H323_STATE::Init
inline
SOURCE_Q931_INFO &
SOURCE_H323_STATE::GetSourceQ931Info (
void
)
/*++
Routine Description:
Accessor method
Arguments:
None
Return Values:
None
Notes:
Retrieves a reference to the contained Q.931 information
--*/
{
return m_SourceQ931Info;
} // SOURCE_H323_STATE::GetSourceQ931Info
inline
SOURCE_H245_INFO &
SOURCE_H323_STATE::GetSourceH245Info (
void
)
/*++
Routine Description:
Accessor method
Arguments:
None
Return Values:
None
Notes:
Retrieves a reference to the contained H.245 information
--*/
{
return m_SourceH245Info;
} // SOURCE_H323_STATE::GetSourceH245Info
// Destination call state description - one side of a call
class DEST_H323_STATE :
public H323_STATE
{
public:
inline
DEST_H323_STATE (
void
);
// initialize when a tcp connection is established on a listening
// interface
inline
HRESULT Init (
IN CALL_BRIDGE &CallBridge
);
inline
DEST_Q931_INFO &
GetDestQ931Info (
void
);
inline
DEST_H245_INFO &
GetDestH245Info (
void
);
inline
SOURCE_H323_STATE &
GetSourceH323State (
void);
protected:
// contains the destination Q931 tcp info, timeout, remote end info
DEST_Q931_INFO m_DestQ931Info;
// contains the H.245 tcp info, timeout, remote end info
DEST_H245_INFO m_DestH245Info;
};
inline
DEST_H323_STATE::DEST_H323_STATE (
void
)
/*++
Routine Description:
Constructor for DEST_H323_STATE class
Arguments:
None
Return Values:
None
Notes:
--*/
{
} // DEST_H323_STATE::DEST_H323_STATE
inline
HRESULT
DEST_H323_STATE::Init (
IN CALL_BRIDGE &CallBridge
)
/*++
Routine Description:
Initialize instance of DEST_H323_STATE when a tcp connection
is established on a listening interface
Arguments:
CallBridge -- reference to the "parent" call-bridge
Return Values:
S_OK if successful
Otherwise passes through status code of initializing contained sockets
Notes:
--*/
{
HRESULT HResult = m_DestQ931Info.Init(*this);
if (FAILED(HResult))
{
return HResult;
}
_ASSERTE(S_FALSE != HResult);
m_DestH245Info.Init(*this);
H323_STATE::Init(
CallBridge,
m_DestQ931Info,
m_DestH245Info,
FALSE
);
return S_OK;
} // DEST_H323_STATE::Init (
inline
DEST_Q931_INFO &
DEST_H323_STATE::GetDestQ931Info (
void
)
/*++
Routine Description:
Accessor method
Arguments:
None
Return Values:
Retrieves reference to the contained Q.931 information
Notes:
--*/
{
return m_DestQ931Info;
} // DEST_H323_STATE::GetDestQ931Info (
inline
DEST_H245_INFO &
DEST_H323_STATE::GetDestH245Info (
void
)
/*++
Routine Description:
Accessor method
Arguments:
None
Return Values:
Retrieves reference to the contained H.245 information
Notes:
--*/
{
return m_DestH245Info;
} // DEST_H323_STATE::GetDestH245Info
// The CALL_BRIDGE represents an active call that is being proxied.
// Number of outstanding i/os is stored only in the call bridge instance
// it is only needed to determine when the call bridge instance can safely
// be shut down
class CALL_BRIDGE :
public SIMPLE_CRITICAL_SECTION_BASE,
public LIFETIME_CONTROLLER
{
public:
enum STATE {
STATE_NONE,
STATE_CONNECTED,
STATE_TERMINATED,
};
protected:
STATE State;
// call state info for the source side. i.e. the side which
// sends the Setup packet
SOURCE_H323_STATE m_SourceH323State;
SOCKADDR_IN SourceAddress; // address of the source (originator of the connection)
DWORD SourceInterfaceAddress; // address of the interface on which the connection was accepted, host order
// call state info for the destination side. i.e. the recipient
// of the setup packet
DEST_H323_STATE m_DestH323State;
SOCKADDR_IN DestinationAddress; // address of the destination (recipient of the connection)
public:
DWORD DestinationInterfaceAddress; // address of the interface to which the connection is destined, host order
private:
HRESULT
InitializeLocked (
IN SOCKET IncomingSocket,
IN SOCKADDR_IN * LocalAddress,
IN SOCKADDR_IN * RemoteAddress,
IN NAT_KEY_SESSION_MAPPING_EX_INFORMATION * RedirectInformation
);
public:
CALL_BRIDGE (
IN NAT_KEY_SESSION_MAPPING_EX_INFORMATION * RedirectInformation
);
~CALL_BRIDGE (
void
);
// initialize member call state instances
HRESULT
Initialize (
IN SOCKET IncomingSocket,
IN SOCKADDR_IN * LocalAddress,
IN SOCKADDR_IN * RemoteAddress ,
IN NAT_KEY_SESSION_MAPPING_EX_INFORMATION * RedirectInformation
);
DWORD
GetSourceInterfaceAddress (
void
) const;
VOID
CALL_BRIDGE::GetSourceAddress (
OUT SOCKADDR_IN* ReturnSourceAddress
);
void
GetDestinationAddress (
OUT SOCKADDR_IN * ReturnDestinationAddress
);
// this function may be called by any thread that holds a safe,
// counted reference to this object.
void
TerminateExternal (
void
);
BOOL
IsConnectionThrough (
IN DWORD InterfaceAddress // host order
);
void
OnInterfaceShutdown (
void
);
// private:
friend class Q931_INFO;
friend class H245_INFO;
friend class SOURCE_H245_INFO;
friend class DEST_H245_INFO;
friend class LOGICAL_CHANNEL;
inline
BOOL
IsTerminated (
void
);
inline
BOOL
IsTerminatedExternal (
void
);
inline
void
CancelAllTimers (
void
);
void
TerminateCallOnReleaseComplete (
void
);
void
Terminate (
void
);
inline
SOURCE_H323_STATE &
GetSourceH323State (
void
);
inline
DEST_H323_STATE &
GetDestH323State (
void
);
};
inline
void
CALL_BRIDGE::CancelAllTimers (
void
)
/*++
Routine Description:
Cancels outstanding timers for all H.245 logical channels and Q.931 connections
Arguments:
None
Return Values:
None
Notes:
--*/
{
m_SourceH323State.GetQ931Info().TimprocCancelTimer();
m_DestH323State.GetQ931Info().TimprocCancelTimer();
GetSourceH323State().GetH245Info().GetLogicalChannelArray().CancelAllTimers();
GetDestH323State().GetH245Info().GetLogicalChannelArray().CancelAllTimers();
} // CALL_BRIDGE::CancelAllTimers
inline
BOOL
CALL_BRIDGE::IsTerminated (
void
)
/*++
Routine Description:
Checks whether the instance is terminated.
Arguments:
None
Return Values:
TRUE - if the instance is terminated
FALSE - if the instance is not terminated
Notes:
1. To be called for locked instance only
--*/
{
return State == STATE_TERMINATED;
} // CALL_BRIDGE::IsTerminated
inline
BOOL
CALL_BRIDGE::IsTerminatedExternal (
void
)
/*++
Routine Description:
Checks whether the instance is terminated
Arguments:
None
Return Values:
TRUE - if the instance is terminated
FALSE - if the instance is not terminated
Notes:
--*/
{
BOOL IsCallBridgeTerminated = TRUE;
Lock ();
IsCallBridgeTerminated = IsTerminated ();
Unlock ();
return IsCallBridgeTerminated;
} // CALL_BRIDGE::IsTerminatedExternal
inline
SOURCE_H323_STATE &
CALL_BRIDGE::GetSourceH323State (
void
)
/*++
Routine Description:
Accessor function
Arguments:
None
Return Values:
Retrieves reference to the source H.323 state
Notes:
--*/
{
return m_SourceH323State;
} // CALL_BRIDGE::GetSourceH323State
inline
DEST_H323_STATE &
CALL_BRIDGE::GetDestH323State (
void
)
/*++
Routine Description:
Accessor function
Arguments:
None
Return Values:
Retrieves reference to the destination H.323 state
Notes:
--*/
{
return m_DestH323State;
} // CALL_BRIDGE::GetDestH323State
///////////////////////////////////////////////////////////////////////////////
// //
// Misc. inline functions that require declarations //
// which are made after them //
// //
///////////////////////////////////////////////////////////////////////////////
//
// OVERLAPPED_PROCESSOR
inline
CALL_BRIDGE &
OVERLAPPED_PROCESSOR::GetCallBridge (
void
)
/*++
Routine Description:
Accessor method
Arguments:
None
Return Values:
Reference to the call-bridge for this
overlapped processor
Notes:
--*/
{
return m_pH323State->GetCallBridge();
} // OVERLAPPED_PROCESSOR::GetCallBridge
inline
CALL_REF_TYPE
Q931_INFO::GetCallRefVal (
void
)
/*++
Routine Description:
Accessor method
Arguments:
None
Return Values:
Reference value for the call
Notes:
--*/
{
return m_CallRefVal;
} // Q931_INFO::GetCallRefVal
inline
HRESULT
SOURCE_Q931_INFO::SetIncomingSocket (
IN SOCKET IncomingSocket,
IN SOCKADDR_IN * LocalAddress,
IN SOCKADDR_IN * RemoteAddress
)
/*++
Routine Description:
Socket initialization
Arguments:
IncomingSocket -- socket on which connection was accepted
LocalAddress -- address of the local side of the connection
RemoteAddress -- address of the remote side of the connection
Return Values:
Result of issuing an async receive
Notes:
--*/
{
assert (IncomingSocket != INVALID_SOCKET);
assert (m_pH323State->IsSourceCall());
assert (Q931_SOURCE_STATE_INIT == m_Q931SourceState);
m_SocketInfo.Init(
IncomingSocket,
LocalAddress,
RemoteAddress);
m_Q931SourceState = Q931_SOURCE_STATE_CON_ESTD;
return QueueReceive();
} // SOURCE_Q931_INFO::SetIncomingSocket
inline
DEST_Q931_INFO &
SOURCE_Q931_INFO::GetDestQ931Info (
void
)
/*++
Routine Description:
Accessor method
Arguments:
None
Return Values:
Reference to the destination Q.931 information
Notes:
--*/
{
return ((SOURCE_H323_STATE *)m_pH323State)->GetDestH323State().GetDestQ931Info();
} // SOURCE_Q931_INFO::GetDestQ931Info
inline
SOURCE_H245_INFO &
SOURCE_Q931_INFO::GetSourceH245Info (
void
)
/*++
Routine Description:
Accessor method
Arguments:
None
Return Values:
Reference to the source H.245 information
Notes:
--*/
{
return ((SOURCE_H323_STATE *)m_pH323State)->GetSourceH245Info();
} // SOURCE_Q931_INFO::GetSourceH245Info
inline
SOURCE_Q931_INFO &
DEST_Q931_INFO::GetSourceQ931Info (
void
)
/*++
Routine Description:
Accessor method
Arguments:
None
Return Values:
Reference to the source Q.931 information
Notes:
--*/
{
return ((DEST_H323_STATE *)m_pH323State)->GetSourceH323State().GetSourceQ931Info();
} // DEST_Q931_INFO::GetSourceQ931Info
inline
DEST_H245_INFO &
DEST_Q931_INFO::GetDestH245Info (
void
)
/*++
Routine Description:
Accessor method
Arguments:
None
Return Values:
Reference to the source Q.931 information
Notes:
--*/
{
return ((DEST_H323_STATE *)m_pH323State)->GetDestH245Info();
} // DEST_Q931_INFO::GetDestH245Info
inline
CALL_BRIDGE &
LOGICAL_CHANNEL::GetCallBridge (
void
)
/*++
Routine Description:
Accessor method
Arguments:
None
Return Values:
Reference to the "parent" call-bridge
Notes:
--*/
{
return GetH245Info().GetCallBridge();
} // LOGICAL_CHANNEL::GetCallBridge
inline
void
LOGICAL_CHANNEL::DeleteAndRemoveSelf (
void
)
/*++
Routine Description:
Remove logical channel from the array of those,
and terminate it.
Arguments:
None
Return Values:
None
Notes:
--*/
{
// remove self from the logical channel array
m_pH245Info->GetLogicalChannelArray().Remove(*this);
TimprocCancelTimer ();
// destroy self
delete this;
} // LOGICAL_CHANNEL::DeleteAndRemoveSelf
inline
H245_INFO &
H245_INFO::GetOtherH245Info (
void
)
/*++
Routine Description:
Accessor function
Arguments:
None
Return Values:
"The other" H.245 information (source for destination, and
destination for source)
Notes:
--*/
{
return GetH323State().GetOtherH323State().GetH245Info();
} // H245_INFO::GetOtherH245Info (
inline
SOURCE_Q931_INFO &
SOURCE_H245_INFO::GetSourceQ931Info (
void
)
/*++
Routine Description:
Accessor function
Arguments:
None
Return Values:
Retrieves source Q.931 information
Notes:
--*/
{
return ((SOURCE_H323_STATE *)m_pH323State)->GetSourceQ931Info();
} // SOURCE_H245_INFO::GetSourceQ931Info
inline
DEST_H245_INFO &
SOURCE_H245_INFO::GetDestH245Info (
void
)
/*++
Routine Description:
Accessor function
Arguments:
None
Return Values:
Retrieves destination H.245 information
Notes:
--*/
{
return ((SOURCE_H323_STATE *)m_pH323State)->GetDestH323State().GetDestH245Info();
} // SOURCE_H245_INFO::GetDestH245Info
inline
DEST_Q931_INFO &
DEST_H245_INFO::GetDestQ931Info (
void
)
/*++
Routine Description:
Accessor function
Arguments:
None
Return Values:
Retrieves destination Q.931 information
Notes:
--*/
{
return ((DEST_H323_STATE *)m_pH323State)->GetDestQ931Info();
} // DEST_H245_INFO::GetDestQ931Info
inline
H323_STATE &
H323_STATE::GetOtherH323State (
void
)
/*++
Routine Description:
Accessor function
Arguments:
None
Return Values:
Retrieves "the other" H.323 state (source for destination, and
destination for source)
Notes:
--*/
{
return (TRUE == m_fIsSourceCall)?
(H323_STATE &)m_pCallBridge->GetDestH323State() :
(H323_STATE &)m_pCallBridge->GetSourceH323State();
} // H323_STATE::GetOtherH323State
inline
DEST_H323_STATE &
SOURCE_H323_STATE::GetDestH323State (
void
)
/*++
Routine Description:
Accessor function
Arguments:
None
Return Values:
Retrieves destination H.323 information
Notes:
--*/
{
return GetCallBridge().GetDestH323State();
} // SOURCE_H323_STATE::GetDestH323State
inline SOURCE_H323_STATE &
DEST_H323_STATE::GetSourceH323State (
void
)
/*++
Routine Description:
Accessor function
Arguments:
None
Return Values:
Retrieves source H.323 information
Notes:
--*/
{
return GetCallBridge().GetSourceH323State();
} // DEST_H323_STATE::GetSourceH323State
#endif // __h323ics_call_bridge_h