1. High level design

[hld.dia]

SIP-H.323 gateway consists of 2 high level components: (1) call translator, and
(2) gatekeeper. Call translator is responsible for translating of call
signalling and call control messages between H.323 and SIP. Gatekeeper
registers H.323 terminals and translates RAS registration messages to
SIP Register command. Translator and gatekeeper are working in different
threads and use asynchronous messages for communication.

SIP proxy is a component used to receive/transmit SIP messages. There are
2 instances of this component in the system: one is used by both gatekeeper
and call translator (for incoming calls); other is used only by call translator
for outgoing calls. Gatekeeper and translator use asynchronous messages to
interact with proxy.

H.323 router is a component that implements H.323 stack: it provides basic
call signalling and call control procedures for call translator. Router works
in the thread of call translator and uses synchronous messages to send
information to call translator. Call translator directly accesses router's
methods and members to control it.

OpenH323 library is used by gatekeeper, translator, and router to encode/decode
Q.931, RAS, and H.245 messages.

The last component if gateway is mte library. It provides infrastructure for
translator and router components.

2. Infrastructure

Call translator and router work in single thread. In idle state these
components are inactive. When some connection, incoming message, external
event, or timer arrive - control is passed from transport library to one
of protocol objects or to one of event observers. Or, in other words,
"minithread" is started. Then incoming connection, message, event, or timer
are transformed to uniform "event" object which is used everywhere in router
or translator. During processing of an event, another (synchronous) event may
be started. Therefore "minithreads" may consist of one or more "events".
mte template library is created to work with these "minithread" and "event"
entities, that explains its name.

mte library uses several concepts that should be explained:

Event - everybody knows what does it mean; there is only one detail that
    distinguishes mte Events: classes that implement these events not only
    contain some data associated with event, but they also have methods used
    to process event (number of these methods is equal to number of states
    in all state machines working with this event).

State Machine (SM) - some object with relatively long lifetime which works as
    "target" for events. State Machine consists of one or several Features.
    Examples of State Machine are call and H.245 logical channel.

Feature - part of State Machine responsible for some separate activity or
    procedure, like call signalling or master-slave determination. Feature
    class contains exactly one state variable (which is used to select
    event handling method from any Event associated with this Feature).

Connection - object that is used by State Machine object to send or receive
    messages of some kind (for example, 'Call' object may use 'ConnectionH245'
    to send/receive H.245 messages and 'ConnectionQ931' to send/receive Q.931
    messages). State Machine will directly access Connection to send a message.
    To be able to receive messages State Machine will register its Connections
    to correspondent 'Router' objects.

Router - object where Connections are registered. All incoming events are sent
    to Routers where some identification information is extracted from the
    event and used to find correspondent Connection. If server is expecting
    several kinds of incoming messages or events (RAS, SIP, Q931, ...) it
    creates separate Router object for each of them.

Secondary event source (Ses) - is used to create Event objects. In fact it
    converts some messages or external events (created by some 'primary'
    source) to Event objects, that's why it is 'secondary'.

[mteObjects.dia]

Events may be directly associated with some Connection object (direct events).
In this case Ses and Route are not needed. In other cases (routed events)
each Event is created by Secondary event source from some message. To make it
possible, Event's prototypes should be registered to Ses. Each time Ses
receives external message it extracts tag information from there and uses it
to clone proper Event from its prototype. Then it fills in Event data and
assigns pointer to some Router to the Event. Then it starts the Event.

When event is started, it immediately passes control to assigned Router or
Connection (depending on type of event: routed or direct). Router extracts
identification information from event and uses it to search correspondent
Connection. Finally Connection passes pointer to the State Machine back
to the Event.

Then Event passes control to one or more Features in given State Machine.
Feature uses its state variable to select one of the Event's methods and calls
it. Initially this state variable is usually set to 'inIdle' state which means
that 'inIdle' method of the first incoming Event will be called. Then, most
likely, inside this method, Feature::setState(inWait) will be called to
change the state. In this case next Event coming to the same Feature will
result in calling 'inWait' method of this Event, and so on. Such methods
of Event object will be called event handlers, their name will always start
from 'in' prefix because it means "handle Event 'in' some state".

Event handler may perform any action appropriate for given event and given
state. In many cases it will change current state by calling Feature::setState.
Also it may access any public members of correspondent 'Feature' object because
reference to this object is passed to each event handler as parameter. Also
this reference may be used to access State Machine - by getSM() method.
Event handler may send a message to one of the Connections assigned to State
Machine.

[mteClasses.dia]

mte class diagram uses following notes to distinguish different kinds of
classes:
#Event - user-defined class (not part of the library)
*Base - group of classes in mte library
Feature - separate class in mte library

Event class hierarchy consists of 2 main parts: source part and destination
part. Source part (starting from EvtTimer, *Cloned, #EvtMessages) is used
to store class data and identification information; also it contains 'start'
method which starts event processing. Destination part (starting from
EvtRouted or EvtDirect) is used to route event to State Machine and provides
event handlers for each state in each Feature.

*EvtBind group of classes is used to bind source and destination parts of the
event. Top level #Event classes are derived from one of the *EvtBind classes.

*Base group consists of 2 classes:
1. BEvent
2. TEvent

BEvent class provides start() method that is used to start event processing.
TEvent template's difference from BEvent is only in its base class. It is
derived from its template argument and hence allows whole Event hierarchy
to be derived from any class provided by any 3rd party library.

EventPtr class encapsulates pointer to Event. It adds some convenience in
calling start() method: if pointer is non-zero, it just calls start() from
*Base; if pointer is empty, it does nothing.

*Cloned group consists of 3 classes:
1. EventStatic
2. EventDynamic
3. EventRefCnt

Each class in this group is derived from *Base and provides 2 additional
methods: clone() and destroy(). Clone method creates new Event from its
prototype, destroy() destroys Event created by clone(). EventDynamic
provides exactly this functionality, EventRefCnt optimizes memory allocation -
it copies only the initial prototype but does not make a copy if used on
already cloned event, EventStatic does not make a copy for events - it
returns pointer to prototype instead. First 2 classes require derived class to
provide clone_impl() method which will actually make a copy.

Ses class is a base for secondary event sources. It allows to register
Event prototype and it clones appropriate event from one of prototypes on
some message or external event.

#EvtMessages classes may contain any data and identification information for
the Event. They are derived from *Cloned.

EvtTimer is similar to #EvtMessages but provides event identifier for timers
in FifoBase and some functionality needed for timer events.

EvtRouted is used to bind its base classes (*EvtRouter and *EvtSM).
It implements Event routing procedure where Router and Connection objects
are used to determine pointer to the State Machine. On context of this
State Machine Event will be processed.

Router is base class for Router object(s). It allows to register Connection
objects. When it is necessary to process an Event, Router uses identification
information from this Event to find appropriate Connection object.

Connection is base class for Connection object(s). Its only functionality is
to provide accessor returning pointer to State Machine. Connection is derived
from Event identifier which is used by Router to find Connection object.

*EvtRouter group consists of 2 classes:
1. EvtRouter
2. EvtRouter2
This group of classes determines actual routing algorithm. These classes
pass control to one (for EvtRouter) or more (for EvtRouter2) Router objects
where appropriate Connection will be found. Then Connection will pass control
back to *EvtRouter (precisely, to its base class, IEvtRouter), but at this
time pointer to the State Machine is already known so *EvtRouter just
passes this address to its derived class, EvtRouted.

EvtRouter2 uses one Router to determine some State Machine which is not yet
ultimate destination of the Event, this State Machine is used to get secondary
Router object. Then this secondary Router is used to determine ultimate
State Machine. An example (and only practical use) of this class is routing
of H.245 logical channel messages: here first Router will provide Call
state machine which contains Router for logical channels. Then this Router
is used to find Logical Channel state machine where Event will be processed.

IEvtRouter is base class for *EvtRouter. It provides interface for Connection
object. This interface allows to pass pointer to State Machine to *EvtRouter.

EvtDirect class is similar to EvtRouted but it does not use Router to find
State Machine. Pointer to the State Machine is assigned to EvtDirect in its
constructor. EvtDirect has only one base class (*EvtSM). It immediately
passes control to this base class and provides it with State Machine pointer.

*EvtSM group consists of 2 classes:
1. EvtSM1
2. EvtSM2
These classes work as binders for 1 or 2 of their base classes.
Their base classes are instantiations of EvtFeature template.
EvtSM1 does not add anything to its base class, EvtFeature.
EvtSM2 binds 2 EvtFeature instances. Its only function is to pass control
sequentially to each base class.

#SM is a State Machine class. It is not part of the mte library. The only
requirement for this class is that it should contain one or more Feature
classes and for each of them it must provide a method returning reference
to Feature object.

EvtFeature class has pointer to member function of the #SM class as one if
template parameters. It applies this pointer to member to State Machine object
and obtains pointer to Feature object. Then it just passes control to this
Feature object. EvtFeature is derived from #Pattern.

#Pattern is a user-defined class which contains stubs for all event handling
methods (which will be provided in the top level #Event class). These stubs
are used by Feature object to invoke appropriate event handler. These
stubs may perform some default action for event handler, in most cases they
just call a default event handler stub (inOther()). #Pattern is derived from
PatternBase.

PatternBase works as a base class for event Patterns. It contains a default
event handler (inOtherState()). This event handler and he class are reserved
for future extensions.

#Feature is a user-defined class. It may contain any data and methods needed
to implement Feature. There is one requirement for this class: it must be
derived from Feature class and must implement process_impl() method. The
implementation of this method must invoke event handler determined by Event
pointer and current state.

Feature class provides several methods needed to control Feature object: it
allows to change current state and to set entry/exit handlers. Entry/exit
handlers are classes derived from EvtFeature and providing the same set of
handlers as any Event. Entry handler for some state is invoked entry to this
state. Exit handler for some state is invoked on exit from this state.

*EvtBind group consists of 2 classes:
1. EvtBind1
2. EvtBind11
EvtBind1 binds source and destination parts of the event. EvtBind11 binds
additional destination part to complete event. This may be used when the
same event should be processed in 2 components and one of these components
is independent from other one. Example is EvtSetup event which is used by
router and EvtTrSetup derived from EvtSetup and used in translator.


				  +---------+
                                  |EvtBind11|
				  +---------+
				      /  \
				     /    \
				    /      \
				   v        v
			    +--------+     +----+
			    |EvtBind1|     |dst2|
			    +--------+     +----+
			       /  \
			      /    \
			     /      \
			    v        v
			 +---+     +----+
			 |src|     |dst1|
			 +---+     +----+

3. H.323 router

H.323 router is based on mte library so most of classes in its implementation
are derived from mte classes or related to mte (State Machines, Connections,
Routers, Ses, Features, Events). There are also several classes that are used
to integrate router with (1) transport library and (2) any component that will
use router.

Classes used for integration with transport library:
- TimerEventObserver
- several Protocol classes

Classes used for integration with translator (or possibly some other high-level
component):
- H323CallFactory

Classes in H.323 router may be divided by number of instances. There are
several classes with single instance:
- TimerEventObserver
- several Protocol classes
- H323CallFactory
- Call Control and Call Signalling Routers
- Secondary Event Sources for Q.931 and H.245 events
- Event prototypes

Some other classes have exactly one object for a call:
- Call State Machine and all Features that are part of this State Machine
- Call Signalling and Call Control Connections
- Routers for Logical Channel State Machines (one for incoming channels and
  one for outgoing channels)

Several classes have one instance for each Logical Channel:
- Logical Channel State Machines
- Logical Channel Connections

Event classes usually have only no more than one instance because router is
single-threaded component and at any time there may be only one event processed
(or, possibly several nested events if one event synchronously starts other
event). There are several exceptions. Timer events usually have one instance
per Feature. Also "call-back" events may be registered by high-level component
(translator) so that router may asynchronously inform translator if something
changes. Each Feature may contain from zero to several "call-back" events.

[router.dia]

Call class is the most important part of H.323 router. It implements
State Machine for a call and contains the following Features:
- FeatureCallSig (call signalling)
- FeatureCallCtlSession (call control session: this feature controls state
  of call control session - is it opened, closed, or will be closed soon)
- FeatureCEI (capability exchange for incoming capability set)
- FeatureCEO (capability exchange for outgoing capability set)
- FeatureMsd (master slave determination procedure)
- FeatureRTD (round-trip delay procedure)
- FeatureAcceptCC (feature controlling process of control channel opening from
  remote side)
- FeatureOpenCC (feature controlling process of control channel opening from
  local side)

Most of these features are described as H.245 procedures in H.245 standard.
Exceptions are: FeatureCallSig, FeatureCallCtlSession, FeatureAcceptCC,
FeatureOpenCC. State diagrams for them may be found in doc/router directory.

Some of these features use timers. All such timers are started and stopped
automatically when relevant state is entered/exited. Entry/exit handlers are
used do do this (Entry* and Exit* classes).

TimerEventObserver class is used to start correspondent event when any timer
expires.

Q931ProtocolBase is intended to pass all Q.931-related messages to Call
Signalling event source (SesQ931).

Q931Protocol class is derived from Q931ProtocolBase and adds functionality
for one special case: when no Call State Machine is yet created which may
handle incoming message. H323CallFactory abstract class is used to create
Call State Machine. Implementation of this call factory is provided by
higher-level component (translator).

Q931ServerProtocol is used to create Q931Protocol objects for incoming
TCP connections. Q931ProtocolBase is created by Call for outgoing TCP
connections.

SesQ931, RouterCallSig, and ConnectionCallSig classes just implement Ses,
Router, and Connection for Call Signalling events.

H245Protocol is intended to pass all H.245-related messages to Call
Control event source (SesH245). Call State Machine creates H245Protocol
for outgoing TCP connections. H245ServerProtocol creates it for incoming
connections.

SesH245, RouterCallCtl, and ConnectionCallCl classes just implement Ses,
Router, and Connection for Call Control events.

LCI and LCO are State Machines needed to maintain Logical Channels (incoming
and outgoing).

ConnectionLCI, ConnectionLCO, RouterLCI, RouterLCO classes just implement
Router and Connection for Logical Channel events. These events are generated
by SesH245 as any other Call Control event. Though they are routed by both
RouterCallCtl and one of the LC routers. RouterLCI has one additional
responsibility: it creates LCI State Machine for new Logical Channels.

4. Call translator

Call translator is based on mte library. The following translator classes
are related to mte: TrCall (call State Machine), Features, Events, Connections,
Routers, SesSIP (SIP event source).

Classes used for integration with transport library:
- RasEventObserver
- SIPEventObserver

Classes used for integration with H.323 router:
- TrCallFactory, TrCallFactoryImp (factory for TrCall objects)
- TrSMMediator (used to pass Events from router to translator module)

Implementation classes (used internally by translator and not dependent on
mte, router, or transport libraries):
- Contacts (used to store contact list and implement redirect feature)
- CapabilityMap (a subset of translator classes needed to translate
  capabilities and Logical Channel parameters between H.245 and SDP formats)
- Address and several related classes (to translate aliases or addresses)

These translator classes have single instance:
- H323CallTranslator
- Event Observers (RasEventObserver, SIPEventObserver)
- SesSIP
- Event Routers (TrRouterSIP, TrRouterRas)
- TrCallFactoryImp
- Event prototypes

The following classes have one instance per call:
- TrCall (call State Machine)
- Connections (TrConnectionRas, TrConnectionSIP, TrConnectionSDP)
- Contacts
- CapabilityMap
- TrSMMediator

There are several classes with larger number of instances: Contact (element
of the contact list), some parts of the Capability Map.

Number of instances for Event classes may be equal to the number of calls
for some call-back events or 1 for other events.

[translator.dia]

H323CallTranslator is a container for all single instance classes of translator
and router components: Event Observers, Protocols, Event Sources and Routers,
Event prototypes and call factory. It is responsible for initialization and
shutdown of call translator component.

TrCall class implements State Machine for a call and contains the following
Features:
- FeatureTrCallSig (call signalling)
- FeatureTrMediaH2S (media translation for the calls from H.323 to SIP)
- FeatureTrMediaS2H (media translation for the calls from SIP to H.323)
State diagrams for this state machines may be found in doc/translator
directory.

TrCallFactoryImp is used to create every instance of TrCall. Its base class
(TrCallFactory) provides interface for the translator components for
creating TrCall objects.

TrCallFactory is derived from router::H323CallFactory which provides interface
for the H.323 router components for creating TrCall objects.

RasEventObserver class is used to start correspondent event when RAS event is
received from the gatekeeper. Currently there is only one RAS event: EvtTrACF.

TrRouterRas is used to route incoming RAS event to some call State Machine.
Call identifier (consisting from H.323 call ID and conference ID) of incoming
RAS message is compared with call identifiers of all RAS Connections to
perform this routing.

TrConnectionRas is used as Connection for RAS events. It contains call
identifier needed for router and send() method to pass RAS events to the
gatekeeper.

SipEventObserver converts external events from one of the SIP proxy components
to the Event used internally by translator. SIP CallID and SIP proxy address
are stored as identification information for the Event and used by TrRouterSIP
to find appropriate call object. The same SIP CallID may be used to route
SIP Events to 2 different call State Machines if call is both originated and
terminated by some H.323 terminal and routed through sip-h323 translator twice.

TrConnectionSIP works as Connection for SIP events. Also it extracts SDP
messages from SIP events and passes them to TrConnectionSDP.

TrConnectionSDP allows to send SDP messages. It only stores outgoing SDP
message in SIP Connection object. So that SDP message will be actually sent
with the next outgoing SIP message.

Several events are coming to translator from H.323 router. All these events
are handled by some H.323 router State Machine before they come to translator.
Initially all these events are routed to some H.323 router Connection and
address of the translator's call object is unknown for them because
router component is independent from translator. To solve this problem
TrSMMediator class is used. It contains address of the TrCall object.
Address of the object of TrSMMediator's base class (mte::Mediator) is known
to the router's Call object and is used in the updateRoute() method in
every Event.

5. Example (handling 'Setup' message)

Q.931 Setup message is coming from Q931Protocol object in the router component.
At this time call object is not yet created so the first thing done by
Q931Protocol is to create call object. This is done with help of
H323CallFactory interface of TrCallFactoryImp object.

After call object is created, setup message is passed to SesQ931. It extracts
tag information from the Setup message and uses it to find any registered
Event with the same tag. H323CallTranslator has already registered only one
such event: EvtTrSetup. SesQ931 then clones this object, fills it with
message data and identification information (address of call signalling
connection in this case), and finally calls start() method of the Event.

start() method is implemented by EvtBind11 template. At the first step it
calls process() method of its base class (EvtSetup) where it is processed
by router component, then EvtBind11 calls updateRoute method (implemented
by EvtTrSetup) to obtain TrCall's address, and finally it calls process()
method from its 'destination' part to process it by the translator component.

Here is the sequence of H323 router and mte classes that sequentially handle
this Event:
- EvtRouted
- ErtRouter
- RouterCallSig (finds pointer to ConnectionCallSig)
- ConnectionCallSig
- IEvtRouter (now call State Machine address is known)
- EvtRouter
- EvtRouted
- EvtSM1
- EvtFeature (here the address of Feature is obtained)
- Feature
- FeatureCallSig
- PatternCallSig (the address of FeatureCallSig is known)
- EvtSetup (inIdleNoRAS() method)
inIdleNoRAS() changes state to "inAlerting" and sends "CallProceeding" message.

Here is the sequence of call translator and mte classes that sequentially
handle this Event:
- EvtDirect
- EvtSM1
- EvtFeature (here the address of Feature is obtained)
- Feature
- FeatureTrCallSig
- PatternTrCallSig (the address of FeatureTrCallSig is known)
- EvtTrSetup (inIdle() method)
inIdle() changes state to "inWaitInAdmission", prepares SIP Invite message,
fills fields of the Invite message with all information known at this moment,
sends "Admission request" to gatekeeper.

======================================================================

Copyright 2000-2003, Cisco Systems, Inc.
THE INFORMATION HEREIN IS PROVIDED ON AN "AS IS" BASIS, WITHOUT ANY
WARRANTIES OR REPRESENTATIONS, EXPRESS, IMPLIED OR STATUTORY, INCLUDING
WITHOUT LIMITATION, WARRANTIES OF NONINFRINGEMENT, MERCHANTABILITY OR
FITNESS FOR A PARTICULAR PURPOSE.

$Id: code.txt,v 1.2.2.1 2003/03/28 05:26:01 bko Exp $
