Table of Contents

  • Introduction
  • ICE
    • SLICE
    • Architecture
  • Event model
  • OCSE Architecture
    • Overview
    • Runtime
  • Developing for OCSE
    • Developer levels
    • Subscribing to events
    • Publishing events
  • Case: A Service for monitoring physical activity in order to provide reliable blood pressure readings
  • Tool support


This wiki entry is work in progress. This section introduces the OCSE architecture.


ICE acknowledged CORBA as being the most prominent and powerful multiplatform middleware on the market, but also acknowledged many of its shortcomings. Realizing that WCF only supports a limited amount of languages and is entirely Windows based, that Java RMI is a java only technology, and that CORBA is overly complex, ICE aimed to offer an alternative to CORBA's gradual abandonment [Rise And Fall of Corba], and to offer the ability to choose a more platform that was efficient and non-proprietary, due to lack of standardization issues

The design philosophy for the Ice encoding is to optimize performance at the expense of bandwidth, that is, to use as few CPU cycles as possible during marshaling and unmarshaling. CORBA's IIOP (Internet Inter-ORB Protocol), for example, uses an encoding scheme allowing the sender to marshal data in the sender's native byte order. For example, IIOP uses considerably more bandwidth for the same data due to its padding rules.

In essence, ICE claims to support machine independence, language independence, support for multiple interfaces, synchronous asynchronous messaging, object oriented semantics, implementation independence, OS independence, Threading support, transport independence, Location and server transparency, security, builtin persistence and source code availability.

ICE supports federation, allowing multiple servers to handle incoming requests thus providing load balancing. IceStorm, a method for publishing data in ICE, can use federation to scale to hundreds of thousands of clients. Scalability in ICE is therefore as simple as adding new hardware and editing configuration. ICE supports batched invocations across the network, if there are no time requirements on the completion of the invocations, allowing a client to queue up invocations until that queue is flushed. Asynchronous Method Invocation (AMI) allows ICE to avoid blocking threads when two-way communication is utilized. Using IcePatch2 ICE enables data transmission in asynchronous chunks.

  • ICE allows multiple interfaces to an object, same object id. Leveraging version issues.
  • An ICE proxy is like a CORBA object reference. However, ICE proxies are not opaque and clients can always create object connections through generated proxies, meaning there's no need for a naming service.
  • CORBA doesnt support Asynchronous Method Dispatch (AMD)
  • No need for ORBS, all communication happens through ICEs own runtime system.
  • CORBA lacks security measures.
  • CORBA does not support c\#, objective-c, ruby or php.
  • ICE has one type of encoding for a Global unique identifier, a stringified proxy, while CORBA has both IOR, corbaloc and also corbaname.
  • CORBA has complex language mappings.

SLICE - Specification Language for ICE

ICE Objects are specified using the SLICE language. SLICE allows you to define the client-server contract in a way that is independent of a specific programming language. The SLICE definitions are compiled by an ICE compiler into an auto generated API of ICE proxies for objects, for a specific programming language. Current programming languages are: C++, Java, C#, Python, Objective-C, while PHP and Ruby are only usable to connect to ICE objects as clients.

Because SLICE doesn't describe implementations, but only interfaces and types, it is a purely declarative language and there is no way to write executable statements. Interfaces are defined within modules that translate to namespaces (as in MS .NET languages) or packages (as in Java). These modules can be nested as desired. By redeclaring a module in a different SLICE file, namespaces can be "reopened", allowing better developer support in terms of allowing additions to the collection of SLICE files making up the API for OCSE. The figure below shows how developers collaborate in a heterogenous environment using SLICE.



There is no clear seperation of the terms "servers" and "clients" in ICE, as callbacks and two-way communication transforms systems into peer-to-peer systems. All communication happens through generated proxies using an installed ICE runtime, meaning no requirement for running ORBs compared to corba. Proxies are used in conjunction with a service identifier and a port number, to create a specific endpoint connection to a service. The figure below shows an overview of the ICE architecture.

Event model

