Пример #1
0
//--------------------------------------------------------------------------------------------------
bool proc_IsRealtime
(
    proc_Ref_t procRef             ///< [IN] The process reference.
)
{
    // Read the priority setting from the config tree.
    le_cfg_IteratorRef_t procCfg = le_cfg_CreateReadTxn(procRef->cfgPathRoot);

    char priorStr[LIMIT_MAX_PRIORITY_NAME_BYTES];
    le_result_t result = le_cfg_GetString(procCfg,
                                          CFG_NODE_PRIORITY,
                                          priorStr,
                                          sizeof(priorStr),
                                          "medium");

    le_cfg_CancelTxn(procCfg);

    if ( (result == LE_OK) &&
         (priorStr[0] == 'r') && (priorStr[1] == 't') )
    {
        return true;
    }

    return false;
}
Пример #2
0
// -------------------------------------------------------------------------------------------------
static json_t* CreateJsonNodeFromIterator
(
    le_cfg_IteratorRef_t iterRef  ///< The iterator to read from.
)
// -------------------------------------------------------------------------------------------------
{
    char nodeName[LE_CFG_NAME_LEN_BYTES] = "";

    le_cfg_nodeType_t type = le_cfg_GetNodeType(iterRef, "");
    le_cfg_GetNodeName(iterRef, "", nodeName, sizeof(nodeName));

    json_t* nodePtr = CreateJsonNode(nodeName, NodeTypeStr(type));

    switch (type)
    {
        case LE_CFG_TYPE_EMPTY:
            json_object_set_new(nodePtr,
                                JSON_FIELD_TYPE,
                                json_string(NodeTypeStr(LE_CFG_TYPE_STEM)));
            json_object_set_new(nodePtr, JSON_FIELD_CHILDREN, json_array());
            break;

        case LE_CFG_TYPE_BOOL:
            json_object_set_new(nodePtr,
                                JSON_FIELD_VALUE,
                                json_boolean(le_cfg_GetBool(iterRef, "", false)));
            break;

        case LE_CFG_TYPE_STRING:
            {
                char strBuffer[LE_CFG_STR_LEN_BYTES] = "";
                le_cfg_GetString(iterRef, "", strBuffer, LE_CFG_STR_LEN_BYTES, "");
                json_object_set_new(nodePtr, JSON_FIELD_VALUE, json_string(strBuffer));
            }
            break;

        case LE_CFG_TYPE_INT:
            json_object_set_new(nodePtr,
                                JSON_FIELD_VALUE,
                                json_integer(le_cfg_GetInt(iterRef, "", false)));
            break;

        case LE_CFG_TYPE_FLOAT:
            json_object_set_new(nodePtr,
                                JSON_FIELD_VALUE,
                                json_real(le_cfg_GetFloat(iterRef, "", false)));
            break;

        case LE_CFG_TYPE_STEM:
        default:
            // Unknown type, nothing to do
            json_decref(nodePtr);
            nodePtr = NULL;
            break;
    }

    return nodePtr;
}
Пример #3
0
//--------------------------------------------------------------------------------------------------
static void LoadECallSettings
(
    int32_t*  hMinAccuracyPtr,
    int32_t*  dirMinAccuracyPtr
)
{
    char psapStr[LE_MDMDEFS_PHONE_NUM_MAX_BYTES] = {0};

    LE_DEBUG("Start reading eCall app settings in Configuration Tree");

    le_cfg_IteratorRef_t eCallCfgRef = le_cfg_CreateReadTxn(CFG_ECALL_APP_PATH);

    // Get PSAP
    if (le_cfg_NodeExists(eCallCfgRef, CFG_NODE_PSAP))
    {
        if ( le_cfg_GetString(eCallCfgRef, CFG_NODE_PSAP, psapStr, sizeof(psapStr), "") != LE_OK )
        {
            LE_FATAL("No node value set for '%s', exit the app!", CFG_NODE_PSAP);
        }
        LE_DEBUG("eCall settings, PSAP number is %s", psapStr);
        if (le_ecall_SetPsapNumber(psapStr) != LE_OK)
        {
            LE_FATAL("Cannot set PSAP number, exit the app!");
        }
    }
    else
    {
        LE_FATAL("No value set for '%s', restart the app!", CFG_NODE_PSAP);
    }

    // Get minimum horizontal accuracy
    if (le_cfg_NodeExists(eCallCfgRef, CFG_NODE_H_MIN_ACCURACY))
    {
        *hMinAccuracyPtr = le_cfg_GetInt(eCallCfgRef, CFG_NODE_H_MIN_ACCURACY, DEFAULT_H_ACCURACY);
        LE_DEBUG("eCall app settings, horizontal accuracy is %d meter(s)", *hMinAccuracyPtr);
    }
    else
    {
        *hMinAccuracyPtr = DEFAULT_H_ACCURACY;
    }

    // Get minimum direction accuracy
    if (le_cfg_NodeExists(eCallCfgRef, CFG_NODE_DIR_MIN_ACCURACY))
    {
        *dirMinAccuracyPtr = le_cfg_GetInt(eCallCfgRef, CFG_NODE_DIR_MIN_ACCURACY, DEFAULT_DIR_ACCURACY);
        LE_DEBUG("eCall app settings, direction accuracy is %d degree(s)", *dirMinAccuracyPtr);
    }
    else
    {
        *dirMinAccuracyPtr = DEFAULT_DIR_ACCURACY;
    }

    le_cfg_CancelTxn(eCallCfgRef);
}
Пример #4
0
//--------------------------------------------------------------------------------------------------
LE_SHARED appCfg_FaultAction_t appCfg_GetProcFaultAction
(
    appCfg_Iter_t procIterRef   ///< [IN] Apps iterator
)
{
    CheckFor(procIterRef, ITER_TYPE_PROC);

    char faultActionStr[LIMIT_MAX_FAULT_ACTION_NAME_BYTES];
    le_result_t result = le_cfg_GetString(procIterRef->cfgIter,
                                          CFG_NODE_FAULT_ACTION,
                                          faultActionStr,
                                          sizeof(faultActionStr),
                                          "");

    if (result != LE_OK)
    {
        LE_CRIT("Fault action string for process is too long.  Assume fault action is 'ignore'.");
        return APPCFG_FAULT_ACTION_IGNORE;
    }

    if (strcmp(faultActionStr, RESTART_STR) == 0)
    {
        return APPCFG_FAULT_ACTION_RESTART;
    }

    if (strcmp(faultActionStr, RESTART_APP_STR) == 0)
    {
        return APPCFG_FAULT_ACTION_RESTART_APP;
    }

    if (strcmp(faultActionStr, STOP_APP_STR) == 0)
    {
        return APPCFG_FAULT_ACTION_STOP_APP;
    }

    if (strcmp(faultActionStr, REBOOT_STR) == 0)
    {
        return APPCFG_FAULT_ACTION_REBOOT;
    }

    if (strcmp(faultActionStr, IGNORE_STR) == 0)
    {
        return APPCFG_FAULT_ACTION_IGNORE;
    }

    LE_WARN("Unrecognized fault action '%s'.  Defaulting to fault action 'ignore'.",
            faultActionStr);

    return APPCFG_FAULT_ACTION_IGNORE;
}
Пример #5
0
//--------------------------------------------------------------------------------------------------
static le_result_t LoadRatList
(
    const char  *ratPath,
    uint32_t    *ratMaskPtr
)
{
    uint32_t idx=0;
    LE_DEBUG("Load Rat Preference <%s>",ratPath);

    le_cfg_IteratorRef_t ratCfg = le_cfg_CreateReadTxn(ratPath);

    *ratMaskPtr = 0;
    do {
        // Get the node name.
        char ratNodeName[LIMIT_MAX_PATH_BYTES] = {0};
        char ratNodeValue[LIMIT_MAX_PATH_BYTES] = {0};

        sprintf(ratNodeName,PATTERN_RAT"%d",idx);

        // This is the exist state for the loop
        if (le_cfg_IsEmpty(ratCfg, ratNodeName))
        {
            LE_DEBUG("'%s' does not exist. stop reading configuration", ratNodeName);
            break;
        }

        if ( le_cfg_GetString(ratCfg,ratNodeName,ratNodeValue,sizeof(ratNodeValue), "") != LE_OK )
        {
            LE_WARN("Node value string for '%s' too large.",ratNodeName);
            le_cfg_CancelTxn(ratCfg);
            return LE_NOT_POSSIBLE;
        }

        if ( strncmp(ratNodeName,"",sizeof(ratNodeName)) == 0 )
        {
            LE_WARN("No node value set for '%s'",ratNodeName);
            le_cfg_CancelTxn(ratCfg);
            return LE_NOT_POSSIBLE;
        }

        *ratMaskPtr |= ConvertRatValue(ratNodeValue);

        ++idx;
    } while (true);

    le_cfg_CancelTxn(ratCfg);

    return LE_OK;
}
Пример #6
0
//--------------------------------------------------------------------------------------------------
LE_SHARED le_result_t appCfg_GetProcExecName
(
    appCfg_Iter_t procIterRef,  ///< [IN] Apps iterator
    char* bufPtr,               ///< [OUT] Buffer to store the app name.
    size_t bufSize              ///< [IN] Size of the buffer.
)
{
    CheckFor(procIterRef, ITER_TYPE_PROC);

    if (le_cfg_NodeExists(procIterRef->cfgIter, "") == false)
    {
        return LE_NOT_FOUND;
    }

    return le_cfg_GetString(procIterRef->cfgIter, CFG_PROC_EXEC_NAME, bufPtr, bufSize, "");
}
Пример #7
0
//--------------------------------------------------------------------------------------------------
LE_SHARED le_result_t appCfg_GetVersion
(
    appCfg_Iter_t appIterRef,   ///< [IN] Apps iterator
    char* bufPtr,               ///< [OUT] Buffer to store the app version.
    size_t bufSize              ///< [IN] Size of the buffer.
)
{
    CheckFor(appIterRef, ITER_TYPE_APP);

    if (le_cfg_NodeExists(appIterRef->cfgIter, "") == false)
    {
        return LE_NOT_FOUND;
    }

    return le_cfg_GetString(appIterRef->cfgIter, CFG_APP_VERSION, bufPtr, bufSize, "");
}
Пример #8
0
//--------------------------------------------------------------------------------------------------
static le_result_t GetEnvironmentVariables
(
    proc_Ref_t procRef,     ///< [IN] The process to get the environment variables for.
    EnvVar_t envVars[],     ///< [IN] The list of environment variables.
    size_t maxNumEnvVars    ///< [IN] The maximum number of items envVars can hold.
)
{
    le_cfg_IteratorRef_t procCfg = le_cfg_CreateReadTxn(procRef->cfgPathRoot);
    le_cfg_GoToNode(procCfg, CFG_NODE_ENV_VARS);

    if (le_cfg_GoToFirstChild(procCfg) != LE_OK)
    {
        LE_WARN("No environment variables for process '%s'.", procRef->name);

        le_cfg_CancelTxn(procCfg);
        return LE_NOT_FOUND;
    }

    int i;
    for (i = 0; i < maxNumEnvVars; i++)
    {
        if ( (le_cfg_GetNodeName(procCfg, "", envVars[i].name, LIMIT_MAX_ENV_VAR_NAME_BYTES) != LE_OK) ||
             (le_cfg_GetString(procCfg, "", envVars[i].value, LIMIT_MAX_PATH_BYTES, "") != LE_OK) )
        {
            LE_ERROR("Error reading environment variables for process '%s'.", procRef->name);

            le_cfg_CancelTxn(procCfg);
            return LE_FAULT;
        }

        if (le_cfg_GoToNextSibling(procCfg) != LE_OK)
        {
            break;
        }
        else if (i >= maxNumEnvVars-1)
        {
            LE_ERROR("There were too many environment variables for process '%s'.", procRef->name);

            le_cfg_CancelTxn(procCfg);
            return LE_FAULT;
        }
    }

    le_cfg_CancelTxn(procCfg);
    return i + 1;
}
Пример #9
0
static void TestValue
(
    le_cfg_IteratorRef_t iterRef,
    const char* valueNamePtr,
    const char* expectedValue
)
{
    static char strBuffer[STR_SIZE] = { 0 };

    le_cfg_GetString(iterRef, valueNamePtr, strBuffer, STR_SIZE, "");
    LE_FATAL_IF(strncmp(strBuffer, expectedValue, STR_SIZE) != 0,
                "Test: %s - Expected '%s' but got '%s' instead.",
                TestRootDir,
                expectedValue,
                strBuffer);

}
Пример #10
0
// -------------------------------------------------------------------------------------------------
static int HandleGetUserFriendly
(
    const char* nodePathPtr  ///< Path to the node in the tree.
)
// -------------------------------------------------------------------------------------------------
{
    // Start a read transaction at the specified node path.  Then dump the value, (if any.)
    le_cfg_IteratorRef_t iterRef = le_cfg_CreateReadTxn(nodePathPtr);

    switch (le_cfg_GetNodeType(iterRef, ""))
    {
        case LE_CFG_TYPE_EMPTY:
            // Nothing to do here.
            break;

        case LE_CFG_TYPE_STEM:
            DumpTree(iterRef, 0);
            break;

        case LE_CFG_TYPE_BOOL:
            if (le_cfg_GetBool(iterRef, "", false))
            {
                printf("true\n");
            }
            else
            {
                printf("false\n");
            }
            break;

        default:
            {
                char nodeValue[LE_CFG_STR_LEN_BYTES] = "";

                le_cfg_GetString(iterRef, "", nodeValue, LE_CFG_STR_LEN_BYTES, "");
                printf("%s\n", nodeValue);
            }
            break;
    }

    le_cfg_CancelTxn(iterRef);

    return EXIT_SUCCESS;
}
Пример #11
0
static void DumpTree(le_cfg_IteratorRef_t iterRef, size_t indent)
{
    if (le_arg_NumArgs() == 1)
    {
        return;
    }

    static char strBuffer[STR_SIZE] = { 0 };

    do
    {
        size_t i;

        for (i = 0; i < indent; i++)
        {
            printf(" ");
        }

        le_cfg_GetNodeName(iterRef, "", strBuffer, STR_SIZE);
        le_cfg_nodeType_t type = le_cfg_GetNodeType(iterRef, "");

        switch (type)
        {
            case LE_CFG_TYPE_STEM:
                printf("%s/\n", strBuffer);

                le_cfg_GoToFirstChild(iterRef);
                DumpTree(iterRef, indent + 2);
                le_cfg_GoToParent(iterRef);
                break;

            case LE_CFG_TYPE_EMPTY:
                printf("%s~~\n", strBuffer);
                break;

            default:
                printf("%s<%s> == ", strBuffer, NodeTypeStr(iterRef));
                le_cfg_GetString(iterRef, "", strBuffer, STR_SIZE, "");
                printf("%s\n", strBuffer);
                break;
        }
    }
    while (le_cfg_GoToNextSibling(iterRef) == LE_OK);
}
Пример #12
0
//--------------------------------------------------------------------------------------------------
wdog_action_WatchdogAction_t proc_GetWatchdogAction
(
    proc_Ref_t procRef             ///< [IN] The process reference.
)
{
    // No actions are performed here. This just looks up the action for this process.
    // The result is passed back up to app to handle as with fault action.
    wdog_action_WatchdogAction_t watchdogAction = WATCHDOG_ACTION_NOT_FOUND;
    {

        if (procRef->paused)
        {
            return WATCHDOG_ACTION_HANDLED;
        };

        // Read the process's fault action from the config tree.
        le_cfg_IteratorRef_t procCfg = le_cfg_CreateReadTxn(procRef->cfgPathRoot);

        char watchdogActionStr[LIMIT_MAX_FAULT_ACTION_NAME_BYTES];
        le_result_t result = le_cfg_GetString(procCfg, wdog_action_GetConfigNode(),
                watchdogActionStr, sizeof(watchdogActionStr), "");

        le_cfg_CancelTxn(procCfg);

        // Set the watchdog action based on the fault action string.
        if (result == LE_OK)
        {
            LE_WARN("%s watchdogAction '%s' in proc section", procRef->name, watchdogActionStr);
            watchdogAction = wdog_action_EnumFromString(watchdogActionStr);
            if (WATCHDOG_ACTION_ERROR == watchdogAction)
            {
                LE_WARN("%s watchdogAction '%s' unknown", procRef->name, watchdogActionStr);
            }
        }
        else
        {
            LE_CRIT("Watchdog action string for process '%s' is too long.",
                    procRef->name);
            watchdogAction = WATCHDOG_ACTION_ERROR;
        }
    }

    return watchdogAction;
}
Пример #13
0
//--------------------------------------------------------------------------------------------------
static void ConfigureGdb
(
    void
)
{
    le_cfg_ConnectService();
    le_cfgAdmin_ConnectService();

    // Get a write iterator to the application node.
    le_cfg_IteratorRef_t cfgIter = le_cfg_CreateWriteTxn("/apps");
    le_cfg_GoToNode(cfgIter, AppName);

    // Check if this is a temporary configuration that was previously created by this or a similar
    // tool.
    if (!le_cfg_IsEmpty(cfgIter, CFG_DEBUG_TOOL))
    {
        char debugTool[LIMIT_MAX_PATH_BYTES];

        // Don't need to check return code because the value is just informative and does not matter
        // if it is truncated.
        le_cfg_GetString(cfgIter, CFG_DEBUG_TOOL, debugTool, sizeof(debugTool), "");

        fprintf(stderr, "This application has already been configured for %s debug mode.\n", debugTool);
        exit(EXIT_FAILURE);
    }

    // Write into the config's debug tool node to indicate that this configuration has been modified.
    le_cfg_SetString(cfgIter, CFG_DEBUG_TOOL, "gdb");

    // Add 512K to the maxFileSytemBytes so that we can debug this app in sandboxed mode
    uint32_t maxBytes;

    maxBytes = le_cfg_GetInt(cfgIter, "maxFileSystemBytes", DEFAULT_LIMIT_MAX_FILE_SYSTEM_BYTES);
    maxBytes += ADD_FILE_SYSTEM_BYTES;  // add an additional 512KBytes
    LE_INFO("Resetting maxFileSystemBytes to %d bytes", maxBytes);
    le_cfg_SetInt(cfgIter, "maxFileSystemBytes", maxBytes);

    // Add gdbserver and libs to the app's 'requires/files' section.
    le_cfg_GoToNode(cfgIter, "requires/files");
    AddImportFiles(cfgIter, &GdbFilesImports, NUM_ARRAY_MEMBERS(GdbFilesImports));

    // Add /proc to the app's dirs section.
    le_cfg_GoToParent(cfgIter);
    le_cfg_GoToNode(cfgIter, "dirs");
    AddImportFiles(cfgIter, &GdbDirsImports, NUM_ARRAY_MEMBERS(GdbDirsImports));

    // Delete the list of processes.
    le_cfg_GoToParent(cfgIter);
    le_cfg_GoToParent(cfgIter);
    int i;
    for (i = 0; i < NumProcs; i++)
    {
        char nodePath[LIMIT_MAX_PATH_BYTES];

        int n = snprintf(nodePath, sizeof(nodePath), "procs/%s", ProcNames[i]);

        INTERNAL_ERR_IF(n >= sizeof(nodePath), "Node name is too long.");
        INTERNAL_ERR_IF(n < 0, "Format error.  %m");

        le_cfg_DeleteNode(cfgIter, nodePath);
    }

    le_cfg_CommitTxn(cfgIter);
}
Пример #14
0
// -------------------------------------------------------------------------------------------------
static void DumpTree
(
    le_cfg_IteratorRef_t iterRef,  ///< Write out the tree pointed to by this iterator.
    size_t indent                  ///< The amount of indentation to use for this item.
)
// -------------------------------------------------------------------------------------------------
{
    // Note that because this is a recursive function, the buffer here is static in order to save on
    // stack space.  The implication here is that we then have to be careful how it is later
    // accessed.  Also, this makes the function not thread safe.  But this trade off was made as
    // this was not intended to be a multi-threaded program.
    static char strBuffer[LE_CFG_STR_LEN_BYTES] = "";

    do
    {
        // Quick and dirty way to indent the tree item.
        size_t i;

        for (i = 0; i < indent; i++)
        {
            printf(" ");
        }

        // Simply grab the name and the type of the current node.
        le_cfg_GetNodeName(iterRef, "", strBuffer, LE_CFG_STR_LEN_BYTES);
        le_cfg_nodeType_t type = le_cfg_GetNodeType(iterRef, "");

        switch (type)
        {
            // It's a stem object, so mark this item as being a stem and recurse into the stem's
            // sub-items.
            case LE_CFG_TYPE_STEM:
                printf("%s/\n", strBuffer);

                le_cfg_GoToFirstChild(iterRef);
                DumpTree(iterRef, indent + 2);
                le_cfg_GoToParent(iterRef);

                // If we got back up to where we started then don't iterate the "root" node's
                // siblings.
                if (indent == 0)
                {
                    return;
                }
                break;

            // The node is empty, so simply mark it as such.
            case LE_CFG_TYPE_EMPTY:
                printf("%s<empty>\n", strBuffer);
                break;

            case LE_CFG_TYPE_BOOL:
                {
                    char* value = NULL;

                    if (le_cfg_GetBool(iterRef, "", false))
                    {
                        value = "true";
                    }
                    else
                    {
                        value = "false";
                    }

                    printf("%s<bool> == %s\n", strBuffer, value);
                }
                break;

            // The node has a different type.  So write out the name and the type.  Then print the
            // value.
            default:
                printf("%s<%s> == ", strBuffer, NodeTypeStr(le_cfg_GetNodeType(iterRef, "")));
                le_cfg_GetString(iterRef, "", strBuffer, LE_CFG_STR_LEN_BYTES, "");
                printf("%s\n", strBuffer);
                break;
        }
    }
    while (le_cfg_GoToNextSibling(iterRef) == LE_OK);
}
Пример #15
0
//--------------------------------------------------------------------------------------------------
static proc_FaultAction_t GetFaultAction
(
    proc_Ref_t procRef              ///< [IN] The process reference.
)
{
    if (procRef->cmdKill)
    {
        // The cmdKill flag was set which means the process died because we killed it so
        // it was not a fault.  Reset the cmdKill flag so that if this process is restarted
        // faults will still be caught.
        procRef->cmdKill = false;

        return PROC_FAULT_ACTION_NO_FAULT;
    }

    // Record the fault time.
    procRef->faultTime = (le_clk_GetAbsoluteTime()).sec;

    // Read the process's fault action from the config tree.
    le_cfg_IteratorRef_t procCfg = le_cfg_CreateReadTxn(procRef->cfgPathRoot);

    char faultActionStr[LIMIT_MAX_FAULT_ACTION_NAME_BYTES];
    le_result_t result = le_cfg_GetString(procCfg, CFG_NODE_FAULT_ACTION,
                                          faultActionStr, sizeof(faultActionStr), "");

    le_cfg_CancelTxn(procCfg);

    // Set the fault action based on the fault action string.
    if (result != LE_OK)
    {
        LE_CRIT("Fault action string for process '%s' is too long.  Assume fault action is 'ignore'.",
                procRef->name);
        return PROC_FAULT_ACTION_IGNORE;
    }

    if (strcmp(faultActionStr, RESTART_STR) == 0)
    {
        return PROC_FAULT_ACTION_RESTART;
    }

    if (strcmp(faultActionStr, RESTART_APP_STR) == 0)
    {
        return PROC_FAULT_ACTION_RESTART_APP;
    }

    if (strcmp(faultActionStr, STOP_APP_STR) == 0)
    {
        return PROC_FAULT_ACTION_STOP_APP;
    }

    if (strcmp(faultActionStr, REBOOT_STR) == 0)
    {
        return PROC_FAULT_ACTION_REBOOT;
    }

    if (strcmp(faultActionStr, IGNORE_STR) == 0)
    {
        return PROC_FAULT_ACTION_IGNORE;
    }

    LE_WARN("Unrecognized fault action for process '%s'.  Assume fault action is 'ignore'.",
            procRef->name);
    return PROC_FAULT_ACTION_IGNORE;
}
Пример #16
0
//--------------------------------------------------------------------------------------------------
le_result_t le_cellnet_GetSimPinCode
(
    le_sim_Id_t simId,
        ///< [IN]
        ///< SIM identifier.

    char* pinCodePtr,
        ///< [OUT]
        ///< Read the PIN code from the config tree.

    size_t pinCodeNumElements
        ///< [IN]

)
{
    le_result_t result=LE_OK;

    LE_DEBUG("simId= %d",simId);

    if (simId >= LE_SIM_ID_MAX)
    {
        LE_ERROR("Invalid simId (%d) provided!", simId);
        result = LE_OUT_OF_RANGE;
    }
    else
    {
        // Set the configuration path for the SIM.
        char configPath[LIMIT_MAX_PATH_BYTES];
        char simPin[LE_SIM_PIN_MAX_BYTES] = {0};
        le_cfg_IteratorRef_t simCfgRef;

        snprintf(configPath,
                 sizeof(configPath),
                 "%s/%d",
                 CFG_MODEMSERVICE_SIM_PATH, simId);

        // Check that the app has a configuration value.
        simCfgRef = le_cfg_CreateReadTxn(configPath);

        // test if the node exists
        if (!le_cfg_NodeExists(simCfgRef, CFG_NODE_PIN))
        {
            LE_ERROR("SIM PIN node isn't found in the config tree");
            result = LE_NOT_FOUND;
        }
        else
        {
            //read config tree
            result = le_cfg_GetString(simCfgRef,CFG_NODE_PIN,simPin,sizeof(simPin),"");
            if (result != LE_OK)
            {
                LE_ERROR("retrieved SIM PIN code exceeds the supplied buffer");
                result = LE_OVERFLOW;
            }
            else
            {
                 //void entry is taken into account
                 if ((strncmp(simPin,"",LE_SIM_PIN_MAX_LEN)!=0) &&
                     (strlen(simPin) < LE_SIM_PIN_MIN_LEN))
                {
                    LE_ERROR("retrieved SIM PIN code is not long enough (min 4 digits) ");
                    result = LE_UNDERFLOW;
                }
                else
                {
                    //copy pincode
                    strncpy ( pinCodePtr, simPin, sizeof(simPin) );
                    LE_DEBUG("SIM PIN code= %s retrieved OK",pinCodePtr);
                }
            }
        }
        le_cfg_CancelTxn(simCfgRef);
    }
    return result;
}
Пример #17
0
static void StringSizeTest()
{
    le_result_t result;

    static char pathBuffer[STR_SIZE] = { 0 };
    static char parentPathBuffer[STR_SIZE] = { 0 };

    static char smallPathBuffer[SMALL_STR_SIZE + 1] = { 0 };
    static char smallParentPathBuffer[SMALL_STR_SIZE + 1] = { 0 };

    snprintf(pathBuffer, STR_SIZE, "%s/stringSizeTest/strVal", TestRootDir);
    snprintf(parentPathBuffer, STR_SIZE, "%s/stringSizeTest/", TestRootDir);

    strncpy(smallPathBuffer, pathBuffer, SMALL_STR_SIZE);
    strncpy(smallParentPathBuffer, parentPathBuffer, SMALL_STR_SIZE);


    le_cfg_QuickSetString(pathBuffer, "This is a bigger string than may be usual for this test.");


    static char buffer[STR_SIZE];

    le_cfg_IteratorRef_t iterRef = le_cfg_CreateReadTxn(pathBuffer);


    result = le_cfg_GetPath(iterRef, "", buffer, SMALL_STR_SIZE);
    LE_FATAL_IF(result != LE_OVERFLOW,
                "Test: %s - The buffer should have been too small.",
                TestRootDir);
    LE_FATAL_IF(strcmp(buffer, smallPathBuffer) == 0,
                "Test: %s - Unexpected value returned, %s",
                TestRootDir,
                buffer);

    result = le_cfg_GetString(iterRef, "", buffer, SMALL_STR_SIZE, "");
    LE_FATAL_IF(result != LE_OVERFLOW,
                "Test: %s - The buffer should have been too small.",
                TestRootDir);
    LE_FATAL_IF(strcmp(buffer, "This ") == 0,
                "Test: %s - Unexpected value returned, %s",
                TestRootDir,
                buffer);


    result = le_cfg_GetPath(iterRef, "", buffer, STR_SIZE);
    LE_FATAL_IF(result != LE_OK,
                "Test: %s - The buffer should have been big enough.",
                TestRootDir);
    LE_FATAL_IF(strcmp(buffer, pathBuffer) != 0,
                "Test: %s - Unexpected value returned, %s",
                TestRootDir,
                buffer);

    result = le_cfg_GetString(iterRef, "", buffer, STR_SIZE, "");
    LE_FATAL_IF(result != LE_OK, "Test: %s - The buffer should have been big enough.", TestRootDir);
    LE_FATAL_IF(strcmp(buffer, "This is a bigger string than may be usual for this test.") != 0,
                "Test: %s - Unexpected value returned, %s",
                TestRootDir,
                buffer);


    le_cfg_CancelTxn(iterRef);


    result = le_cfg_QuickGetString(pathBuffer, buffer, SMALL_STR_SIZE, "");
    LE_FATAL_IF(result != LE_OVERFLOW,
                "Test: %s - The buffer should have been too small.",
                TestRootDir);
    LE_FATAL_IF(strcmp(buffer, "This ") == 0,
                "Test: %s - Unexpected value returned, %s",
                TestRootDir,
                buffer);

    result = le_cfg_QuickGetString(pathBuffer, buffer, STR_SIZE, "");
    LE_FATAL_IF(result != LE_OK,
                "Test: %s - The buffer should have been big enough.",
                TestRootDir);
    LE_FATAL_IF(strcmp(buffer, "This is a bigger string than may be usual for this test.") != 0,
                "Test: %s - Unexpected value returned, %s",
                TestRootDir,
                buffer);
}
Пример #18
0
//--------------------------------------------------------------------------------------------------
static le_result_t GetServerUid
(
    le_cfg_IteratorRef_t    i,  ///< [in] Config tree iterator positioned at binding config.
    uid_t*  uidPtr              ///< [out] The application's user ID.
)
//--------------------------------------------------------------------------------------------------
{
    le_result_t result;

    char userName[LIMIT_MAX_USER_NAME_BYTES];

    // If an app name is present in the binding config,
    if (le_cfg_NodeExists(i, "app"))
    {
        // Make sure there isn't also a user name.
        if (le_cfg_NodeExists(i, "user"))
        {
            char path[LIMIT_MAX_PATH_BYTES];
            le_cfg_GetPath(i, "", path, sizeof(path));
            LE_CRIT("Both server user and app nodes appear under binding (@ %s)", path);
            return LE_DUPLICATE;
        }

        // Get the app name.
        char appName[LIMIT_MAX_APP_NAME_BYTES];
        result = le_cfg_GetString(i, "app", appName, sizeof(appName), "");
        if (result != LE_OK)
        {
            char path[LIMIT_MAX_PATH_BYTES];
            le_cfg_GetPath(i, "app", path, sizeof(path));
            LE_CRIT("Server app name too big (@ %s)", path);
            return result;
        }
        if (appName[0] == '\0')
        {
            char path[LIMIT_MAX_PATH_BYTES];
            le_cfg_GetPath(i, "app", path, sizeof(path));
            LE_CRIT("Server app name empty (@ %s)", path);
            return LE_NOT_FOUND;
        }

        // Find out if the server app is sandboxed.  If not, it runs as root.
        char path[LIMIT_MAX_PATH_BYTES];
        if (snprintf(path, sizeof(path), "/apps/%s/sandboxed", appName) >= sizeof(path))
        {
            LE_CRIT("Config node path too long (app name '%s').", appName);
            return LE_OVERFLOW;
        }
        if (!le_cfg_GetBool(i, path, true))
        {
            *uidPtr = 0;

            return LE_OK;
        }

        // It is not sandboxed.  Convert the app name into a user name.
        result = user_AppNameToUserName(appName, userName, sizeof(userName));
        if (result != LE_OK)
        {
            LE_CRIT("Failed to convert app name '%s' into a user name.", appName);

            return result;
        }
    }
    // If a server app name is not present in the binding config,
    else
    {
        // Get the server user name instead.
        result = le_cfg_GetString(i, "user", userName, sizeof(userName), "");
        if (result != LE_OK)
        {
            char path[LIMIT_MAX_PATH_BYTES];

            le_cfg_GetPath(i, "user", path, sizeof(path));
            LE_CRIT("Server user name too big (@ %s)", path);

            return result;
        }
        if (userName[0] == '\0')
        {
            char path[LIMIT_MAX_PATH_BYTES];

            le_cfg_GetPath(i, "", path, sizeof(path));
            LE_CRIT("Server user name or app name missing (@ %s)", path);

            return LE_NOT_FOUND;
        }
    }

    // Convert the server's user name into a user ID.
    result = user_GetUid(userName, uidPtr);
    if (result != LE_OK)
    {
        // Note: This can happen if the server application isn't installed yet.
        //       When the server application is installed, sdir load will be run
        //       again and the bindings will be correctly set up at that time.
        if (strncmp(userName, "app", 3) == 0)
        {
            LE_DEBUG("Couldn't get UID for application '%s'.  Perhaps it is not installed yet?",
                     userName + 3);
        }
        else
        {
            char path[LIMIT_MAX_PATH_BYTES];
            le_cfg_GetPath(i, "", path, sizeof(path));
            LE_CRIT("Couldn't convert server user name '%s' to UID (%s @ %s)",
                    userName,
                    LE_RESULT_TXT(result),
                    path);
        }

        return result;
    }

    return LE_OK;
}
Пример #19
0
//--------------------------------------------------------------------------------------------------
static void LoadPreferredList
(
)
{
    uint32_t idx = 0;
    le_dls_List_t preferredNetworkList = LE_DLS_LIST_INIT;

    // Check that the modemRadioControl has a configuration value for preferred list.
    le_cfg_IteratorRef_t mrcCfg = le_cfg_CreateReadTxn(CFG_MODEMSERVICE_MRC_PATH"/"CFG_NODE_PREFERREDLIST);

    if (le_cfg_NodeExists(mrcCfg,"") == false)
    {
        LE_DEBUG("'%s' does not exist. Stop reading configuration",
                    CFG_MODEMSERVICE_MRC_PATH"/"CFG_NODE_PREFERREDLIST);
        le_cfg_CancelTxn(mrcCfg);
        return;
    }

    // Read all network from configDB
    do
    {
        uint32_t ratMask;
        char mccNodePath[LIMIT_MAX_PATH_BYTES] = {0};
        char mncNodePath[LIMIT_MAX_PATH_BYTES] = {0};
        char ratNodePath[LIMIT_MAX_PATH_BYTES] = {0};
        char mccStr[LIMIT_MAX_PATH_BYTES] = {0};
        char mncStr[LIMIT_MAX_PATH_BYTES] = {0};

        // Get the node name.
        char nodeName[LIMIT_MAX_PATH_BYTES] = {0};

        sprintf(nodeName,PATTERN_NETWORK"%d",idx);

        if (le_cfg_IsEmpty(mrcCfg, nodeName))
        {
            LE_DEBUG("'%s' does not exist. stop reading configuration", nodeName);
            break;
        }

        snprintf(mccNodePath, sizeof(mccNodePath), "%s/%s",nodeName,CFG_NODE_MCC);
        snprintf(mncNodePath, sizeof(mncNodePath), "%s/%s",nodeName,CFG_NODE_MNC);
        snprintf(ratNodePath, sizeof(ratNodePath),
                 CFG_MODEMSERVICE_MRC_PATH"/"CFG_NODE_PREFERREDLIST"/%s/%s",nodeName,CFG_NODE_RAT);

        if ( le_cfg_GetString(mrcCfg,mccNodePath,mccStr,sizeof(mccStr),"") != LE_OK )
        {
            LE_WARN("String value for '%s' too large.",mccNodePath);
            break;
        }

        if ( strcmp(mccStr,"") == 0 )
        {
            LE_WARN("No node value set for '%s'",mccNodePath);
            break;
        }

        if ( le_cfg_GetString(mrcCfg,mncNodePath,mncStr,sizeof(mncStr),"") != LE_OK )
        {
            LE_WARN("String value for '%s' too large.",mncNodePath);
            break;
        }

        if ( strcmp(mncStr,"") == 0 )
        {
            LE_WARN("No node value set for '%s'",mncNodePath);
            break;
        }

        if ( LoadRatList(ratNodePath,&ratMask) != LE_OK )
        {
            LE_WARN("Could not read rat information in '%s'",ratNodePath);
            break;
        }

        if ( pa_mrc_AddPreferredNetwork(&preferredNetworkList,mccStr,mncStr,ratMask) != LE_OK )
        {
            LE_WARN("Could not add [%s,%s] into the preferred list",mccStr,mncStr);
        }

        ++idx;
    }
    while (true);

    le_cfg_CancelTxn(mrcCfg);

    if ( pa_mrc_SavePreferredList(&preferredNetworkList) != LE_OK )
    {
        LE_WARN("Could not save the preferred list");
    }
    pa_mrc_ClearPreferedList(&preferredNetworkList);
}
Пример #20
0
//--------------------------------------------------------------------------------------------------
le_result_t proc_SetPriority
(
    const char* priorStr,   ///< [IN] Priority level string.
    pid_t pid               ///< [IN] PID of the process to set the priority for.
)
{
    // Declare these varialbes with the default values.
    struct sched_param priority = {.sched_priority = 0};
    int policy = SCHED_OTHER;
    int niceLevel = MEDIUM_PRIORITY_NICE_LEVEL;

    if (strcmp(priorStr, "idle") == 0)
    {
         policy = SCHED_IDLE;
    }
    else if (strcmp(priorStr, "low") == 0)
    {
        niceLevel = LOW_PRIORITY_NICE_LEVEL;
    }
    else if (strcmp(priorStr, "high") == 0)
    {
        niceLevel = HIGH_PRIORITY_NICE_LEVEL;
    }
    else if ( (priorStr[0] == 'r') && (priorStr[1] == 't') )
    {
        // Get the realtime level from the characters following "rt".
        char *endPtr;
        errno = 0;
        int level = strtol(&(priorStr[2]), &endPtr, 10);

        if ( (*endPtr != '\0') || (level < MIN_RT_PRIORITY) ||
             (level > MAX_RT_PRIORITY) )
        {
            LE_WARN("Unrecognized priority level (%s) for process '%d'.  Using default priority.",
                    priorStr, pid);
        }
        else
        {
            policy = SCHED_RR;
            priority.sched_priority = level;
        }
    }
    else if (strcmp(priorStr, "medium") != 0)
    {
        LE_WARN("Unrecognized priority level for process '%d'.  Using default priority.", pid);
    }

    // Set the policy and priority.
    if (sched_setscheduler(pid, policy, &priority) == -1)
    {
        LE_ERROR("Could not set the scheduling policy.  %m.");
        return LE_FAULT;
    }

    // Set the nice level.
    errno = 0;
    if (setpriority(PRIO_PROCESS, pid, niceLevel) == -1)
    {
        LE_ERROR("Could not set the nice level.  %m.");
        return LE_FAULT;
    }

    return LE_OK;
}


//--------------------------------------------------------------------------------------------------
/**
 * Sets the scheduling policy, priority and/or nice level for the specified process based on the
 * process' configuration settings in the config tree.
 *
 * @note This function kills the specified process if there is an error.
 */
//--------------------------------------------------------------------------------------------------
static void SetSchedulingPriority
(
    proc_Ref_t procRef      ///< [IN] The process to set the priority for.
)
{
    // Read the priority setting from the config tree.
    le_cfg_IteratorRef_t procCfg = le_cfg_CreateReadTxn(procRef->cfgPathRoot);

    char priorStr[LIMIT_MAX_PRIORITY_NAME_BYTES];

    if (le_cfg_GetString(procCfg, CFG_NODE_PRIORITY, priorStr, sizeof(priorStr), "medium") != LE_OK)
    {
        LE_CRIT("Priority string for process %s is too long.  Using default priority.", procRef->name);

        LE_ASSERT(le_utf8_Copy(priorStr, "medium", sizeof(priorStr), NULL) == LE_OK);
    }

    le_cfg_CancelTxn(procCfg);

    if (proc_SetPriority(priorStr, procRef->pid) != LE_OK)
    {
        kill_Hard(procRef->pid);
    }
}
Пример #21
0
//--------------------------------------------------------------------------------------------------
static void LoadScanMode
(
)
{
    char configPath[LIMIT_MAX_PATH_BYTES];
    snprintf(configPath, sizeof(configPath), "%s/%s",CFG_MODEMSERVICE_MRC_PATH,CFG_NODE_SCANMODE);

    LE_DEBUG("Start reading MRC scanMode information in ConfigDB");

    le_cfg_IteratorRef_t mrcCfg = le_cfg_CreateReadTxn(configPath);

    do
    {
        if ( le_cfg_GetBool(mrcCfg,CFG_NODE_MANUAL,false) )
        {

            char mccStr[LIMIT_MAX_PATH_BYTES] = {0};
            char mncStr[LIMIT_MAX_PATH_BYTES] = {0};

            if ( le_cfg_GetString(mrcCfg,CFG_NODE_MCC,mccStr,sizeof(mccStr),"") != LE_OK )
            {
                LE_WARN("String value for '%s' too large.",CFG_NODE_MCC);
                break;
            }

            if ( strcmp(mccStr,"") == 0 )
            {
                LE_WARN("No node value set for '%s'",CFG_NODE_MCC);
                break;
            }

            if ( le_cfg_GetString(mrcCfg,CFG_NODE_MNC,mncStr,sizeof(mncStr),"") != LE_OK )
            {
                LE_WARN("String value for '%s' too large.",CFG_NODE_MNC);
                break;
            }

            if ( strcmp(mncStr,"") == 0 )
            {
                LE_WARN("No node value set for '%s'",CFG_NODE_MNC);
                break;
            }

            if ( le_mrc_ConnectCellularNetwork(mccStr,mncStr) != LE_OK )
            {
                LE_WARN("Could not connect to Network [%s,%s]",mccStr ,mncStr);
                break;
            }
        }
        else
        {
            if ( pa_mrc_SetAutomaticNetworkRegistration() != LE_OK )
            {
                LE_WARN("Could not set the Automatic Network Registration");
                break;
            }
        }

    } while (false);

    le_cfg_CancelTxn(mrcCfg);
}
Пример #22
0
//--------------------------------------------------------------------------------------------------
static le_result_t GetArgs
(
    proc_Ref_t procRef,             ///< [IN] The process to get the args for.
    char argsBuffers[LIMIT_MAX_NUM_CMD_LINE_ARGS][LIMIT_MAX_ARGS_STR_BYTES], ///< [OUT] A pointer to
                                                                             /// an array of buffers
                                                                             /// used to store
                                                                             /// arguments.
    char* argsPtr[NUM_ARGS_PTRS]    ///< [OUT] An array of pointers that will point to the valid
                                    ///       arguments list.  The list is terminated by NULL.
)
{
    // Get a config iterator to the arguments list.
    le_cfg_IteratorRef_t procCfg = le_cfg_CreateReadTxn(procRef->cfgPathRoot);
    le_cfg_GoToNode(procCfg, CFG_NODE_ARGS);

    if (le_cfg_GoToFirstChild(procCfg) != LE_OK)
    {
        LE_ERROR("No arguments for process '%s'.", procRef->name);
        le_cfg_CancelTxn(procCfg);
        return LE_FAULT;
    }

    size_t ptrIndex = 0;
    size_t bufIndex = 0;

    // Record the executable path.
    if (le_cfg_GetString(procCfg, "", argsBuffers[bufIndex], LIMIT_MAX_ARGS_STR_BYTES, "") != LE_OK)
    {
        LE_ERROR("Error reading argument '%s...' for process '%s'.",
                 argsBuffers[bufIndex],
                 procRef->name);

        le_cfg_CancelTxn(procCfg);
        return LE_FAULT;
    }

    argsPtr[ptrIndex++] = argsBuffers[bufIndex++];

    // Record the process name in the list.
    argsPtr[ptrIndex++] = procRef->name;

    // Record the arguments in the caller's list of buffers.
    while(1)
    {
        if (le_cfg_GoToNextSibling(procCfg) != LE_OK)
        {
            // Terminate the list.
            argsPtr[ptrIndex] = NULL;
            break;
        }
        else if (bufIndex >= LIMIT_MAX_NUM_CMD_LINE_ARGS)
        {
            LE_ERROR("Too many arguments for process '%s'.", procRef->name);
            le_cfg_CancelTxn(procCfg);
            return LE_FAULT;
        }

        if (le_cfg_IsEmpty(procCfg, ""))
        {
            LE_ERROR("Empty node in argument list for process '%s'.", procRef->name);

            le_cfg_CancelTxn(procCfg);
            return LE_FAULT;
        }

        if (le_cfg_GetString(procCfg, "", argsBuffers[bufIndex],
                             LIMIT_MAX_ARGS_STR_BYTES, "") != LE_OK)
        {
            LE_ERROR("Argument too long '%s...' for process '%s'.",
                     argsBuffers[bufIndex],
                     procRef->name);

            le_cfg_CancelTxn(procCfg);
            return LE_FAULT;
        }

        // Point to the string.
        argsPtr[ptrIndex++] = argsBuffers[bufIndex++];
    }

    le_cfg_CancelTxn(procCfg);

    return LE_OK;
}
Пример #23
0
//--------------------------------------------------------------------------------------------------
static void SendBindRequest
(
    uid_t uid,                  ///< [in] Unix user ID of the client whose binding is being created.
    le_cfg_IteratorRef_t i      ///< [in] Configuration read iterator.
)
//--------------------------------------------------------------------------------------------------
{
    le_result_t result;

    le_msg_MessageRef_t msgRef = le_msg_CreateMsg(SessionRef);
    le_sdtp_Msg_t* msgPtr = le_msg_GetPayloadPtr(msgRef);

    msgPtr->msgType = LE_SDTP_MSGID_BIND;
    msgPtr->client = uid;

    // Fetch the client's service name.
    result = le_cfg_GetNodeName(i,
                                "",
                                msgPtr->clientServiceName,
                                sizeof(msgPtr->clientServiceName));
    if (result != LE_OK)
    {
        char path[LIMIT_MAX_PATH_BYTES];
        le_cfg_GetPath(i, "", path, sizeof(path));
        LE_CRIT("Configured client service name too long (@ %s)", path);
        return;
    }

    // Fetch the server's user ID.
    result = GetServerUid(i, &msgPtr->server);
    if (result != LE_OK)
    {
        return;
    }

    // Fetch the server's service name.
    result = le_cfg_GetString(i,
                              "interface",
                              msgPtr->serverServiceName,
                              sizeof(msgPtr->serverServiceName),
                              "");
    if (result != LE_OK)
    {
        char path[LIMIT_MAX_PATH_BYTES];
        le_cfg_GetPath(i, "interface", path, sizeof(path));
        LE_CRIT("Server interface name too big (@ %s)", path);
        return;
    }
    if (msgPtr->serverServiceName[0] == '\0')
    {
        char path[LIMIT_MAX_PATH_BYTES];
        le_cfg_GetPath(i, "interface", path, sizeof(path));
        LE_CRIT("Server interface name missing (@ %s)", path);
        return;
    }

    msgRef = le_msg_RequestSyncResponse(msgRef);

    if (msgRef == NULL)
    {
        ExitWithErrorMsg("Communication with Service Directory failed.");
    }

    le_msg_ReleaseMsg(msgRef);
}
Пример #24
0
//--------------------------------------------------------------------------------------------------
static void LoadSimFromConfigDb
(
    le_sim_Id_t simId
)
{
    uint32_t attemptCounter = CONFIGDB_ATTEMPT_MAX;
    // Get the configuration path for the SIM.
    char configPath[LIMIT_MAX_PATH_BYTES];
    snprintf(configPath, sizeof(configPath), "%s/%d",
             CFG_MODEMSERVICE_SIM_PATH,
             simId);

    LE_DEBUG("Start reading SIM-%d information in ConfigDB",simId);

    le_result_t result;
    le_sim_States_t simState;

    do
    {
        simState = le_sim_GetState(simId);

        switch (simState)
        {
            case LE_SIM_INSERTED:
            {
                // Check that the app has a configuration value.
                le_cfg_IteratorRef_t simCfg = le_cfg_CreateReadTxn(configPath);

                char simPin[LIMIT_MAX_PATH_BYTES] = {0};

                result = le_cfg_GetString(simCfg,CFG_NODE_PIN,simPin,sizeof(simPin),"");
                if ( result != LE_OK )
                {
                    LE_WARN("PIN string too large for SIM-%d",simId);
                    le_cfg_CancelTxn(simCfg);
                    return;
                }
                if ( strncmp(simPin,"",sizeof(simPin))==0 )
                {
                    LE_WARN("PIN not set for SIM-%d",simId);
                    le_cfg_CancelTxn(simCfg);
                    return;
                }
                if ( (result = le_sim_EnterPIN(simId,simPin)) != LE_OK )
                {
                    LE_ERROR("Error.%d Failed to enter SIM pin for SIM-%d",result,simId);
                    le_cfg_CancelTxn(simCfg);
                    return;
                }
                LE_DEBUG("Sim-%d is unlocked", simId);

                le_cfg_CancelTxn(simCfg);
                attemptCounter = 1;
                break;
            }
            case LE_SIM_BLOCKED:
            {
                LE_EMERG("Be carefull the sim-%d is BLOCKED, need to enter PUK code",simId);
                attemptCounter = 1;
                break;
            }
            case LE_SIM_BUSY:
                if (attemptCounter==1)
                {
                    LE_WARN("Could not load the configuration because "
                            "the SIM is still busy after %d attempts", CONFIGDB_ATTEMPT_MAX);
                }
                else
                {
                    LE_WARN("Sim-%d was busy when loading configuration,"
                            "retry in 1 seconds",simId);
                }
                sleep(1); // Retry in 1 second.
                break;
            case LE_SIM_READY:
                LE_DEBUG("Sim-%d is ready",simId);
                attemptCounter = 1;
                break;
            case LE_SIM_ABSENT:
                LE_WARN("Sim-%d is absent",simId);
                attemptCounter = 1;
                break;
            case LE_SIM_STATE_UNKNOWN:
                break;
        }
    } while (--attemptCounter);

    LE_DEBUG("Load SIM information is done");
}