# Application definition .adef

Source: [https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_adef.html](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_adef.html)

This topic provides details about TelAF's application definition file.

`.adef` files can contain these sections:

## bindings

Bindings allow client-side IPC API interfaces (listed in the *requires* sections of Component.cdef files) to be bound to server-side interfaces (listed in the *provides* sections of Component.cdef files).

This gives direct control over how IPC interfaces are interconnected so reusable components and/or apps can be bound (wired) together to form a working system.

Bindings can be between two interfaces inside the same app (internal binding), or can be between a client-side interface in an app and a server-side interface provided by another app (or non-app user).

Interface instances inside the app use the executable name, component name, and the service instance name separated by a period (‘.’).

The client interface always appears first with an arrow (` -> `) to separate the client interface from the server interface.

Here's a code sample binding `clientExe.clientComponent.clientInterface` to `serverExe.serverComponent.serverInterface`:

    bindings:
    {
        clientExe.clientComponent.clientInterface -> serverExe.serverComponent.serverInterface
    }Copy to clipboard

External services provided by other apps use the app name and the service name, separated by a period ('.'):

    bindings:
    {
        clientExe.clientComponent.clientInterface -> otherApp.serverInterface
    }Copy to clipboard

To bind to a service provided by a non-app user, the app name is replaced by a user name inside angle brackets:

    bindings:
    {
        clientExe.clientComponent.clientInterface -> <root>.serverInterface
    }Copy to clipboard

If client-side code was built using the ifgen tool, the code built using mkcomp or mkexe and the pre-built executable was added to the app using a `requires:` or `bundles:` section then the tool reading your .adef file won't know about the client-side interface.

You will need to use the following work-around to bind the interfaces:

    bindings:
    {
        *.le_data -> dataConnectionService.le_data
    }Copy to clipboard

This would bind any unknown client-side `le_data` interfaces in the current app to the `le_data` server-side interface on the `dataConnectionService` app.

If server-side code was built using the ifgen tool and a compiler or using the mk tools and this executable was added to your app using a `requires:` or `bundles:` section, the tool reading your .adef file won't know about the server-side interface. Use this work-around if you need to bind to one of those interfaces inside your own app:

    bindings:
    {
        clientExe.clientComponent.clientInterface -> *.le_data
    }Copy to clipboard

This would bind the known client-side interface `clientExe.clientComponent.clientInterface` to the unknown server-side `le_data` interface served by a pre-built executable inside the current app.

## bundles

Lists additional files or directories to be copied from the build host into the app so they’re available to the app at runtime (e.g., audio files, web pages, executable scripts or programs built using some external build system).

    bundles:
    {
        file:
        {
            // Include the web server executable (built using some other build tool) 
            // in the app's /bin.
            [x] 3rdParty/webServer/bin/wwwServ  /bin/
            // Put the company logo into the app's /var/www/ for read-only access
            // by the web server.
            images/abcCorpLogo.jpg  /var/www/
            // Make the appropriate welcome page for the product appear 
            // at /var/www/index.html.        webContent/$PRODUCT_ID/welcome.html  /var/www/index.html
            // Create a file to record persistent custom audio messages into.        [w] audio/defaultMessage.wav  /usr/share/sounds/customMessage.wav
        }
         dir:
        {
            // Recursively bundle the directory containing all the audio 
            // files into the app.
            // It will appear to the app read-only under /usr/share/sounds/.
            audio   /usr/share/sounds
        }
    }Copy to clipboard

If the directory that you bundle into the app is empty, the directory will not be copied over.

Three things need to be specified for each file or directory:

- access permissions
- build system path
- target path

**Access permissions** - any combination of one or more of the following letters, enclosed in square brackets:

- r = readable
- w = writeable
- x = executable

If permissions values are not specified, then read-only ([r]) is the default.

Note: For security reasons, files and directories cannot be both writable and executable.

Directories always have executable permission set so they can be traversed. Setting the `[x]` permission in the `dir:` subsection causes the files under the directory to be made executable.

Setting `[w]` in the `dir:` subsection causes all files under that directory to be writable, but the directory itself will not be writable.

Note: Check with your module vendor to see if your target supports disk quotas. If not, directories in the persistent (flash) file system are never made writable because the on-target flash file system does not support usage quotas (yet).

**Build system path** - file system path on the build PC where the file is located at build time.

The path can be relative to the directory where the .adef file is located.

Note: Environment variables can be used inside these paths.

**Target path** - file system path on the target where the file will appear at runtime.

It's an absolute path inside the app's sandbox file system.

If the path ends with '/', it means the directory path where the source object (file or directory) will be copied. The destination object will have the same name as the source object.

If the path doesn't end in a '/', it's a full destination object path. The destination object could have a different name than the source object.

Note: If the app is running unsandboxed, the bundled files and directories can be found in their installation location under `/legato/systems/current/apps/xxxx`, (if the system is running, else current is replaced by the newest system index) where xxxx is replaced by the app name.

**Quoting Paths**

