Overview of the PPS Service

The services layer of the QNX CAR Platform for Infotainment is built on the QNX Persistent Publish/Subscribe (PPS) service, a simple filesystem-based facility that provides persistence across reboots. Small and extensible, PPS allows interfacing from almost any higher-level language that can support open, read, write, and close operations on files.
Note: For a more in-depth description of PPS, see the Persistent Publish/Subscribe Developer's Guide.

Key concepts

Objects are implemented as files under the /pps directory. Your applications use objects to communicate with each other. There can be many objects in the system, but never more than one instance of the same object.

Applications often use a control object for sending commands and a corresponding status object for publishing responses.

Applications can read a single special object (.all) to get notifications of changes to all the objects in a directory. Apps can use the special .notify object to get changes for a certain set of objects.

Objects contain attributes or properties that apps can modify. Each attribute appears on a single line in the object file.
As publishers, apps can modify objects and their attributes so that other interested apps can receive updates. Publishing is asynchronous—apps don't have to wait for the publisher.

To publish to an object, the publisher calls open() for that object and then write() to modify it. Multiple publishers can publish to the same object. When a publisher changes an object, the PPS service informs all subscribers of the change.

As subscribers, apps receive updates for objects and attributes that publishers have modified. To get updates for an object, a subscriber calls open() for that object and then read() to query it. Note that reads are nonblocking by default. Multiple subscribers can subscribe to the same object.
Note: The same app can be a publisher, a subscriber, or both.
Full subscription mode
In full mode (the default), the subscriber gets a "snapshot" of the entire object as it exists when the request is made. Note that if a publisher changes the object many times, the subscriber may miss some of the changes. Full mode is useful, for instance, for high-bandwidth objects that have numerous and frequent changes.
Delta subscription mode
In delta mode, the subscriber gets only the changes made to an object. On first read, the subscriber will get all the object's attributes (because the subscriber knows nothing yet about the object's state); subsequent reads will return only the changes since the previous read. Delta mode is useful, for instance, when you want to receive all the warnings or error messages that might be published to an object.
PPS maintains objects in memory while it's running and can save them to persistent storage (either at shutdown or on demand) on any reliable filesystem, such as flash or hard disk. Objects can be restored immediately on startup or on first access.
Server objects
A publisher can designate itself as a server for a particular object. When an app writes to a server object, only the publisher will get the message. PPS appends a unique identifier to the object name so that the publisher knows which client app is sending the message. For details, see "Server objects" in the Persistent Publish/Subscribe Developer's Guide.

Command-line options for the PPS service

pps [-A file][-b][-C][-d backlog][-l argument][-m mount][-p dir]
    [-P prio][-t period][-T tolerance][-U uid:gid][-v]
-A file
Set path to ACL configuration file. For details, see "Access Control List configuration file" in the Persistent Publish/Subscribe Developer's Guide.
Don't run in the background (useful for debugging).
Convert between -U and non-U persistence formats.
-d backlog
Set size of delta backlog (default is 256 kilobytes).
-l argument
Set load behavior:
  • 0 — load directory names and objects on demand (default).
  • 1 — load directories at startup, but objects on demand.
  • 2 — load directories and objects at startup.
-m mount
Specify the mountpoint for PPS (default is /pps).
-p dir
Specify the directory for persistent storage (default is /var/pps).
-P prio
Set the priority of the persistence thread.
-t period
Set the time period (in milliseconds) for writing to persistent storage (default is off).
-T tolerance
Set the tolerance (in milliseconds) for writing to persistent storage (default is off).
-U uid:gid
Downgrade from root to the specified UID and GID.
Run in verbose mode (use multiple v's to increase verbosity).
Note: You can also use SIGUSR1 to increase verbosity.

Pathname options

PPS lets you use various pathname options when opening objects. An option must follow a question mark (?). Use a comma to separate multiple options. For example, opening the playlist object like this:


will open the object with the wait and delta options.

Total delta size to keep before flushing this OCB (Open Control Block).
Output the credentials for this object.
Designate the publisher as critical to the object.
Set the crypto domain for this object.
Open the object in delta mode.
Return the names of all objects in the .all object in a directory.
Filter notifications based on changes to the names and/or values of specified attributes, where attrspec can be either an attribute's name or an expression specifying an attribute's value. Here's the syntax for a value expression:


  • Operators for integers (which must be in the range of a long long) are: <, <=, >, >=, =, ==, and !=
  • Operators for strings are: =, ==, and != (you can use + if escaped with \)
Treat the object as a server object, with purge and overflow notifications.
Flow high-water mark as percent of client backlog. If this tag isn't specified, the default (100) is used.
Make the object nonpersistent.
Associate the object with the notification group specified by id:value, where:
  • id is the string returned by the first read from the .notify object
  • value is any arbitrary string
Update an _opens::rd,wr attribute when the open count changes.
Reflect attribute changes made on this object back to itself.
Designate the publisher as a server for the object.
Set the verbosity level for this object.
Clear the O_NONBLOCK flag so that read() calls will wait until the object changes or a delta appears.

Object format

Objects appear as files and directories in the PPS filesystem. For example, to view the contents of an object called AA:BA:19:B2:AA:70 (in this case the filename is a device's MAC address) under the /pps/services/bluetooth/remote_devices/ directory, you can simply use cat at the command line:

cat /pps/services/bluetooth/remote_devices/AA:BA:19:B2:AA:70

The object's contents might look like this:

[n]name::My mobile

The first line always begins with an at sign (@), immediately followed by the object's name. Each line after that can begin with a qualifier, followed by an attribute name, followed by its encoding, followed by its value. For example, this line:


means that the nonpersistence qualifier ([n]) has been set and that the attribute paired has the Boolean value of false.
Note: For details on encodings and on qualifiers, see these sections in the Persistent Publish/Subscribe Developer's Guide:

Format for messages to server objects


Name of the command being sent to the object.
Any ID that identifies this instance of the message. The server always reflects the ID back in the response.
The dat is usually JSON encoded, because it may contain more than a simple string.

Format for responses

Responses always reflect the command_string and ID_number that were sent in the message, along with any errors:


Changing the directory for persistent storage

The root PPS object tree (/pps by default) may look something like this:

# pwd
# ls -1F

PPS populates its root object tree from the persistence tree (/var/pps by default), where the objects and attributes that you want to persist are stored.

To specify a different directory for persistent storage:
  1. Create your own persistence directory (e.g., mkdir /myobjects).
  2. Start the PPS service from a different mountpoint (e.g., /fs/pps) and specify your new persistence directory:

    pps -m /fs/pps -p /myobjects

Note: You may want to run PPS with the -t option, which lets you specify the time period (in milliseconds) that the service will use to write to persistent storage. Without the -t, you won't see any changes in your persistence directory until PPS exits.