Abstract Services

Unbound applications don't execute as part of a service, and so they don't have a service context to execute in. To get round this, OCAP uses the concept of an abstract service. These are analogous to broadcast services, but instead they exist only within the receiver. Abstract services are defined by the network operator, and allow the network operator to provide some guarantees as to what applications work together. Instead of saying that every unbound application can execute at the same time as every other unbound application, abstract services can group together applications that are known to inter-operate. This allows the broadcaster to provide some guarantees that applications in the same abstract service will play nicely together.

Managing abstract services

Before an abstract service can be started, the Executive Module needs to know about that service, and in fact the Executive Module needs to create that service using the OCAP service API.

Abstract services aren't created at the whim of the receiver - something has to tell the receiver what abstract services it should create and what applications are associated with it. This information is contained within the XAIT, as anyone who has read the section on application signaling will already know. The XAIT contains a list of abstract services that should be created, and defines the applications that are available and the abstract services that they are associated with.

To define an abstract service, the broadcaster inserts an abstract service descriptor in the common descriptor loop of an XAIT. They must then define at least some of the applications in that XAIT as belonging to that abstract service, by specifying its service ID in the unbound application descriptor of the application in question (see the application signalling tutorial for more information about the unbound application descriptor). An abstract service descriptor has the following format:

Format of the OCAP abstract service descriptor. Source: OCAP 1.0 profile, version I15.
  No. of bits Identifier Value
abstract_service_descriptor() {
descriptor_tag 8 uimsbf 0xAE
descriptor_length 8 uimsbf  
service_id 24 uimsbf  
reserved _for_future_use 7 uimsbf  
auto_select 1 bslbf  
for (i = 0; i < N; i++) {
service_name_byte 8 uimsbf  

Abstract services don't have to contain broadcast applications - they could be resident in the receiver. For instance, a set of resident applications such as an EPG, a messenger application and a web browser could be grouped together in the same abstract service. Abstract services defined by the receiver manufacturer must have a service ID in the range 0x010000 to 0x01FFFF, while those defined by the network operator will be in the range 0x020000 to 0xFFFFFF. Abstract services are represented by an instance of the AbstractService class, which contained in the org.ocap.service package:

public interface AbstractService 
  extends javax.tv.service.Service {

  public java.util.Enumeration getAppAttributes();
  java.util.Enumeration getAppIDs();


Registering applications

Now that we've created a service, we need to register the applications that are associated with that service. This is done using the AppManagerProxy class from the OCAP application API, defined in the org.ocap.application package. This class has two methods that we are interested in at the moment:

public class AppManagerProxy { 

  static AppManagerProxy getInstance();

  void registerUnboundApp(java.io.InputStream xait);
  void unregisterUnboundApp(
    int serviceId,
    org.dvb.application.AppID appid);

The registerUnboundApp() method registers an unbound application, as you would expect. Since the XAIT specifies which applications are associated with which abstract services, this method takes an InputStream pointing to a complete XAIT as an argument.

The name registerUnboundApp() is a little misleading, because it actually registers every unbound application that is contained in the XAIT as well as creating any abstract services that are specified in that XAIT.

Just when you thought this seemed simple, life gets a bit more interesting. There is no need for an application to call this in order to update the applications database when the XAIT that's signaled on the network changes - those updates are handled automatically. (In practice, the middleware will probably use this method to do the updating, but that doesn't matter to application developers). Instead, an application should only call this function when it wants to create its own abstract service using an XAIT that it has defined. In this case, the application can't modify any abstract services of application entries that are contained in the broadcast XAIT - that's too risky and would allow a hostile app to hijack other applications.

unregisterUnboundApp() does the opposite to registerUnboundApp() and removes a previously-registered application from all abstract services in the apps database that refer to it. When all applications for an abstract service that are signaled as either auto-start or startable have been removed, the receiver treats that service as if it were terminated and removes it from the list of available services.

Selecting abstract services

When a user wants to start an application that is part of an abstract service, that service must be selected just like any other service. Just like any other service, this means using a service context. The monitor application or executive module uses the JavaTV service selection API to select that service, either in an existing service context or in a new one. Thus, starting an abstract service may mean that the receiver can't display the service that the viewer is currently watching.

When the abstract service is selected, all of the applications that are associated with that service are added to the application database, just like they would be if they were signaled using real AIT signaling. The similarities don't stop there - applications in an abstract service have exactly the same lifecycle and application model as those applications that are part of a real service. One slight difference comes when we start asking whether applications in an abstract service are service bound. Even though they aren't bound to any broadcast service, they are bound to a specific abstract service (or services). What this means is that application in an abstract service follow the same rules as service-bound applications in any other service - if a new service is selected (a broadcast service or another abstract service) that doesn't have a given applications signaled as present, that application will be killed. So, unbound applications that are associated with an abstract service are actually service-bound.