File paths can be enclosed in quotation marks (either single ' or double "). This is required when the file path contains spaces or comment start sequences

    "//" or  "/*"Copy to clipboard

**File Ownership and Set-UID Bits**

When the app is installed on a target:

- the owner and group are set to `root` on all files in the app.
- the `setuid` bit is cleared on everything in the app.

**Overriding .cdef**

If a file is bundled by a component's .cdef file and another file is bundled to the same target path by the .adef, then the file specified by the .adef will be bundled into the app.

If a directory is bundled by a component's .cdef file and another directory is bundled to the same target path by the .adef, then the two directories will be merged into the bundle, where conflicts are resolved by omitting the file from the directory specified by the .cdef.

## components

Allows components to be included in an app without being built into an executable (see [executables](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_adef.html#concept.def_files_adef__section_cyb_p45_v5b)). This can be useful if:

- the component doesn't contain any source code files
- the component's source files are run using an interpreter (such as shell scripts)
- the component contains executables that are built using a different build system prior to building the app

The `components` section contains a list of file system paths to component directories.

For example,

    components:
    {
        $SOURCE_ROOT/audioFiles  // <-- component containing just audio files.
         path/to/audioPlayer // <-- component that bundles audioExe built using 
                            // another build system.}
    processes:
    {
        run:
        {
            (audioExe)
        }
    }Copy to clipboard

Note: If a component is included in an [executable](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_adef.html#concept.def_files_adef__section_cyb_p45_v5b), then it isn't necessary to include that component in a `components:` section.

## cpuShare

Specifies the relative cpu share for an app.

Cpu share calculates the cpu percentage for a process relative to all other processes in the system. New cgroups and processes default value is **1024** if not otherwise configured. The actual percentage of the cpu allocated to a process is calculated like this:

(share value of process) / (sum of shares from all processes contending for the cpu)

All processes within a cgroup share the available cpu percentage share for that cgroup like this:

- cgroupA is configured with the default share value, 1024.
- cgroupB is configured with 512 as its share value.
- cgroupC is configured with 2048 as its share value.
- cgroupA has one process running.
- cgroupB has two processes running.
- cgroupC has one process running.

This assumes all processes in cgroupA, cgroupB and cgroupC are running and not blocked waiting for an I/O or timer event, and another system process is also running.

Sum of all shares (including the one system process) is 1024 + 512 + 2048 + 1024 = 4608

The process in cgroupA will get 1024/4608 = 22% of the cpu. The two processes in cgroupB will share 512/4608 = 11% of the cpu, each process getting 5.5%. The process in cgroupC will get 2048/4608 = 44% of the cpu. The system process will get 1024/4608 = 22% of the cpu.

    cpuShare: 512Copy to clipboard

Although apps aren't limited to running inside a sandbox (i.e., unsandboxed apps), the Supervisor still enforces limits. Ensure `cpuShare` values are set high enough for unsanboxed apps. Also see [maxFileBytes](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_adef.html#concept.def_files_adef__section_pzb_p45_v5b).

## executables

Lists executables to be constructed and moved to the `bin` directory inside the app.

An executable’s content is specified as a list of components.

    executables:
    {
        myExe = ( myComponent otherComponent )
    }Copy to clipboard

Each component included in an executable will be built and linked into the executable and its `COMPONENT_INIT` function will be run at process start-up. The component’s runtime files (shared libraries, source code, etc.) will be packaged inside the app to be installed on the target.

The mechanisms used to construct executables and components depend on the type of content and the target device.

C and C++ files will be compiled and linked using the appropriate compiler tool chain based on the target.

(In the future) Java code will be compiled to Java bytecode, and interpreted code, such as Python code will be simply copied into the app.

Note: There may be incompatibilities between components that prevent them from being included in the same executable (e.g., Java component and C components in the same executable together). The build tools will advise if there's a problem.

## groups

Supplementary groups are used to grant additional permissions or access to resources beyond the primary group membership assigned to a user. If no supplementary group is used for a user, then that user will only have access to the resources that are available to their primary group. Without supplementary groups, a user might face limitations in accessing certain files, directories, or other system resources that require permissions beyond what the primary group provides. The developer should explicitly check the application's supplementary group and add them before executing them.

    groups:
    {
        system
        diag
        radio
        inet
        locclient
    }Copy to clipboard

## username

When the username is set in the .adef file of the application, the application process(es) will be running as a given user. If the username is invalid (e.g., not set in /etc/passwd), the "root" username is used for the non-sandboxed applications and "appdefault" for the sandboxed applications.

    username: telaf  //The user needs to be a valid user in the system.Copy to clipboard

## capability

Linux capabilities allow the application, which is executed by non-root users, to perform
        privileged operations. There are currently 40 capabilities supported by the Linux kernel.
        Refer to [http://man7.org/linux/man-pages/man7/capabilities.7.html](http://man7.org/linux/man-pages/man7/capabilities.7.html) for more information.

If no Linux capabilities are set for a process or program running with a non-root user, then it will have no capability and cannot execute privileged operations.

    capability:
    {
        CAP_WAKE_ALARM
        CAP_NET_BIND_SERVICE
        CAP_NET_ADMIN
        CAP_BLOCK_SUSPEND
    }Copy to clipboard

## startorder group

When the initiation group order is specified within the adef file for each application, the
        TelAF application will be activated in accordance with the assigned startorder group. The
        available range for these groups spans from 0 to 31, where 0 signifies the highest priority
        and 31 serves as the lowest. If no priority is explicitly designated for launching the TelAF
        application, the default value is established as 31.

In the event that multiple applications share the same startorder group, they will be
        launched in accordance with their sequence in the configuration tree.

    startGroup: 0Copy to clipboard

## maxFileSystemBytes

Specifies the maximum amount of RAM that can be consumed by an app's temporary (volatile) file system at runtime.

Default is **128K**

    maxFileSystemBytes: 120KCopy to clipboard

Note: The file system size will also be limited by the `maxMemoryBytes` limit.

Warning: maxFileSystemBytes is not currently supported on Linux OS's and setting this variable will have no effect on the target.

## maxMemoryBytes

Specifies the maximum amount of memory (in bytes) that all processes in an app can share. Default is **40960K** (40MB).

    maxMemoryBytes: 1000KCopy to clipboard

Note: Will be rounded to the nearest memory page boundary.

## maxQueuedSignals

Specifies the maximum number of signals that can be waiting for delivery to processes in the app.

This limit will only be enforced when using `sigqueue()` to send a signal. Signals sent using `kill()` are limited to at most one of each type of signal anyway.

Default is **100**.

    maxQueuedSignals: 200Copy to clipboard

## maxThreads

Specifies the maximum number of threads allowed to run at one time: an integer number.

Note: A single-threaded process (a running program that doesn't start any threads other than the one running the `main()` function) counts as one thread.

Warning: When creating a new thread, the system calculates
        the total number of threads owned by all apps with the same username, not just the current
        app. The system also checks if the maxThreads limit for the current app is reached or not.
        If the app wants to limit the maximum threads within the app domain, it must configure its
        own unique user instead of sharing the user with other apps. The default user "appdefault"
        is also limited by maxThreads, but the "root" username isn't limited by maxThreads.

If `fork()` calls or `pthread_create()` calls start failing with error code `EAGAIN` (seen in strace output as `clone()` system calls), then you are probably running into this limit.

Default is **300**.

    maxThreads: 4Copy to clipboard

## maxSecureStorage Bytes

Specifies the maximum number of bytes that can be stored in Secure Storage.

Default is **8K**.

    maxSecureStorageBytes: 4KCopy to clipboard

## processes

A `processes` section specifies processes to run when the app is started including environment variables, command-line arguments, limits, and fault handling actions.

The `processes` section is divided into subsections.

If different processes have different variables, they must be in separate `processes:` sections.

    processes:
    {
        // Start up these processes when the app starts
        run:
        {
            myProc1 = ( myExe --foo -b 43 )
            myProc2 = ( myExe --bar -b 92 )
            ( myExe2 "Hello, world." )  // If no proc name is specified, uses 
                                        // the exe name by default.
        }
        // Env var settings (name = value) for all processes in this section.    envVars:
        {
            LE_LOG_LEVEL = DEBUG
        }
        priority: medium              // Starting (and maximum) scheduling 
                                      // priority.
                                      // Process can only lower its priority 
                                      // from here.
        maxCoreDumpFileBytes: 100K    // Maximum size of core dump files.
        maxFileBytes: 50K             // Files are not allowed to grow bigger 
                                      // than this.    maxLockedMemoryBytes: 32K     // Can't mlock() more than this many bytes.    maxFileDescriptors: 20        // Can't have more than this number of FDs 
                                      // open at the same time.}
    processes:
    {
        run:
        {
            ( realTimeExe )
        }
        priority: rt10   // Allow real-time scheduling (max priority 10) 
                         // for processes in this section.
         /*-- Exception handling policy for processes in this section. --*/
        faultAction: restart   // Restart the process if it fails.
    }Copy to clipboard

## run

Names a process to be started by the Supervisor when the app is started. Also specifies executable and command-line arguments.

    run:
    {
        myProc1 = ( myExe --foo -b 43 )
    }Copy to clipboard

Process name and command-line arguments are optional.

    run:
    {
        ( myExe )
    }Copy to clipboard

If the process name isn't specified, then the process will be given the same name as the executable it's running (e.g. `myExe`)

A given executable can be launched multiple times; each process needs a unique name.

    run:
    {
        process1 = ( myExe )
        process2 = ( myExe )
    }Copy to clipboard

Command-line arguments passed to the process when started can appear after the executable name.

    run:
    {
        ( myExe --foo )
    }Copy to clipboard

    run:
    {
        ( myExe --bar     // Note that the command-line can be broken into multiple lines for readability.            
                --toto )  // And it can be commented too.
    }Copy to clipboard

Executable names can be the ones listed in the app’s `executables:` section. They can also be the names of files that are bundled into the app with `[x]` (executable) permission.

Quotation marks (either single **'** or double **"**) can be used if white-space (spaces, tabs, `//`, etc.) is needed inside a command-line argument, or if an empty argument is needed ("").

## envVars

Environment variables appear as name = value pairs. First is the environment variable name and second is the variable value.

Enclose the value in quotation marks (either single ' or double ") if white-space is required:

    envVars:
    {
        LE_LOG_LEVEL = DEBUG
        MESSAGE = "The quick brown fox jumped over the lazy dog."
    }Copy to clipboard

## faultAction

Specifies the action the Supervisor should take when the process terminates with a non-zero exit code or because of an un-caught signal (e.g., SIGSEGV, SIGBUS, SIGKILL).

Possible values are:

- `ignore` - Supervisor just logs a warning message; no further action taken.
- `restart` - log a critical message and restart the process.
- `restartApp` - log a critical message and restart the entire app.
- `stopApp` - log a critical message and terminate the entire app (send all processes the SIGTERM signal, followed shortly by SIGKILL).
- `reboot` - log an emergency message and reboot the system.

Default is **ignore**.

    faultAction: restartCopy to clipboard

## priority

Specifies the starting (and maximum) scheduling priority. A running app process can only lower its priority from this point. Once it has lowered its priority, it can't raise it again (e.g., if the process starts at medium priority and reduces to low priority, it can't go back to medium priority). The default is **medium**.

Values:

- **idle** - for low priority processes that get CPU time only if no other processes are waiting.
- **low**, **medium**, **high** - intended for normal processes that contend for the CPU. Processes with these priorities don't preempt each other, but their priorities affect how they're inserted into the scheduling queue (high to low).
- **rt1** to **rt32** - intended for (soft) realtime processes. A higher realtime priority will preempt a lower realtime priority (ie. rt2 would preempt rt1). Processes with any realtime priority will preempt processes with high, medium, low and idle priorities.

Warning: Processes assigned realtime priorities preempt TelAF framework processes. Ensure that your design relinquishes the CPU appropriately. Processes assigned a realtime priority aren't constrained by an app's cpu share even if the process later changes to a non-realtime priority. This also applies to all threads the process spawns.

    priority: mediumCopy to clipboard

## maxCoreDumpFileBytes

Specifies the maximum size (in bytes) of core dump files that can be generated by processes.

Default is **100K**

Note: Core dump file size is limited by [maxFileBytes](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_adef.html#concept.def_files_adef__section_pzb_p45_v5b). If the the core file is generated in
        the sandbox's temporary runtime file system, it 'll also be limited by [maxFileSystemBytes](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_adef.html#concept.def_files_adef__section_hyb_p45_v5b).

    maxCoreDumpFileBytes: 100K
    maxFileBytes: 100K
    maxFileSystemBytes: 200KCopy to clipboard

## maxFileBytes

Specifies the maximum size processes can make files. The *K* suffix permits specifying in kilobytes (multiples of 1024 bytes).

Default is **100K**

    maxFileBytes: 200KCopy to clipboard

Exceeding this limit results in a `SIGXFSZ` signal sent to the process. By default, this kills the process, but it can be blocked or caught to receive an error with `errno` set to `EFBIG`.

Although apps aren't limited to running inside a sandbox (i.e., unsandboxed apps), the
        Supervisor still enforces limits. Ensure `maxFileBytes` values are set high
        enough for unsanboxed apps. Also see [cpuShare](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_adef.html#concept.def_files_adef__section_zxb_p45_v5b).

Note: If the file is in the sandbox's temporary runtime file system, the file size will also be limited by [maxFileSystemBytes](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_adef.html#concept.def_files_adef__section_hyb_p45_v5b) and [maxMemoryBytes](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_adef.html#concept.def_files_adef__section_lyb_p45_v5b).

## maxFileDescriptors

Specifies the maximum number of file descriptors a process can have open at one time.

Default is **256**

    maxFileDescriptors: 100Copy to clipboard

## maxLockedMemoryBytes

Specifies the maximum bytes of memory the process can lock into physical RAM (e.g., using `mlock()` ).

Can't be higher than [maxMemoryBytes](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_adef.html#concept.def_files_adef__section_lyb_p45_v5b).

Default is **8K**

    maxLockedMemoryBytes: 100KCopy to clipboard

Note: Also limits the maximum number of bytes of shared memory the app can lock into memory using `shmctl()`.

## maxStackBytes

Specifies the maximum bytes of memory the process uses for its stack.

This value must be less than [maxMemoryBytes](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_adef.html#concept.def_files_adef__section_lyb_p45_v5b).

The default is determined by the OS.

    maxStackBytes: 800KCopy to clipboard

## watchdogAction

Specifies the action the Supervisor should take when a **process** that is subscribed to the watchdog daemon fails to kick the watchdog before the process reaches it's timeout value.

Possible watchdog actions:

- `ignore` - Supervisor just logs a warning message; no further action taken.
- `restart` - log a critical message and restart the process.
- `restartApp` - log a critical message and restart the entire app.
- `stop` - Supervisor terminates the process if it's still running.
- `stopApp` - log a critical message and terminate the entire app (send all processes the SIGTERM signal, followed shortly by SIGKILL).
- `reboot` - log an emergency message and reboot the system.

If a watchdog action has not been supplied, the default action is **restart**.

## watchdogTimeout

Specifies the timeout length (in milliseconds) for watchdogs called by processes in the enclosing processes section.

To register a process with the watchdog daemon call `le_wdog_Kick()` from within the process. The watchdog daemon then starts the timer, if the process fails to call `le_wdog_Kick()` within the given timeout, the Supervisor is notified will take the action specified in watchdogAction

    watchdogTimeout: 10000 // Process must call le_wdog_Kick() at least 
                           // every 10 seconds.Copy to clipboard

To disable the watchdog for a given process set the `watchdogTimeout` to `never:`

    watchdogTimeout: never  // Disable watchdog for these processes.Copy to clipboard

## extern

Externs indicate which of your app's IPC API interfaces should be made available for binding to the IPC API interfaces of other apps. (The binding is preferably done in [a .sdef file's bindings section](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_sdef.html#concept.def_files_sdef__section_mwz_4m5_v5b), but may also be done in [a .adef file's bindings section](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_adef.html#concept.def_files_adef__section_fxb_p45_v5b).)

For example,

    extern:
    {
        aliasName = exeName.componentName.interfaceName
    }Copy to clipboard

This also creates an alias for each interface that doesn't include any internal implementation details of your app.

Inside your app, its interfaces are identified using the names of the executables and components that implement them. Exposing these details outside your app can create maintainability problems later (see [https://en.wikipedia.org/wiki/Information_hiding](https://en.wikipedia.org/wiki/Information_hiding)).

Externally, the interface will be identified using the app name and the external alias (`appName.aliasName`), thereby hiding from other apps the details of which executable and component implements the interface. Encapsulating the app's implementation details allows them to be changed later without affecting other apps that communicate with this app. Only if an app's external interface changes would any other app be affected.

Use period characters ('.') to seperate components of an interface. (E.g., executables, components, interface names.) External aliases must not contain any period characters ('.').

When the external alias has the same name that the component uses as the interface name, it's possible to save time by omitting the `aliasName =` part. For example,

    extern:
    {
        exeName.componentName.interfaceName
    }Copy to clipboard

This is equivalent to

    extern:
    {
        interfaceName = exeName.componentName.interfaceName
    }Copy to clipboard

## Server-side Example

This code sample declares the `temperature` interface on the `thermistor` component in the `sensor` executable should be made into a bindable external server-side interface (service) called `spaceTemp:`

    extern:
    {
        spaceTemp = sensor.thermistor.temperature
    }Copy to clipboard

If the app was called *thermometer*, then other apps could bind their client-side interfaces to `thermometer.spaceTemp` to receive temperature readings from this sensor app.

## Client-side Example

This code sample declares that the `temperature` interface on the `tempInput` component in the `controller` executable should be made into a bindable external interface:

    extern:
    {
        controller.tempInput.temperature
    }Copy to clipboard

If this app were called thermostat, then to outsiders (e.g., in a .sdef file or another app's .adef file), the interface would be called `thermostat.temperature`.

## Binding Example

To bind the client-side interface to the server-side interface (service) defined above, a .sdef file could contain the following:

    bindings:
    {
        thermostat.temperature -> thermometer.spaceTemp
    }Copy to clipboard

## requires and provides

The `requires:` and `provides:` subsections within the `extern:` section are used only when apps contain pre-built binary executables that have TelAF IPC API interfaces. For example, when someone uses ifgen to generate code that they compile into an executable and add to their app using a `bundles:` section in a .cdef or .adef file, then the TelAF build tools (mkapp or mksys) can't tell that this executable has IPC interfaces available for binding.

Note: `requires:` and `provides:` subsections are generated by mkapp when the `--bin-pack` command-line option is used to generate a pre-built binary version of an app. While the `requires:` and `provides:` subsections *can* be used within the `extern:` section in situations like the example given above, they are not normally used in hand-coded .adef files.

    extern:
    {
        provides:
        {
            spaceTemp = $CURDIR/interfaces/temperature.api
        }
    }Copy to clipboard

Service "spaceTemp" implements the IPC API defined in `interfaces/temperature.api` under the directory containing the .adef file.

    extern:
    {
        requires:
        {
            temperature = $CURDIR/interfaces/temperature.api
        }
    }Copy to clipboard

The app has a client-side interface called "temperature" that requires a service that implements the IPC API defined in `interfaces/temperature.api` under the directory containing the app's .adef file. The app's "temperature" interface must be bound to a service that implements this temperature API using a `bindings:` section in a .sdef file

    bindings:
    {
        clientApp.temperature -> serverApp.spaceTemp
    }Copy to clipboard

or elsewhere in the app's .adef file

    bindings:
    {
        *.temperature -> serverApp.spaceTemp
    }Copy to clipboard

Client-side pre-built interfaces can be marked "optional" to tell mksys not to generate an error if the interface is not bound to anything.

    extern:
    {
        requires:
        {
            temperature = $CURDIR/interfaces/temperature.api [optional]
        }
    }Copy to clipboard

## requires

The `requires:` section specifies things the app needs from its runtime environment.

It can contain various subsections.

## configTree

Declares the app requires access to a specified configuration tree. Each app has its own configuration tree named after the app. There's also a system configuration tree that contains privileged system data.

By default, an app only has read access to its own configuration tree.

Apps can be granted read access or both read and write access to trees using an optional access permission specifier:

- `[r]` - grant read-only access
- `[w]` - grant read and write access

If access is granted to a tree, but the access mode ([r] or [w]) isn't specified, only read permission will be granted.

A special tree name "." can be used to refer to the app's own configuration data tree.

    requires:
    {
        configTree:
        {
            [w] .       // I need write access to my configuration data.        otherApp    // I need read access to another app's configuration data.
        }
    }Copy to clipboard

Warning: Because config data can be saved to flash storage, granting write access to a config tree can make it possible for the app to wear out your flash device. Granting an untrusted app write access to another app's config settings creates a security hole, because it makes it possible for the untrusted app to interfere with the other app's operation. It's especially dangerous to grant write access to the system tree, because it's possible to completely compromise the target device. Even read access may be dangerous if any kind of security key, including PIN and PUK codes, are kept in the system tree. Don't give apps direct access to the `system tree`.

## dir

Used to declare directories located on the target outside of the app that are to be made accessible to the app.

The location inside the app's sandbox where the directory will appear is also specified.

Things listed here are expected to be found on the target at runtime. They are not copied into the app at build time; they are made accessible to the app inside of its sandbox at runtime.

Three things need to be specified for each directory:

- access permissions
- source path
- destination path

**Access permissions** - any combination of one or more of the following letters, enclosed in square brackets:

- r = readable
- w = writeable
- x = executable

If permissions values are not specified, then the directory will be mounted into the sandbox without modifying any permissions. Applications can mount any directories except for the TelAF directory (/mnt/flash/legato or /legato).

Specifying the permission values on a directory will only modify the permission of the directory. Any subdirectory and files will remain the same.

Also specifying the permission value on directories is only allowed in two locations:

- Any directory under /home/root/
- Any directory under /mnt/flash/ except /legato

**Source path**is the path to the directory **outside** of the app. This must be an absolute path (beginning with "/") and can never end in a "/".

**Destination path** is the absolute path **inside** the app’s sandbox where the directory will appear at runtime.

Paths can be enclosed in quotation marks (either single ' or double "). This is required when it contains spaces or character sequences that would start comments.

If the destination path ends in a "/", the name from the source is appended to it. Otherwise, only the destination path is used. That means `/foo/bar` /baz will appear as `/baz` inside the sandbox, and `/foo/bar` /baz/ will appear as `/baz/bar` inside the sandbox.

    requires:
    {
        dir:
        {
           // I need access to /proc for debugging.       /proc   /         
    
           // For now, I want access to all executables and libraries 
           // in /bin and /lib.
           // Later I'll remove this and replace with just the files
           // I really need in the field.
           // Also, I don't want to hide the stuff that the tools 
           // automatically bundle into my app's /bin and /lib for 
           // me, so I'll make the root file system's /bin and /lib 
           // accessible as my app's /usr/bin and /usr/lib.
           /bin       /usr/bin
           /lib       /usr/lib
    
           // I need permissions to create a file in /home/root/myTestDir
           // Execute is needed since we need to search a directory before 
           // creating the file.
           [rwx] /home/root/myTestDir    /myTestDir
        }
    }Copy to clipboard

Warning: Any time anything is made accessible from inside an app sandbox, the security risks must be considered carefully. Ask yourself if access to the object can be exploited by the app (or a hacker who has broken into the app) to access sensitive information or launch a denial-of-service attack on other apps within the target device or other devices connected to the target device?

Note: It's not possible to put anything inside of a directory that was mapped into the app from outside of the sandbox. If you *require* `/bin` to appear at `/usr/bin`, you can't then *bundle* a file into `/usr/bin` or *require* something to appear in `/usr/bin`; that would have an effect on the contents of the /bin directory outside of the app. If an access to the directory /dev/shm is required, it should be listed in this subsection as below mentioned, because it is treated like a directory even if it is located in /dev.

    requires:
    {
        dir:
        {
            /dev/shm    /dev/shm
        }
    }Copy to clipboard

        If your `requires:` dir: section includes /dev/shm then, inside your TelAF application after calling: shm\_open (sharedMemRegion, ...) you have to run: chmod ("/dev/shm/sharedMemRegion", S\_IRWXU | S\_IRWXG | S\_IRWXO);

## file

Declares:

- specific files located on the target outside of the app, but made accessible to the app.
- location inside the app's sandbox where the file will appear.

Things listed in `requires` are expected to be found on the target at runtime. They're not copied into the app at build time; they are made accessible to the app inside of its sandbox at runtime.

Each entry consists of:

- access permissions
- source path
- destination path

**Access permissions** - any combination of one or more of the following letters, enclosed in square brackets:

- r = readable
- w = writeable
- x = executable

If permission values are not specified, then the file will be mounted into the sandbox without modifying any permissions.

A file path can be enclosed in quotation marks (either single ' or double "). This is required when it contains spaces or character sequences that would start comments.

The first path can't end in a '/'.

If the second path ends in a '/', then it's specifying the directory where the object appears, and the object has the same name inside the sandbox as it has outside the sandbox.

    requires:
    {
        file:
        {
            // I get character stream input from outside via a named pipe
            // (read-only)        /var/run/someNamedPipe  /var/run/
    
            // I need to be able to play back audio files installed 
            // in /usr/local/share/audio.
            "/usr/local/share/audio/error message.wav" /usr/share/audio/
            '/usr/local/share/audio/success message.wav' /usr/share/audio/
    
             // Need to write to log.txt. Read is required to open the file.
            [rw] /home/root/myFiles/log.txt      /usr/myFiles/
    
             // I get read-only access to the NMEA port.        /dev/nmea         /dev/nmea
        }
    }Copy to clipboard

It's also possible to give the object a different names inside and outside of the sandbox by adding a name to the end of the second path.

    requires:
    {
        file:
        {
            // Program uses /var/run/someNamedPipe which it 
            // calls /var/run/externalPipe.        /var/run/someNamedPipe  /var/run/externalPipe
        }
    }Copy to clipboard

Warning: When something is accessible from inside an app sandbox, there are potential security risks (e.g., access to the object could be exploited by the app, or hacker, to access sensitive information or launch a denial-of-service attack on other apps within the target device or other devices connected to the target device).

For example, appA will create the shared memory files /dev/shm/appShm00 and /dev/shm/shamem. If a second app, called appB wants to access to these files, it needs to define them inside its `appB.adef` as shown below:

    requires:
    {
        file:
        {
            // Import the shared memory /dev/shm/appShm00 
            // and /dev/shm/shamem into the appB.
            /dev/shm/appShm00  /dev/shm/appShm00 
            /dev/shm/shamem    /dev/shm/shamem
        }
    }Copy to clipboard

## device

Declares:

- device files that reside on the target outside of the app, but made accessible to the app.
- location inside the app's sandbox where the file will appear.
- access permissions the app is given to the device file.

Things listed in `requires` are expected to be found on the target at runtime. They're not copied into the app at build time; they are made accessible to the app inside of its sandbox at runtime.

Each entry consists of two file system paths and a set of optional access permissions:

- access permissions, readable ([r]) and/or writeable ([w]). Executable isn't allowed on device files. If permission values are not specified, then read-only ([r]) is the default.
- path to the object in the file system outside of the app, which must be an absolute path (beginning with ‘/’). This must be a path to a valid character or block device file.
- absolute file system path inside the app’s sandbox where the object will appear at runtime.

A file path can be enclosed in quotation marks (either single ' or double "). This is required when it contains spaces or character sequences that would start comments.

The first path can't end in a '/'.

If the second path ends in a '/', then it's specifying the directory where the object appears, and the object has the same name inside the sandbox as it has outside the sandbox.

    requires:
    {
        device:
        {
            // I get read-only access to the SPI port.
            [r]     /dev/some_spi   /dev/some_spi
    
            // I get read and write access to the I2C port.        [rw]    /dev/some_i2c   /dev/
        }
    }Copy to clipboard

Note that if a hot-plug device is unplugged and plugged back in, the app must be restarted before it can access the device.

It's also possible to give the object a different names inside and outside of the sandbox by adding a name to the end of the second path.

    requires:
    {
        device:
        {
            /dev/ttyS0  /dev/port1     // Program uses /dev/port1, but UART0 is 
                                       // called /dev/ttyS0.    }
    }Copy to clipboard

Warning: 
        
When something is accessible from inside an app sandbox, there are potential security risks (e.g., access to the object could be exploited by the app, or hacker, to access sensitive information or launch a denial-of-service attack on other apps within the target device or other devices connected to the target device).

This section is experimental. Future releases of may not support this section.

Note: If an access to the directory `/dev/shm` is required, it should be listed in the subsection `dir:` because it is treated like a directory even if it is located in `/dev`.

## kernelModules

Your app may depend on one or more kernel modules to load before the app starts. Use `kernelModules:` section to declare the app dependencies on kernel modules. Each entry is a path to another [.mdef](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_mdef.html) definition file. This section marks that the app has a requirement on a kernel module but does not add the kernel module to the TelAF system. The kernel module needs to be **explicitly** **added** to kernelModules: section of your systems [.sdef](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_sdef.html). After the kernel modules are added to the sdef, the modules will be bundled as a part of the application and installed with the TelAF system. The listed modules will be installed before the app starts. In the example below, hello and world kernel modules will be installed before the app starts.

    requires:
    {
        kernelModules:
        {
           $CURDIR/kernelmodule/hello
           $CURDIR/kernelmodule/world [optional]
        }
    }Copy to clipboard

In case a module fails to load, the fault handler kicks in which triggers the fault action of each process in the app (see [faultAction](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_adef.html#concept.def_files_adef__section_fzb_p45_v5b)) in order to attempt the recovery of the app. The faultAction values relevant for an app with kernel modules dependencies are:

- restartApp - log a critical message and restart the entire app.
- stopApp - log a critical message and terminate the entire app.
- reboot - log an emergency message and reboot the system.

If the fault action for each process must not be triggered when a module fails to load, the module must be marked as optional by using '[optional]' tag. In the above example, world is an optional module.

## sandboxed

Specifies if the app will be launched inside a sandbox.

Permitted content in this section is:

- **true** - app will be run inside of a sandbox.
- **false** - app won't be run in a sandbox.

The default is **true**.

If an app is unsandboxed (app isn't inside of a sandbox), it can see the target device's real root file system. A sandboxed app can't see the target's real root file system; a sandboxed app has a separate root file system, which it can't leave.

Each app has its own user and primary group IDs. The app's user name and primary group name are both `appxxxx`, where the `xxxx` is the name of the app.

User and/or group will be automatically created if missing for the specified app, but only users and groups of sandboxed apps will automatically be deleted when those apps are uninstalled.

    sandboxed: falseCopy to clipboard

## start

Specifies if the app should start automatically at start-up:

- **auto** starts automatically by the Supervisor.
- **manual"** starts through manual prompt to the Supervisor. Default is **auto**.

    start: autoCopy to clipboard

## tags

The tags section is an optional field that allow clients to specify key-value pairs on a per application basis. This feature is used in the .adef file of the specific application that clients wish to set tags for. Tags must be used as a key-value pair, where key is the tag name and value is the value associated with that tag.

## version

Optional field that specifies a string to use as the app's version string.

    version: 0.3aCopy to clipboard

Note:
- The `--append-to-version` option to mkapp can be used to add to the app's version string.
- `app foo version` can be run on-target to get the version string of the app called "foo".

## watchdogAction

Specifies the action the Supervisor should take when any app's process fails to kick the watchdog daemon before the app reaches it's timeout value. If a specific action need to be taken for individual processes then that should be set in the watchdogAction .

Possible watchdog actions:

- `ignore` - Supervisor just logs a warning message; no further action taken.
- `restart` - log a critical message and restart the process.
- `restartApp` - log a critical message and restart the entire app.
- `stop` - Supervisor terminates the process if it's still running.
- `stopApp` - log a critical message and terminate the entire app (send all processes the SIGTERM signal, followed shortly by SIGKILL).
- `reboot` - log an emergency message and reboot the system.

If a watchdog action has not been supplied, the default action is **restart**.

To register a process with the watchdog daemon call `le_wdog_Kick()` from within the process. The watchdog daemon then starts the timer, if the process fails to call `le_wdog_Kick()` within the given timeout, the Supervisor is notified will take the action specified in [watchdogAction](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_adef.html#concept.def_files_adef__section_pcc_p45_v5b)

## watchdogTimeout

Specifies the timeout length (in milliseconds) for watchdogs called by an app.

To register an app with the watchdog daemon call `le_wdog_Kick()` from within the app. The watchdog daemon then starts the timer, if the process fails to call `le_wdog_Kick()` within the given timeout, the Supervisor is notified will take the action specified in [watchdogAction](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_adef.html#concept.def_files_adef__section_pcc_p45_v5b)

    watchdogTimeout: 10000 // Process will call le_wdog_Kick() every 10 seconds.Copy to clipboard

To disable the watchdog for a given process set the `watchdogTimeout` to `never:`

    watchdogTimeout: never  // Disable watchdog for these processes.Copy to clipboard

## maxWatchdogTimeout

The `maxWatchdogTimeout` section should be set for critical services that
        are configured as auto started. Setting the `maxWatchdogTimeout` will invoke
        a recovery procedure that will:

- first try to perform the watchdogAction to recover the hung process.
- wait for the `maxWatchdogTimeout` value to elapse again.
- if the process is still not started then the target will be rebooted.

The `maxWatchdogTimeout` starts counting on system boot. The app can't be stopped longer than the timeout given in `maxWatchdogTimeout`. If it is the system will try and "recover itself" and may reboot the target.

The `maxWatchdogTimeout` value can not be set to `never`, if you wish to disable it, remove the `maxWatchdogTimeout` from the app's .adef and reinstall the app.

If a `maxWatchdogTimeout` is set then le\_wdog\_Timeout() can not exceed the `maxWatchdogTimeout` value.

Warning: `watchdogActions` **ignore**, **stop** and **stopApp** should not be used when a `maxWatchdogTimeout` is configured.

**Parent Topic:** [Definition files](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files.html)

Last Published: Apr 23, 2025

[Previous Topic
System definition .sdef](https://docs.qualcomm.com/bundle/publicresource/80-41102-3/topics/def_files_sdef.md) [Next Topic
Component definition .cdef](https://docs.qualcomm.com/bundle/publicresource/80-41102-3/topics/def_files_cdef.md)