Snapdragon® Telematics Application Framework (TelAF) Interface Specification
Config Tree Admin API

API Reference

The Config Tree Admin API is intended to provide tools help with administration of Trees. These administration functions are provided as a separate API for security reasons. The Admin API needs to be explicitly included to use these admin functions keeping access separate from the main app permissions.

The API includes the following functions:

  • an iterator function to walk the current list of trees.
  • an import function to bulk load the data (full or partial) into a tree from a given file in .cfg format or .json format.
  • an export function to save the contents of a tree.
  • a delete function to remove a tree and all its objects.

Example of Iterating the List of Trees:

void ListTrees(void)
{
// Open a tree iterator. Note that this isn't the same iterator that you would be using for
// read and write transactions.
LE_INFO("Listing configuration Trees in the current system...");
// The iteratorRef starts at item -1, so we need to start with calling NextTree in our loop.
while (le_cfgAdmin_NextTree(iteratorRef) == LE_OK)
{
// Simply extract the name of the tree and dump it to the device log.
char treeName[MAX_TREE_NAME_BYTES] = "";
if (le_cfgAdmin_GetTreeName(iteratorRef, treeName, sizeof(treeName)) == LE_OK)
{
LE_INFO("Tree: '%s'", treeName);
}
}
// Again, this isn't a regular config node iterator, so you need to use the cfgAdmin
// release on the tree iterator.
}

Example of Importing a Tree:

void ImportMyTree(const char* filePath)
{
static char resolvedPath[PATH_MAX] = "";
// Because the configTree is a seperate process, we need to make sure that the path we
// received is an absolute path.
LE_FATAL_IF(realpath(filePath, resolvedPath) == NULL, "Could not resolve filePath: error %d",
errno);
// Open a write transaction on /myData, as we will be writing to the configTree.
le_cfg_IteratorRef_t iteratorRef = le_cfg_CreateWriteTxn("/myData");
// Our iterator is currently on /myData, so everything under that node is replaced. If we
// want to replace the whole tree we could supply a "/" here instead of using the iterator's
// current location. Alternativly, we could have opened or moved the iterator to "/" in the
// first place.
LE_FATAL_IF(le_cfgAdmin_ImportTree(iteratorRef, resolvedPath, "") != LE_OK,
"Error occured while writing config data.");
// Close up the iterator,free it's resources, and commit the new data to the configTree.
le_cfg_CommitTxn(iteratorRef);
}
// To import the config data back from ./myData.cfg:
ImportMyData("./myData.cfg");

Supported JSON Types:

Primitive Types:

  • String

The template of a string type config field is as follows:

{
"name": "aStringField", // The field name of a string type node.
"type": "string", // The type should be string.
"value": "someStringValue" // The field value.
}

Example:

{
"name": "valueA",
"type": "string",
"value": "aNewValue"
}
- Integer
The template of a integer type config field is as follows:
@code
{
"name": "anIntField", // The field name of a string type node.
"type": "int", // The type should be int.
"value": // The field value, range is -2,147,483,648 to 2,147,483,647.
}

Example:

{
"name": "valueA",
"type": "int",
"value": 1024
}
  • Float

The template of a string type config field is as follows:

{
"name": "aFloatField", // The field name of a string type node.
"type": "float", // The type should be string.
"value": // The field value.
}

Example:

{
"name": "valueA",
"type": "float",
"value": 10.24
}
  • Boolean

The template of a string type config field is as follows:

{
"name": "aBoolField", // The field name of a string type node.
"type": "bool", // The type should be string.
"value": // true or false.
}

Example:

{
"name": "valueA",
"type": "bool",
"value": false
}

Nested value:

  • Stem

The template of a string type config field is as follows:

{
"name": "aNestedValue", // The field name of a string type node.
"type": "stem", // The type should be string.
"children": [] // The array of nested fields.
}

Example:

{
"name": "nestedValues",
"type": "stem",
"children": [
{
"name": "aBoolValue",
"type": "bool",
"value": true
},
{
"name": "aSecondBoolValue",
"type": "bool",
"value": false
},
{
"name": "aStringValue",
"type": "string",
"value": "Something \"wicked\" this way comes!"
},
{
"name": "anIntVal",
"type": "int",
"value": 1024
},
{
"name": "aFloatVal",
"type": "float",
"value": 10.24
}
]
}

Example of Exporting a Tree

void ExportMyData(const char* filePath)
{
static char resolvedPath[PATH_MAX] = "";
// Because the configTree is a seperate process, we need to make sure that the path we
// received is an absolute path.
LE_FATAL_IF(realpath(filePath, resolvedPath) == NULL, "Could not resolve filePath: error %d",
errno);
// Open a read transaction on /myData.
le_cfg_IteratorRef_t iteratorRef = le_cfg_CreateReadTxn("/myData");
// Our iterator is currently on /myData, so everything under that node is exported. If we
// want to export the whole tree we could supply a "/" here instead of using the iterator's
// current location. Alternativly, we could have opened or moved the iterator to "/" in the
// first place.
LE_FATAL_IF(le_cfgAdmin_ExportTree(iteratorRef, resolvedPath, "") != LE_OK,
"Error occured while writing config data.");
// Close up the iterator and free it's resources.
le_cfg_CancelTxn(iteratorRef);
}
// To export the config tree to ./myData.cfg:
ExportMyData("./myData.cfg");

Example of Deleting a Tree

// To delete a tree simply call le_cfgAdmin_DeleteTree. For example to delete the tree foo,
// call as follows:

Copyright (C) Sierra Wireless Inc.