Internet Engineering Task Force E. Haleplidis
Internet-Draft O. Koufopavlou
Intended status: Informational S. Denazis
Expires: March 5, 2011 University of Patras
September 1, 2010
ForCES Implementation Experience Draft
draft-haleplidis-forces-implementation-experience-01
Abstract
The forwarding and Control Element Separation (ForCES) protocol
defines a standard communication and control mechanism through which
a Control Element (CE) can control the behavior of a Forwarding
Element (FE). This document captures the experience of implementing
the ForCES protocol and model. Its aim is to help others by
providing examples and possible strategies for implementing the
ForCES protocol.
Status of this Memo
This Internet-Draft is submitted in full conformance with the
provisions of BCP 78 and BCP 79.
Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF). Note that other groups may also distribute
working documents as Internet-Drafts. The list of current Internet-
Drafts is at http://datatracker.ietf.org/drafts/current/.
Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress."
This Internet-Draft will expire on March 5, 2011.
Copyright Notice
Copyright (c) 2010 IETF Trust and the persons identified as the
document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents
(http://trustee.ietf.org/license-info) in effect on the date of
publication of this document. Please review these documents
carefully, as they describe your rights and restrictions with respect
to this document. Code Components extracted from this document must
Haleplidis, et al. Expires March 5, 2011 [Page 1]
Internet-Draft ForCES Implementation Experience Draft September 2010
include Simplified BSD License text as described in Section 4.e of
the Trust Legal Provisions and are provided without warranty as
described in the Simplified BSD License.
Table of Contents
1. Terminology and Conventions . . . . . . . . . . . . . . . . . 3
1.1. Requirements Language . . . . . . . . . . . . . . . . . . 3
2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.1. Document Goal . . . . . . . . . . . . . . . . . . . . . . 4
2.2. Definitions . . . . . . . . . . . . . . . . . . . . . . . 5
3. ForCES Architecture . . . . . . . . . . . . . . . . . . . . . 6
3.1. Pre-association setup - Initial Configuration . . . . . . 6
3.2. TML . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
3.3. Model . . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.3.1. Components . . . . . . . . . . . . . . . . . . . . . . 7
3.3.2. LFBs . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.4. Protocol . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.4.1. TLVs . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.4.2. Message Deserialization . . . . . . . . . . . . . . . 13
3.4.3. Message Serialization . . . . . . . . . . . . . . . . 15
4. Developement Platforms . . . . . . . . . . . . . . . . . . . . 17
5. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 18
6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 19
7. Security Considerations . . . . . . . . . . . . . . . . . . . 20
8. References . . . . . . . . . . . . . . . . . . . . . . . . . . 21
8.1. Normative References . . . . . . . . . . . . . . . . . . . 21
8.2. Informative References . . . . . . . . . . . . . . . . . . 21
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . . 22
Haleplidis, et al. Expires March 5, 2011 [Page 2]
Internet-Draft ForCES Implementation Experience Draft September 2010
1. Terminology and Conventions
The terminology that is used is the same as in the FE-protocol
[RFC5810] and is not copied in this document.
1.1. Requirements Language
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
document are to be interpreted as described in [RFC2119].
Haleplidis, et al. Expires March 5, 2011 [Page 3]
Internet-Draft ForCES Implementation Experience Draft September 2010
2. Introduction
Forwarding and Control Element Separation (ForCES) defines an
architectural framework and associated protocols to standardize
information exchange between the control plane and the forwarding
plane in a ForCES Network Element (ForCES NE). [RFC3654] has defined
the ForCES requirements, and [RFC3746] has defined the ForCES
framework.
The ForCES protocol works in a master-slave mode in which FEs are
slaves and CEs are masters. The protocol includes commands for
transport of Logical Function Block (LFB) configuration information,
association setup, status, and event notifications, etc. The reader
is encouraged to read FE-protocol [RFC5810] for further information.
The FE-MODEL [RFC5812] presents a formal way to define FE Logical
Function Blocks (LFBs) using XML. LFB configuration components,
capabilities, and associated events are defined when the LFB is
formally created. The LFBs within the FE are accordingly controlled
in a standardized way by the ForCES protocol.
The Transport Mapping Layer (TML) transports the protocol messages.
The TML is where the issues of how to achieve transport level
reliability, congestion control, multicast, ordering, etc. are
handled. It is expected that more than one TML will be standardized.
The various possible TMLs could vary their implementations based on
the capabilities of underlying media and transport. However, since
each TML is standardized, interoperability is guaranteed as long as
both endpoints support the same TML. All ForCES Protocol Layer
implementations MUST be portable across all TMLs. Although more than
one TML may be standardized for the ForCES Protocol, all ForCES
implementations MUST implement the SCTP-TML [RFC5811].
The Applicability Statement [I-D.ietf-forces-applicability] captures
the applicable areas in which ForCES can be used.
2.1. Document Goal
This document captures the experience of implementing the ForCES
protocol and model and its main goal is not to tell others how to
implement, but to provide alternatives, ideas and proposals as how it
can be implemented.
Also, this document mentions possible problems and potential choices
that can be made, in an attempt to help implementors develop their
own products.
Additionally this document takes into account that the reader has
Haleplidis, et al. Expires March 5, 2011 [Page 4]
Internet-Draft ForCES Implementation Experience Draft September 2010
become familiar with the three main ForCES RFCs, the FE-protocol
[RFC5810], the FE-MODEL [RFC5812] and the SCTP-TML [RFC5811].
2.2. Definitions
This document follows the terminology defined by the ForCES
Requirements in [RFC3654] and by the ForCES framework in [RFC3746].
Haleplidis, et al. Expires March 5, 2011 [Page 5]
Internet-Draft ForCES Implementation Experience Draft September 2010
3. ForCES Architecture
This section discusses the ForCES architecture, implementation
challenges and how to overcome them.
3.1. Pre-association setup - Initial Configuration
The initial configuration of the FE and the CE is done respectively
by the FE Manager and the CE Manager. These entities have not as yet
been standardized.
The simplest solution, are static configuration files, which play the
role of the Managers and are read by FEs and CEs.
For more dynamic solutions however, it is expected that the Managers
will be entities that will talk to each other and exchange details
regarding the associations. Any developer can create any Manager,
but they should at least be able to exchange the following details:
From the FE Manager side:
1. FEIDs
2. FE IPs, if the FEs and CEs will be communicating via network.
3. TML. The TML that will be used. If this is omitted, then SCTP
MUST be chosen as default.
4. TML Priority ports. If this is omitted as well, then the CE MUST
use the default values from the respective TML RFC.
From the CE Manager side:
1. CEIDs
2. CE IPs, if the FEs and CEs will be communicating via network.
3. TML. The TML that will be used. If this is omitted, then SCTP
MUST be chosen as default.
4. TML Priority ports. If this is omitted as well, then the FE MUST
use the default values from the respective TML RFC.
3.2. TML
All ForCES implementations MUST support the SCTP as TML. Even if
another TML will be chosen by the developer, SCTP is mandatory and
MUST be supported.
Haleplidis, et al. Expires March 5, 2011 [Page 6]
Internet-Draft ForCES Implementation Experience Draft September 2010
There are several issues that should concern a developer for the TML.
1. Security. TML must be secure according to the respective RFC.
For SCTP you have to use IPSec.
2. NAT issues. ForCES can be deployed everywhere and can run over
SCTP/IP. In order for the FE and CE to work behind NATs you must
ensure that the TML ports are forwarded and that the firewall
allows SCTP through. This problem was identified during the
first ForCES interoperability test and documented at the ForCES
Implementation Report [I-D.ietf-forces-implementation-report].
3.3. Model
The model inherently is very dynamic. Using the basic atomic values
that are specified, new datatypes can be built using atomic (single
valued) and/or compound (structures and arrays).
The difficulty is to create something that is completely scalable so
a develeper doesn't need to write the same code for new LFBs, or for
new components etc. Just create code for the defined atomic values
and then new components can be built based on already written code.
The model itself provides the key which is inheritance.
3.3.1. Components
First, a basic component needs to be created as the mother of all the
components with the basic parameters of all the components:
o The ID of the component.
o The access rights of that component.
o If it is an optional component.
o If it is of variable size.
o Minimum data size.
o Maximum data size.
If the data size of the component is not variable, then the size is
either the minimum or the maximum size, as both should have the same
value.
Next, some basic functions are in order:
Haleplidis, et al. Expires March 5, 2011 [Page 7]
Internet-Draft ForCES Implementation Experience Draft September 2010
o A common constructor.
o A common deconstructor.
o Retrieve Component ID.
o Retrieve access right property.
o Query if it is an optional component.
o Get Full Data.
o Set Full Data.
o Get Sparse Data.
o Set Sparse Data.
o Del Full Data.
o Del Sparse Data.
o Get Property
o Set Property
o Get Value.
o Set Value.
o Del Value.
o Get Data.
o Clone component.
The Get/Set/Del Full/Sparse Data and Get/Set Property functions
handle the respective ForCES commands and return the respective TLV,
for example the Set Full Data should return a Result TLV. The Get/
Set/Del Value are called from the Get/Set/Del Full/Sparse Data
respectively and provide the interface to the actual values in the
hardware, separating the forces handling logic from the interface to
the actual values.
The Get Data function should return the value of the data only, not
in TLV format.
The last function seems out of place. That function MUST return a
Haleplidis, et al. Expires March 5, 2011 [Page 8]
Internet-Draft ForCES Implementation Experience Draft September 2010
new component that has the exact same values and attributes. This
function is useful in array components as described further.
The only requirement is to implement the base atomic data types. Any
new atomic datatype can be built as a child of a base data type which
will inherit all the functions and if necessary override them.
The struct component can then be built. A struct component is a
component by itself, but consists of a number of atomic components.
These atomic components create a static array within the struct. The
ID of each atomic component is the array's index. The Clone
function, for a struct component, MUST create and return an exact
copy of the struct component with the same static array.
The most difficult component to be built is the array. The
difficulty lie in the actual benefit of the model. You have absolute
freedom over what you build. An array is an array of components. In
all rows you have the exact same type of component either a single
component or a struct. The struct can have multiple single
components, or a combination of single components, structs and arrays
and so on. So, the difficulty lies in how to create a new row, a new
component by itself. This is where the Clone function is very
useful. For the array a mother component that can spawn new
components exactly like itself is needed. Once a set command is
received, the mother component can spawn a new component, if the
targeted row does not exists, and add it into the array, and with the
set fulldata the value is set in the recently spawned component, as
the spawned component knows how the data is created. In order to
distinguish these spawned components from each other and their
functionality, some kind of index is required that will also reflect
on how the actual data of the specific component is stored on the
hardware.
Once the basic constructors of all possible components are created,
then a developer only has to create his LFB components or datatypes
as a child of one of the already created components and the only
thing the developer really needs to add, is the three functions of
Get/Set/Del value of each component which is platform dependent. The
rest stays the same.
3.3.2. LFBs
The same architecture in the components can be used for the LFBs,
allowing a developer to write LFB handling code only once. The
parent LFB has some basic attributes:
Haleplidis, et al. Expires March 5, 2011 [Page 9]
Internet-Draft ForCES Implementation Experience Draft September 2010
o The LFB Class ID.
o The LFB Instance ID.
o An Array of Components.
o An Array of Capabilities.
o An Array of Events.
Then some common functions:
o Handle Configuration Command.
o Handle Query Command.
o Get Class ID.
o Get Instance ID.
Once these are created each LFB can inherit all these from the parent
and the only thing it has to do is to add the components that have
already been created.
An example can be seen in Figure 1. The following code creates a
part of FEProtocolLFB:
//FEID
cui = new Component_uInt(FEPO_FEID, ACCESS_READ_ONLY, FE_id);
Components[cui->get_ComponentId()]=cui; //Add component to array list
//Current FEHB Policy Value
cub = new Component_uByte(FEPO_FEHBPolicy, ACCESS_READ_WRITE, 0);
Components[cub->get_ComponentId()]=cub; //Add component to array list
//FEIDs for BackupCEs Array
cui = new Component_uInt(0, ACCESS_READ_WRITE, 0);
ca = new Component_Array(FEPO_BackupCEs, ACCESS_READ_WRITE);
ca->AddRow(cui, 1);
ca->AddMotherComponent(cui);
Components[ca->get_ComponentId()]=ca; //Add component to array list
Figure 1: Example code for creating part of FEProtocolLFB
The same concept can be applied to handling LFBs as one FE. An FE is
a collection of LFBs. Thus all LFBs can be stored in an array based
on the LFB's class id, version and instance. Then what is required
is an LFBHandler that will handle the array of the LFBs. A specific
Haleplidis, et al. Expires March 5, 2011 [Page 10]
Internet-Draft ForCES Implementation Experience Draft September 2010
LFB, for example, can be addressed using the following scheme:
LFBs[ClassID][Version][InstanceID].
Note: While an array can be used in components, capabilities and
events, a hash table or a similar concept is better suited for
storing LFBs using the component ID as the hash key with linked lists
for collision handling, as the created array can have large gaps if
the values of LFB Class ID vary greatly.
3.4. Protocol
3.4.1. TLVs
The goal, for protocol handling, is to create a general and scalable
architecture that handles all protocol messages instead of something
implementation specific. There are certain difficulties that have to
be overcome first.
Since the model allows a developer to define any LFB required, the
protocol has been thus created to cope with, allowing the user the
freedom to configure and query any component whatever the underlying
model. While this being a strong point for the protocol itself, one
difficulty lies with the unkwown underlying model and the unlimited
number of types of messages that can be created, making creating
something generic a daunting task.
Another difficulty also arises from the batching capabilities of the
protocol. You can have multiple Operations within a message, you can
select more than one LFB to command, and more than one component to
manipulate.
A possible solution is again provided by inheritance. There are two
basic components in a protocol message.
1. The common header.
2. The rest of the packet.
The rest of the packet is divided in Type-Length-Value (TLV) packets,
and in one case Index-Length-Value (ILV) packets.
The TLV hierarchy can be seen in the Figure 2:
Haleplidis, et al. Expires March 5, 2011 [Page 11]
Internet-Draft ForCES Implementation Experience Draft September 2010
Common Header
|
+-----------+----------+-----------+
| | | |
Redirect LFBSelect ASResult ASTreason
TLV TLV TLV TLV
|
|
Operation
TLV
|
| Optional
PathData ---> KeyInfo TLV
TLV
|
+----------+---------+----------+
| | | |
SparseData Result FullData PathData
TLV TLV TLV TLV
Figure 2: ForCES TLV Hierrachy
The above figure shows only the basic hierarchy level of TLVs and
does not show batching. Also this figure does not show the recursion
that can occur at the last level of the hierarchy. The figure shows
one kind of recursion with PathData within PathData. FullData can be
within FullData and SparseData. The possible combination of TLVs are
described in detail in the FE-protocol [RFC5810] as well as the data
packing rules.
A TLV's main attributes are:
o Type
o Length
o Data
o An array of TLVs.
The array of TLVs is the next hierarchy level of TLVs nested in this
TLV.
A TLVs common function could be:
o A basic constructor.
Haleplidis, et al. Expires March 5, 2011 [Page 12]
Internet-Draft ForCES Implementation Experience Draft September 2010
o A constructor using data from the wire.
o Add a new TLV for next level.
o Get the next TLV of next level.
o Get a specific TLV of next level.
o Replace a TLV of next level.
o Get the Data.
o Get the Length.
o Set the Data.
o Set the Length.
o Set the Type.
o Serialize the header.
o Serialize the TLV to be written on the wire.
Next all TLVs can inherit all these functions and attributes and
either override them or create some new functions where required.
3.4.2. Message Deserialization
What follows is a the algorithm for deserializing any protocol
message:
1. Get the message header.
2. Read the length.
3. Check the message type to understand what kind of packet this is.
4. If the length is larger than the message header then there is
data for this packet.
5. A check can be made here regarding the message type and the
length of the packet
If the packet is a Query or Config type then for this level there are
LFBSelector TLVs:
Haleplidis, et al. Expires March 5, 2011 [Page 13]
Internet-Draft ForCES Implementation Experience Draft September 2010
1. Read the next 2 shorts(type-length). If the type is an
LFBSelector then the message is valid.
2. Read the necessary length for this LFBSelector and create the
LFBSelector from the data of the wire.
3. Add this LFBSelector to the mainheader array of LFBSelectors
4. Do this until the rest of the packet has finished.
The next level of TLVs are Operation TLVs
1. Read the next 2 shorts(type-length). If the type is an
OperationTLV then the message is valid.
2. Read the necessary length for this OperationTLV and create the
OperationTLV from the data of the wire.
3. Add this OperationTLV to the LFBSelector array of TLVs.
4. Do this until the rest of the LFBSelector's Packet has finished.
1. Read the next 2 shorts(type-length). If the type is a PathData
then the message is valid.
2. Read the necessary length for this PathDataTLV and create the
PathDataTLV from the data of the wire.
3. Add this PathData TLV to the Operation TLV's array of TLVs.
4. Do this until the rest of the OperationTLV's Packet has finished.
Here it gets interesting, as the next level of PathDataTLVs can be
either:
o PathData TLVs.
o FullData TLV.
o SparseData TLV.
o Result TLV.
The solution to this difficulty is recursion. If the next TLV is
PathDataTLV then the PathDataTLV that is created uses the same kind
of deserialisation until it reaches a FullDataTLV or SparseDataTLV.
There can be only one FullDataTLV or SparseData within a PathData.
Haleplidis, et al. Expires March 5, 2011 [Page 14]
Internet-Draft ForCES Implementation Experience Draft September 2010
1. Read the next 2 shorts(type-length).
2. If the Type is a PathDataTLV then do again the previous algorithm
but add the PathDataTLV to this PathDataTLV's array of TLVs.
3. Do this until the rest of the PathData's Packet has finished.
4. If the Type is a FullDataTLV then create the FullData TLV from
the packet and add this to the PathData's array of TLVs.
5. If the Type is a SparseDataTLV then create the SparseData TLV
from the packet and add this to the PathData's array of TLVs.
6. If the Type is a ResultTLV then create the Result TLV from the
packet and add this to the PathData's array of TLVs.
If the message is a Query it MUST NOT have any kind of data inside
the PathData.
If the message is a Query Response then it MUST either have a
ResultTLV or a FullData TLV.
If the message is a Config it MUST have inside either a FullDataTLV
or a SparseData TLV.
If the message is a Config Reponse, it MUST have inside a ResultTLV.
More details regarding message validation can be be read in Section 7
of the FE-protocol [RFC5810].
Note: When deserializing, implementors must take care to ignore
padding of TLVs as all must be 32-bit aligned. The length value in
TLVs includes the Type and Length (4 bytes) but does not include
padding.
3.4.3. Message Serialization
The same concept can be applied in the message creation process.
Having the TLVs ready, a developer can go bottom up. All that is
required is the serialization function that will transform the TLV
into bytes ready to be transfered on the network.
For example for the creation of a simple query from the CE to the FE,
all the PathData are created. Then they will be serialized and
inserted into an Operation TLV, which in turn will be serialized and
inserted into an LFB Selector and in turn serialized and entered into
the Common Header which will be passed to the TML to be transported
to the FE.
Haleplidis, et al. Expires March 5, 2011 [Page 15]
Internet-Draft ForCES Implementation Experience Draft September 2010
Having an array of TLVs inside a TLV that are next in the TLV
hierarchy, allows the developer to insert any number of next level
TLVs thus creating any kind of message.
Note: When the TLV is serialized to be written on the wire,
implementors must take care to include padding to TLVs as all must be
32-bit aligned.
Haleplidis, et al. Expires March 5, 2011 [Page 16]
Internet-Draft ForCES Implementation Experience Draft September 2010
4. Developement Platforms
Any Developmens platform that can support the SCTP TML and the TML of
the developer's choosing is available for use.
Figure 3 provides an initial survey of SCTP support for C/C++ and
Java at present time.
/-------------+-------------+-------------+-------------\
|\ Platform | | | |
| ----------\ | Windows | Linux | Solaris |
| Language \| | | |
+-------------+-------------+-------------+-------------+
| | | | |
| C/C++ | Supported | Supported | Supported |
| | | | |
+-------------+-------------+-------------+-------------+
| | Limited | | |
| Java | Third Party | Supported | Supported |
| | Not from SUN| | |
\-------------+-------------+-------------+-------------/
Figure 3: SCTP Support on Operating Systems
A developer should be aware of some limitations regarding Java
implementations.
Java inherently does not support unsigned types. A workaround this
can be found in the creation of classes that do the translation of
unsigned to java types. The problem is that the unsigned long cannot
be used as it is in the Java platform. The proposed set of classes
can be found in [Java Unsigned Types].
Haleplidis, et al. Expires March 5, 2011 [Page 17]
Internet-Draft ForCES Implementation Experience Draft September 2010
5. Acknowledgements
The authors would like to thank Adrian Farrel for sponsoring this
document and Jamal Hadi Salim for discussions to make this document
better.
Haleplidis, et al. Expires March 5, 2011 [Page 18]
Internet-Draft ForCES Implementation Experience Draft September 2010
6. IANA Considerations
This memo includes no request to IANA.
Haleplidis, et al. Expires March 5, 2011 [Page 19]
Internet-Draft ForCES Implementation Experience Draft September 2010
7. Security Considerations
Developers of ForCES FEs and CEs should take the security
considerations of the ForCES framework in [RFC3746] and FE-protocol
[RFC5810] into account.
Also, as specified in the security considerations section of the
SCTP-TML RFC [RFC5811] the transport-level security, has to be
ensured by IPSec.
Haleplidis, et al. Expires March 5, 2011 [Page 20]
Internet-Draft ForCES Implementation Experience Draft September 2010
8. References
8.1. Normative References
[I-D.ietf-forces-applicability]
Crouch, A., Khosravi, H., Doria, A., Wang, X., and K.
Ogawa, "ForCES Applicability Statement",
draft-ietf-forces-applicability-09 (work in progress),
June 2010.
[I-D.ietf-forces-implementation-report]
Haleplidis, E., Ogawa, K., Wang, W., and J. Salim,
"Implementation Report for ForCES",
draft-ietf-forces-implementation-report-02 (work in
progress), June 2010.
[RFC5810] Doria, A., Hadi Salim, J., Haas, R., Khosravi, H., Wang,
W., Dong, L., Gopal, R., and J. Halpern, "Forwarding and
Control Element Separation (ForCES) Protocol
Specification", RFC 5810, March 2010.
[RFC5811] Hadi Salim, J. and K. Ogawa, "SCTP-Based Transport Mapping
Layer (TML) for the Forwarding and Control Element
Separation (ForCES) Protocol", RFC 5811, March 2010.
[RFC5812] Halpern, J. and J. Hadi Salim, "Forwarding and Control
Element Separation (ForCES) Forwarding Element Model",
RFC 5812, March 2010.
8.2. Informative References
[Java Unsigned Types]
"Classes that support unsigned primitive types for Java.
All except the unsigned long",
<http://darksleep.com/player/JavaAndUnsignedTypes.html>.
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119, March 1997.
[RFC3654] Khosravi, H. and T. Anderson, "Requirements for Separation
of IP Control and Forwarding", RFC 3654, November 2003.
[RFC3746] Yang, L., Dantu, R., Anderson, T., and R. Gopal,
"Forwarding and Control Element Separation (ForCES)
Framework", RFC 3746, April 2004.
Haleplidis, et al. Expires March 5, 2011 [Page 21]
Internet-Draft ForCES Implementation Experience Draft September 2010
Authors' Addresses
Evangelos Haleplidis
University of Patras
Patras,
Greece
Email: ehalep@ece.upatras.gr
Odysseas Koufopavlou
University of Patras
Patras,
Greece
Email: odysseas@ece.upatras.gr
Spyros Denazis
University of Patras
Patras,
Greece
Email: sdena@upatras.gr
Haleplidis, et al. Expires March 5, 2011 [Page 22]