In order to provide a robust and reliable mechanism for data communication between services, OCSEs data and event publication is based on on ICE's IceStorm service, introduced below. By Wrapping IceStorm in a Publish/Subscribe pattern, ICE specific implementation are abstracted from clients who wish to subscribe to data offered by a particular publisher.

Usually, when using ICE, a client will interact directly with the IceStorm service to register itself to a topic. In OCSE, each publisher maintains a list of the topic or topics it provides data for, and handles all subscriber requests for those topics. The publisher also determines Quality of Service (QoS) parameters for all it's subscribers. Whenever the Publisher is used to publish data or events, the publisher publishes that data through icestorm on a specific topic, afterwhich all subscribers listening to that topic will get notified. No need for a local list of clients to update. The same pattern could be achieved using a simple distributed observer pattern, but IceStorm has proven to be robust and provide QoS (order of arrival, retry count for lost clients, etc). Another boon is the fact that publishers may disappear and reappear without affecting clients listening to a topic through IceStorm (decoupling). If the publisher is started back up and starts publishing to an active topic, the clients will receive these updates without realizing the absence of the publisher. A sequence of the general flow of publishing and subscribing in OCSE is depicted by the figure below.



IceStorm is a publish/subscribe service that offers a means of publishing requests to a group of subscribers. IceStorm relieves service developers from the burden of managing subscribers and handling delivery errors, simplifying development and allowing the developer to focus on more important implementation details and not on the details of distribution, by for instance having to implement a custom distributed observer pattern. IceStorms support for replication and integration with \emph{IceGrid} provides greater reliability in the face of network and system failures without complex administrative burdens. Finally, IceStorm leverages Ice request-forwarding facilities in order to provide a typed interface to publishers and subscribers, minimizing the impact on applications.

The primary disadvantage of a regular distributed publish/subscribe system is that this architecture is tightly coupled between the collector and its monitors, needlessly complicating the collector implementation by requiring it to manage the details of subscriber registration and data delivery.


IceStorm acts as a mediator between the collector (the publisher) and the monitors (the subscribers), and allows a publisher to publish data/events to all subscribers using a single publish interface through the IceStorm service, making the publisher completely unaware of its subscribers.



An application indicates its interest in receiving messages by subscribing to a so called "topic". An IceStorm server supports any number of topics, which are created dynamically and are distinguished by unique names. Each topic can have multiple publishers and subscribers.

A topic is essentially equivalent to an application-defined Slice interface: the operations of the interface define the types of messages supported by the topic. A publisher uses a proxy for the topic interface to send its messages, and a subscriber implements the topic interface (or an interface derived from the topic interface) in order to receive these messages. This is no different than if the publisher and subscriber were communicating directly in the traditional client-server style; the interface represents the contract between the client (the publisher) and the server (the subscriber), except IceStorm transparently forwards each message to multiple recipients. IceStorm does not verify that publishers and subscribers are using compatible interfaces, therefore applications must ensure that topics are used correctly.

Quality of Service

Through IceStorm, ICE allows quality of service parameters that give further rise to reliability and robustness. Messages can be relayed in ordered or unordered fashion, allowing ICE to provide optimizations in communication where able. The IceStorm server can attempt to retry connections, x number of times, to clients that have disconnected unexpectedly. Further optimization in communication can be achieved by specifying communication to happen either oneway or twoway, allowing ICE to optimize either bandwidth or focus on reliability.

OCSE Architecture



OCSE Runtime

This section describes how the OCSE runtime uses a Lifecycle Manager and a Naming Service to manage service lifecycles according to the following requirements:

  • During startup, vital core services must first be initialized and started.
  • Services must provide an implementation of the isAlive() method of the SLICE interface definition OCSEService, or be refused.
  • Services intended to be running, should be restarted automatically from a local service repository, if they cannot be restarted.

As mentioned, every service under management by the LifeCycle Manager must be of type OCSEService. The SLICE for this basic OCSE type is as follows:

