General Legato Basics

Configuration
Factory Calibration
Security
Internationalization
Power Management
What's Next?

Configuration

Device configuration data is vital for most applications. Seldom are all devices in an application identical. Usually, there's some kind of customization on each device: it may be a complex set of user preferences, or it may be just a simple node name. Regardless of the device's customization, the device needs to be:

  • stored somewhere it can be retrieved quickly
  • easy to modify programmatically from within the device application code
  • easy to view and modify remotely via generic network or managed portal service
  • protected from
    • malicious snooping and vandalizm
    • multi-threaded race conditions
    • untimely device reset or power loss

Structure

Configuration data is stored in a tree structure, where each non-leaf node can contain any number of child nodes, each with its own name. At the leaves of the tree, the nodes can contain data.

This tree structure allows configuration data items to be uniquely identified using path names, much like file system paths, which makes it much easier to access configuration data via HTTP, SNMP, OMA-DM, and other protocols. It also allows the configuration database to be explored using tree walking algorithms and tools.

Transactions

Configuration data can be shared by multiple processes and threads. This can sometimes result in race conditions that can threaten data integrity. For example, if threads A and B both use data fields X and Y, it could be bad if thread A interrupts thread B to read those fields just after thread B has updated field X and is about to update field Y to be consistent with the new value of field X.

A possible reset or power loss may occur at any time, and we must be sure that would not corrupt the configuration data. For example, if power fails just after field X has been updated, but before field Y gets updated to match the new value of field X, then the configuration data could be in an invalid state. Transactions are used to prevent these sorts of problems.

Before a change can be made to configuration data, a write transaction must be started. All changes are made in the context of such a transaction, and when the changes are complete, the transaction can be "committed". If a fault prevents the entire set of changes from being applied on commit, or if the transaction is cancelled before it is committed, then none of that transaction's changes will be applied.

Transactions can also be started for reading only. A write transaction will be allowed to start while there is a read transaction in progress. But the commit process will block write transactions until the read transactions have finished. This ensures that anyone reading configuration data fields will see only field values that are consistent.

To prevent denial of service problems (either accidental or malicious), transactions have a limited lifetime. If a transaction remains open for too long, it will be automatically terminated; the configration database will drop its connection to the offending client.

Backward/Forward Compatibility

For example, to support a new recurring wake-up schedule that supports waking on particular days of the week, the wake schedule configuration data may need to be completely re-structured. There are several ways to do this.

One approach is to have a "configuration data upgrade" utility run when the new software is installed. However, if the new software upgrades the configuration data and then fails to fully boot, and the device is forced to fall-back to the old software, then the old software won't be able to read its configuration data anymore. This can be mitigated by keeping a complete backup copy of the configuration data prior to the software upgrade, but this either consumes space in the device's non-volatile memory or it consumes time and over-the-air bandwidth to make backup copies elsewhere in the network.

However, the recommended approach is to:

  • have newer software understand the configuration data structure used by previous versions of the software;
  • never write to the configuration data unless settings are being changed;
  • when changing settings, write the configuration data using the newest format;
  • leave the older version of the configuration data along-side the newer version (in case of later software "downgrade");
  • if both multiple versions of the same configuration data are found, use only the newest that is understood by the current running software.

Configuration Change Notifications

Sometimes, action needs to be taken whenever a configuration data field changes value. The Configuration Data API allows client software to register for notification when changes are committed to a particular branch of the configuration tree.

Access Control

Because the behaviour of applications can be affected by the configuration data that they use, configuration data can be used as an attack vector for malicious software. As a result, access to configuration data must be strictly controlled when there is any possibility that malicious software may be allowed to run on a device.

The Configuration Data system separates each applications' configration data only allowing access to its own data.

Factory Calibration

Factory calibration is different than configuration. Factory calibration settings are generally set at the factory and do not change thereafter. These settings can be read by software in the field, but cannot be written. Furthermore, even if all configuration settings are deleted and restored to defaults, the calibration data will remain untouched.

Calibration data can be accessed through the Configuration Data API, but it is not possible to write to that data unless the device is in a special "Calibration Mode".

Calibration data appears in a special branch of the configuration data tree.

Note:
This has not yet been implemented.

Security

Legato application sandboxes are chroot jails, where each application has its own unique user ID, group ID, and root directory. Files are bound into the chroot jail using bind mounts.

Access control for files is done using the underlying POSIX access control mechanisms, based on users and permissions.

See Legato Sandboxes

Internationalization

Legato provides string manipulation functions that support UTF-8 encoding.

For now, at least, other Internationalization and localization features are left up to application developers.

Power Management

Peripheral device power management is generally taken care of by the device drivers and the operating system. For example, if a device is not in use, the driver will automatically keep that device in its lowest power state.

Of course, application behaviour drives power consumption. If application code is using a peripheral device when it doesn't really need to, then power will be wasted. Power is also wasted if application code is running busy-wait loops or periodically polling for events. Instead, applications should register call-back functions to be triggered when events occur. This way application code will only run when an event occurs, rather than waking up to check for events that haven't happened. Every CPU cycle uses power, so when a power-sensitive application is woken up, it should execute as few instructions as possible before going back to sleep.

When all threads are sleeping, the operating system will reduce the CPU power state and/or memory automatically. When an event handler function returns back to the Legato event loop, it puts the thread to sleep (unless there is another event waiting). If your thread is not running the Legato event loop, to put your thread to sleep when it's not working, block your thread on poll(), select(), read(), write(), recv(), etc.

Periodic timers will wake your application up and consume power. To save power when using a periodic timer, make the timer period as long possible. Longer timer periods allow the operating system to go into deeper sleep states.

What's Next?

Runtime Architecture


Copyright (C) Sierra Wireless, Inc. 2014. All rights reserved. Use of this work is subject to license.

 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines