O2 1.2
Inter-process communication system for media applications
O2

Introduction

This documentation is divided into modules. Each module describes a different area of functionality: Basics, Return Codes, Low-Level Message Send, and Low-Level Message Parsing.

Overview

O2 is a communication protocol for interactive music and media applications. O2 is inspired by Open Sound Control (OSC) and uses similar means to form addresses, specify types, and encode messages.

However, in addition to providing message delivery, O2 offers a discovery mechanism where processes automatically discover and connect to other processes. Each process can offer zero or more named "services," which are top-level nodes in a global, tree-structured address space for a distributed O2 application. In O2, services replace the notion of network addresses (e.g. 128.2.100.57) in OSC.

O2 is based on IP (Internet Protocol), but there are some mechanisms that allow an O2 process to serve as a bridge to other networks such as Bluetooth.

O2 addresses begin with the service name. Thus, a complete O2 address would be written simply as "/synth/filter/cutoff," where "synth" is the service name.

Furthermore, O2 implements a clock synchronization protocol. A single process is designated as the "master," and other processes automatically synchronize their local clocks to the master. All O2 messages are timestamped. Messages are delivered immediately, but their designated operations are invoked according to the timestamp. A timestamp of zero (0.0) means deliver the message immediately. Messages with non-zero timestamps are only deliverable after both the sender and receiver have synchronized clocks.

A service is created using the functions:

o2_service_new("service_name")

and

o2_method_new("address," "types," handler, user_data, coerce, parse),

where o2_method_new is called to install a handler for each node, and each "address" includes the service name as the first node.

Some major components and concepts of O2 are the following:

  • Application - a collection of collaborating processes are called an "application." Applications are named by a simple ASCII string. In O2, all components belong to an application, and O2 supports communication only within an application. This allows multiple independent applications to co-exist and share the same local area network.
  • Host - (conventional definition) a host is a computer (virtual or real) that may host multiple processes. Essentially, a Host is equivalent to an IP address.
  • Process - (conventional definition) an address space and one or more threads. A process can offer one or more O2 services and can serve as a client of O2 services in the same or other processes. Each process using O2 has one directory of services shared by all O2 activity in that process (thus, this O2 implementation can be thought of as a "singleton" object). The single O2 instance in a process belongs to one and only one application. O2 does not support communication between applications.
  • Service - an O2 service is a named server that receives and acts upon O2 messages. A service is addressed by name. Multiple services can exist within one process. A service does not imply a (new) thread because services are "activated" by calling o2_poll(). It is up to the programmer ("user") to call o2_poll() frequently, and if this is done using multiple threads, it is up to the programmer to deal with all concurrency issues. O2 is not reentrant, so o2_poll() should be called by only one thread. Since there is at most one O2 instance per process, a single call to o2_poll() handles all services in the process.
  • Message - an O2 message, similar to an OSC message, contains an address pattern representing a function, a type string and a set of values representing parameters.
  • Address Pattern - O2 messages use URL-like addresses, as does OSC, but the top-level node in the hierarchical address space is the service name. Thus, to send a message to the "note" node of the "synth" service, the address pattern might be "/synth/note." The OSC pattern specification language is used unless the first character is "!", e.g. "!synth/note" denotes the same address as "/synth/note" except that O2 can assume that there are no pattern characters such as "*" or "[".
  • Scheduler - O2 implements two schedulers for timed message delivery. Schedulers are served by the same o2_poll() call that runs other O2 activity. The o2_gtsched schedules according to the application's master clock time, but since this depends on clock synchronization, nothing can be scheduled until clock synchronization is achieved (typically within a few seconds of starting the process that provides the master clock). For local-only services, it is possible to use the o2_ltsched scheduler (not with o2_send(), but by explicitly constructing messages and scheduling them with o2_schedule(). In any case, scheduling is useful within a service for any kind of timed activity.