module Service {
interface OCSEService {
bool isAlive();

The method isAlive(), can be implemented by any service to return true (is alive), false (is not alive), using basic boolean values or more elaborate is-alive mechanisms. As an example, a method might return false if there is no contact with the device the service offers interaction with. Services that aren't defined in SLICE as a type of OCSEService, are not considered to be true services by the framework, and as such, cannot be maintained by the lifecycle manager.

The stringified proxy definitions for the location of all core services are managed in a local configuration file and is injected into every service during startup, given the implementation of the service extends the ICE abstract class Ice.Application and forwards the configuration file, received as command line arguments, to Ice.Application as per it's specification. By resolving these proxies, services can get a hold of the OCSE core services.

Each of the 4 entries in the configuration file (See listing below) can be resolved to a proxy to one of OCSEs core service. TopicManager.Proxy is the location of the IceStorm service. This proxy is primarily used by publishers, but can be accessed directly if so desired by senior programmers who know the ICE middleware. ServiceEventPublisher, DiscoveryPublisher, NamingService.

TopicManager.Proxy=OpenCareSubscriptions/TopicManager:default -p 10000
ServiceEventPublisher.Proxy=ServiceEventPublisher:default -p 12001
DiscoveryPublisher.Proxy=DiscoveryPublisher:default -p 12002
NamingService.Proxy=NamingService:default -p 12003

Service Descriptors

An XML Servicedescriptor describes each service and the services it requires to function. As an example, the listing below is the service descriptor for the core services of the OCSE Runtime, that must always be running. The node, ID, indicates the ICE object identifier the service registers itself with in the Naming Service.

<?xml version='1.0'?>
<service type="core">
<binary type="windows executable">start.bat</binary>
<service type="core">
<binary type="windows executable">NamingService.exe</binary>
<service type="core">
<binary type="windows executable">DiscoveryPublisher.exe</binary>
<service type="core">
<binary type="windows executable">ServiceEventPublisher.exe</binary>

Case: A Service for monitoring physical activity in order to provide reliable blood pressure readings

This section documents how the open source frameworks TinyOS and SPINE, aswell as the low battery operating wireless sensor platform SHIMMER, were used to implement and integrate an Activity Level Service into OCSE

In the Activity Level Service, four different "Level of activity" are defined, based on the 3-axis acceleration values received from a SHIMMER mote. The trigger values for these activity levels were determined by a simple and crude movement test, evaluating the fluctuations in acceleration based on moderate to high physical activity. The SLICE for this Activity Level is defined as follows:

module DTO {
module Activity {
enum Level { HIGH, NORMAL, LOW, SILENT };

The SILENT value, in particular, is useful to give an indication of whether or not the user is moving or potentially not wearing his/her device at all. Three components are involved in creating the Activity Level Service, and are explained in detail. Three components are required to integrate SPINE into OCSE and offer up acceleration data received by a SHIMMER device, and each are detailed in the following sections.

  • An adapter/driver, converting SPINE data packets received from a Body Sensor Network.
  • A publisher, used to publish converted SPINE packets to OCSE.
  • A service, subscribing to the publication of converted SPINE data packets, evaluating the acceleration values, making them available to OCSE in the form of an activity level.

SPINE Adapter/Driver

The hardware setup for the SPINE environment is as follows:

  • 1 SHIMMER mote flashed with the SPINE TinyOS node application, sampling acceleration and transmitting these samples using it's 802.15.4 radio.
  • 1 SHIMMER mote flashed with the TinyOS BaseStation application connected through a docking station to a PC, forwarding any TinyOS/SPINE messages it receives from BSN motes, over it's serial interface.

The nature of the TinyOS application, BaseStation, allows PC's to communicate directly with wireless sensor networks. For the SPINE Adapter to listen to messages forwarded through the dockingstation, the installation of a standard FTDI USB-to-Serial driver is required on the coordinator (PC), allowing two-way communication between the coordinator and the SHIMMER docking station. Two-way communication is needed in order to both receive and transmit configurations and commands to the active nodes in the Body Sensor Network.

Installation of the ftdi Usb-to-serial driver realizes itself through the delegation of two COM port numbers by windows, one used for writing and one for listening. The highest COM port number must be entered into a configuration, required by SPINE, in order for the SPINE libraries to be able to listen for node traffic forwarded through the dockingstation.

Each mote in the BSN is configured by the SPINE Adapter/driver during startup in terms of samplerate and transmission type, for each desired sensor available on the SHIMMER, through an XML based configuration file. The configuration is translated into a series of commands, issued by the coordinator through the SHIMMER basestation, and broadcasted to the whole Body Sensor Network. As each SHIMMER is flashed with a unique id, the SPINE applications running on the motes will only react to their own configurations. In this case, a SHIMMER with ID equal to 1 is told to sample it's onboard accelrometer every 100 milliseconds, and transmit a buffer for every 31 collected samples. The method of using raw buffered collection, was chosen to allow less frequent transmissions, thus saving battery, while still allowing OCSE to witness and reach to every sample.

The OCSE Activity Level Service

This section describes the workings of the ActivityLevel Service, a service that attempts to provide a categorization of physical activity based on data received from the SPINE Adapter/driver described in the section above. The SLICE listing below shows the SLICE module definition for the ActivityLevel Service.

module Services {
module Healthcare {
module Movement {
interface ActivityLevelService extends Service::OCSEService {
DTO::Activity::Level getCurrentActivityLevel();
DTO::Activity::Level getRecentActivityLevel(int minutes);

Upon receiving acceleration publications from the SPINE driver, values for each axis of acceleration (x,y,z) is stored in seperate \emph{First In First Out} queues. When either of the exposed methods are called by another service, calculations are made across the entire buffer of samples for each axis, and by calculating the standard deviation (Root Mean Square), an activity level is determined. As previously mentioned, the trigger values seperating each level were defined by a simplistic movement test. This activity level classification mechanism is crude and could be more accurate, but was tested to give a fairly realistic view of a human beings activity in respect to deciding if a person is eligible for taking a reliable bloodpressure by the parameters defined in the section "Taking a reliable blood pressure reading"

Taking a reliable blood pressure reading

Some patients measuring their bloodpressure at home are tempted to round the numbers up or down, or to record a lower blood pressure than what was recorded. This shortcut can affect treatment and therefor the long-term risk of stroke and heart attack. This section documents how an orchestration of existing OCSE services was successfully performed in order to take a blood pressure reading and document it's reliability based on a number of commonly accepted criteria for taking reliable bloodpressure readings [reliable blood pressure]. A few of these criteria, mentioned below, are used to instruct the patient in how to ensure the right prerequisites for a reliable blood pressure.
  • "Wear a short sleeved T-shirt or loose fitting clothing so that the sleeve can be rolled up comfortably".
  • "Before taking readings rest for five minutes. You should be sitting down, preferably at a desk or a table, in a quiet place, with your arm resting on a firm surface. It is very important that your arm is supported so that the cuff around the arm is at the same level as your heart. You may need to support your arm with books to make sure it is at the correct height. Ensure that the arm is totally relaxed and not tensed."
  • "The deflated cuff needs to be tight, but not too tight. You should be able to insert two fingers between it and the skin."
  • "Start the machine - keep still and silent whilst the reading is taken. Moving and talking can affect the reading."

The OCSE SpeechService is used to verbalize the above instructions to the patient. To get an indication of the patients recent physical activity, the Activity Level service just described, is used. The MyTech BPM Service is used to to initiate a blood pressure measurement. In order for a successful measurement to take place, the patient is required to be wearing a SHIMMER device.Developing for OCSE

Developing for OCSE

Publishing events

Subscribing to events

Contacting services (NamingService / Abstractions )

Existing services

Tool support

A variety of tools exist in order to automate the process of generating proxies for the existing SLICE.

Visual Studio: (.NET proxies)
Eclipse: (Java proxies). A short screencast shows how to install the Eclipse plugin on MAC.

See the ICE documentation for manual command line tools to generate proxies for all supported languages.


[] Michi Henning. The rise and fall of corba. Queue, 4(5):28{34, 2006.
[1] ZeroC. Ice manual, 2009.
[] ICE in 20 minutes.
[] Eclipse plugin :
[] reliable blood pressure: