//-------------------------------------------------------------------------------------------------- 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; }
//-------------------------------------------------------------------------------------------------- void userAddRemove_Add ( const char* appName ) //-------------------------------------------------------------------------------------------------- { le_result_t result; uid_t uid; gid_t gid; char userName[256] = "app"; result = le_utf8_Append(userName, appName, sizeof(userName), NULL); LE_FATAL_IF(result != LE_OK, "App name '%s' is too long.", appName); LE_INFO("Creating user '%s' for application '%s'.", userName, appName); // Start a read transaction and go to node /apps/app-name le_cfg_ConnectService(); le_cfg_IteratorRef_t i = le_cfg_CreateReadTxn("/apps"); le_cfg_GoToNode(i, appName); // If the node doesn't exist, bail out. if (!le_cfg_NodeExists(i, "")) { fprintf(stderr, "** ERROR: App '%s' doesn't exist in the system configuration.\n", appName); } else { result = user_Create(userName, &uid, &gid); if (result == LE_OK) { printf("Created user '%s' (uid %u, gid %u).\n", userName, uid, gid); // TODO: Groups configuration. le_cfg_CancelTxn(i); exit(EXIT_SUCCESS); } else if (result == LE_DUPLICATE) { // TODO: Verify correct groups configuration. printf("User '%s' already exists (uid %u, gid %u).\n", userName, uid, gid); le_cfg_CancelTxn(i); exit(EXIT_SUCCESS); } else { fprintf(stderr, "** ERROR: user_Create() failed for user '%s'.\n", userName); } } le_cfg_CancelTxn(i); exit(EXIT_FAILURE); }
// ------------------------------------------------------------------------------------------------- static int HandleExport ( void ) // ------------------------------------------------------------------------------------------------- { le_result_t result; // Check required format. if (UseJson) { result = HandleGetJSON(NodePath, FilePath); } else { le_cfg_IteratorRef_t iterRef = le_cfg_CreateReadTxn(NodePath); result = le_cfgAdmin_ExportTree(iterRef, FilePath, ""); le_cfg_CancelTxn(iterRef); } if (result != LE_OK) { ReportImportExportFail(result, "Export", NodePath, FilePath); return EXIT_FAILURE; } return EXIT_SUCCESS; }
//-------------------------------------------------------------------------------------------------- rlim_t resLim_GetSandboxedAppTmpfsLimit ( app_Ref_t appRef ///< [IN] The application to set resource limits for. ) { // Create a config iterator to get the file system limit from the config tree. le_cfg_IteratorRef_t appCfg = le_cfg_CreateReadTxn(app_GetConfigPath(appRef)); // Get the resource limit from the config tree. int fileSysLimit = GetCfgResourceLimit(appCfg, CFG_NODE_LIMIT_MAX_FILE_SYSTEM_BYTES, DEFAULT_LIMIT_MAX_FILE_SYSTEM_BYTES); if (fileSysLimit == 0) { // Zero means unlimited for tmpfs mounts and is not allowed. Use the default limit. LE_ERROR("Configured resource limit %s is zero, which is invalid. Assuming the default value %d.", CFG_NODE_LIMIT_MAX_FILE_SYSTEM_BYTES, DEFAULT_LIMIT_MAX_FILE_SYSTEM_BYTES); fileSysLimit = DEFAULT_LIMIT_MAX_FILE_SYSTEM_BYTES; } le_cfg_CancelTxn(appCfg); return (rlim_t)fileSysLimit; }
//-------------------------------------------------------------------------------------------------- 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); }
//-------------------------------------------------------------------------------------------------- static int GetRebootCount ( void ) { le_cfg_IteratorRef_t iterRef = le_cfg_CreateReadTxn(BOOT_COUNT_CFG); int bootCount = le_cfg_GetInt(iterRef, BOOT_COUNT_CFG_VAR, -1); le_cfg_CancelTxn(iterRef); return bootCount; }
//-------------------------------------------------------------------------------------------------- LE_SHARED appCfg_Iter_t appCfg_CreateAppsIter ( void ) { AppsIter_t* iterPtr = le_mem_ForceAlloc(AppIterPool); iterPtr->type = ITER_TYPE_APP; iterPtr->cfgIter = le_cfg_CreateReadTxn(CFG_APPS_LIST); iterPtr->atFirst = true; return iterPtr; }
//-------------------------------------------------------------------------------------------------- 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; }
static void ClearTree() { LE_INFO("---- Clearing Out Current Tree -----------------------------------------------------"); le_cfg_IteratorRef_t iterRef = le_cfg_CreateWriteTxn(TestRootDir); LE_FATAL_IF(iterRef == NULL, "Test: %s - Could not create iterator.", TestRootDir); DumpTree(iterRef, 0); le_cfg_DeleteNode(iterRef, ""); le_cfg_CommitTxn(iterRef); iterRef = le_cfg_CreateReadTxn(TestRootDir); DumpTree(iterRef, 0); le_cfg_CancelTxn(iterRef); }
//-------------------------------------------------------------------------------------------------- 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; }
//-------------------------------------------------------------------------------------------------- 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; }
// ------------------------------------------------------------------------------------------------- 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; }
//-------------------------------------------------------------------------------------------------- LE_SHARED appCfg_Iter_t appCfg_CreateAppProcIter ( appCfg_Iter_t appIterRef ///< [IN] Apps iterator ) { CheckFor(appIterRef, ITER_TYPE_APP); char pathStr[LE_CFG_STR_LEN_BYTES] = ""; le_cfg_GetPath(appIterRef->cfgIter, "", pathStr, sizeof(pathStr)); AppsIter_t* iterPtr = le_mem_ForceAlloc(AppIterPool); iterPtr->type = ITER_TYPE_PROC; iterPtr->cfgIter = le_cfg_CreateReadTxn(pathStr); le_cfg_GoToNode(iterPtr->cfgIter, CFG_PROCS_LIST); iterPtr->atFirst = true; return iterPtr; }
static void DeleteTest() { static char pathBuffer[STR_SIZE] = { 0 }; snprintf(pathBuffer, STR_SIZE, "%s/deleteTest/", TestRootDir); le_cfg_IteratorRef_t iterRef = le_cfg_CreateWriteTxn(pathBuffer); le_cfg_SetString(iterRef, "valueA", "aNewValue"); le_cfg_SetString(iterRef, "valueB", "aNewValue"); le_cfg_SetString(iterRef, "valueC", "aNewValue"); TestValue(iterRef, "valueA", "aNewValue"); TestValue(iterRef, "valueB", "aNewValue"); TestValue(iterRef, "valueC", "aNewValue"); le_cfg_CommitTxn(iterRef); iterRef = le_cfg_CreateWriteTxn(pathBuffer); le_cfg_DeleteNode(iterRef, "valueB"); TestValue(iterRef, "valueA", "aNewValue"); TestValue(iterRef, "valueB", ""); TestValue(iterRef, "valueC", "aNewValue"); le_cfg_CommitTxn(iterRef); iterRef = le_cfg_CreateReadTxn(pathBuffer); TestValue(iterRef, "valueA", "aNewValue"); TestValue(iterRef, "valueB", ""); TestValue(iterRef, "valueC", "aNewValue"); DumpTree(iterRef, 0); le_cfg_CancelTxn(iterRef); }
//-------------------------------------------------------------------------------------------------- rlim_t resLim_GetSandboxedAppTmpfsLimit ( app_Ref_t appRef ///< [IN] The application to set resource limits for. ) { // Get the resource limit from the config tree. Zero means unlimited for tmpfs mounts and is // not allowed. // Determine the file system limit to set. rlim_t fileSysLimit = DEFAULT_LIMIT_FILE_SYSTEM_SIZE; // Create a config iterator to get the file system limit from the config tree. le_cfg_IteratorRef_t appCfg = le_cfg_CreateReadTxn(app_GetConfigPath(appRef)); le_cfg_GoToNode(appCfg, CFG_NODE_LIMIT_FILE_SYSTEM_SIZE); if (le_cfg_NodeExists(appCfg, "") == false) { LE_WARN("No resource limit %s. Assuming the default value %d.", CFG_NODE_LIMIT_FILE_SYSTEM_SIZE, DEFAULT_LIMIT_FILE_SYSTEM_SIZE); } else if ( (GetCfgResourceLimit(appCfg, &fileSysLimit) != LE_OK) || (fileSysLimit == 0) ) { // Use the default limit. LE_ERROR("Configured resource limit %s is invalid. Assuming the default value %d.", CFG_NODE_LIMIT_FILE_SYSTEM_SIZE, DEFAULT_LIMIT_FILE_SYSTEM_SIZE); fileSysLimit = DEFAULT_LIMIT_FILE_SYSTEM_SIZE; } le_cfg_CancelTxn(appCfg); return fileSysLimit; }
//-------------------------------------------------------------------------------------------------- static void Load ( void ) //-------------------------------------------------------------------------------------------------- { le_result_t result; // Connect to the Configuration API server. le_cfg_ConnectService(); // Initialize the "User API". user_Init(); // Start a read transaction on the root of the "system" configuration tree. le_cfg_IteratorRef_t i = le_cfg_CreateReadTxn("system:"); // Tell the Service Directory to delete all existing bindings. SendUnbindAllRequest(); // Iterate over the users collection. le_cfg_GoToNode(i, "/users"); result = le_cfg_GoToFirstChild(i); while (result == LE_OK) { uid_t uid; if (GetUserUid(i, &uid) == LE_OK) { // For each user, iterate over the bindings collection, sending the binding to // the Service Directory. le_cfg_GoToNode(i, "bindings"); result = le_cfg_GoToFirstChild(i); while (result == LE_OK) { SendBindRequest(uid, i); result = le_cfg_GoToNextSibling(i); } // Go back up to the user name node. le_cfg_GoToNode(i, "../.."); } // Move on to the next user. result = le_cfg_GoToNextSibling(i); } // Iterate over the apps collection. le_cfg_GoToNode(i, "/apps"); result = le_cfg_GoToFirstChild(i); while (result == LE_OK) { uid_t uid; if (GetAppUid(i, &uid) == LE_OK) { // For each app, iterate over the bindings collection, sending the binding to // the Service Directory. le_cfg_GoToNode(i, "bindings"); result = le_cfg_GoToFirstChild(i); while (result == LE_OK) { SendBindRequest(uid, i); result = le_cfg_GoToNextSibling(i); } // Go back up to the app's node. le_cfg_GoToNode(i, "../.."); } // Move on to the next app. result = le_cfg_GoToNextSibling(i); } exit(EXIT_SUCCESS); }
//-------------------------------------------------------------------------------------------------- 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; }
//-------------------------------------------------------------------------------------------------- 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); }
//-------------------------------------------------------------------------------------------------- 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); }
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); }
// ------------------------------------------------------------------------------------------------- static int HandleGetJSON ( const char* nodePathPtr, ///< Path to the node in the configTree. const char* filePathPtr ///< Path to the file in the file system. If NULL STDOUT is used ///< instead of a file. ) // ------------------------------------------------------------------------------------------------- { json_t* nodePtr = NULL; // Get the node path from our command line arguments. if (strcmp("*", nodePathPtr) == 0) { // Dump all trees // Create JSON root item json_t* rootPtr = CreateJsonNode("root", "root"); json_t* treeListPtr = json_array(); // Loop through the trees in the system. le_cfgAdmin_IteratorRef_t iteratorRef = le_cfgAdmin_CreateTreeIterator(); while (le_cfgAdmin_NextTree(iteratorRef) == LE_OK) { // Allocate space for the tree name, plus space for a trailing :/ used when we create a // transaction for that tree. char treeName[MAX_TREE_NAME_BYTES + 2] = ""; if (le_cfgAdmin_GetTreeName(iteratorRef, treeName, MAX_TREE_NAME_BYTES) != LE_OK) { continue; } // JSON node for the tree. json_t* treeNodePtr = CreateJsonNode(treeName, "tree"); strcat(treeName, ":/"); // Start a read transaction at the specified node path. Then dump the value, (if any.) le_cfg_IteratorRef_t iterRef = le_cfg_CreateReadTxn(treeName); le_cfg_GoToFirstChild(iterRef); // Dump tree to JSON DumpTreeJSON(iterRef, treeNodePtr); le_cfg_CancelTxn(iterRef); json_array_append(treeListPtr, treeNodePtr); } le_cfgAdmin_ReleaseTreeIterator(iteratorRef); // Finalize root object... json_object_set_new(rootPtr, "trees", treeListPtr); nodePtr = rootPtr; } else { // Start a read transaction at the specified node path. Then dump the value, (if any.) le_cfg_IteratorRef_t iterRef = le_cfg_CreateReadTxn(nodePathPtr); le_cfg_nodeType_t type = le_cfg_GetNodeType(iterRef, ""); switch (type) { case LE_CFG_TYPE_STEM: { char strBuffer[LE_CFG_STR_LEN_BYTES] = ""; char nodeType[LE_CFG_STR_LEN_BYTES] = ""; le_cfg_GetNodeName(iterRef, "", strBuffer, sizeof(strBuffer)); // If no name, we are dumping a complete tree. if (strlen(strBuffer) == 0) { strcpy(nodeType, "tree"); } else { strcpy(nodeType, NodeTypeStr(type)); } nodePtr = CreateJsonNode(strBuffer, nodeType); le_cfg_GoToFirstChild(iterRef); DumpTreeJSON(iterRef, nodePtr); le_cfg_GoToParent(iterRef); } break; default: nodePtr = CreateJsonNodeFromIterator(iterRef); break; } le_cfg_CancelTxn(iterRef); } if (nodePtr == NULL) { // Empty node nodePtr = json_object(); } // Dump Json content // stdout mode? int result = EXIT_SUCCESS; if (filePathPtr == NULL) { printf("%s\n", json_dumps(nodePtr, JSON_COMPACT)); } else if (json_dump_file(nodePtr, filePathPtr, JSON_COMPACT) != 0) { result = EXIT_FAILURE; } json_decref(nodePtr); return result; }
//-------------------------------------------------------------------------------------------------- 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; }
//-------------------------------------------------------------------------------------------------- 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); } }
//-------------------------------------------------------------------------------------------------- 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; }
//-------------------------------------------------------------------------------------------------- static assetData_InstanceDataRef_t GetObject9InstanceForApp ( const char* appName, ///< Name of the application in question. bool mapIfNotFound ///< If an instance was created, should a mapping be created for it? ) //-------------------------------------------------------------------------------------------------- { LE_DEBUG("Getting object 9 instance for application '%s'.", appName); // Attempt to read the mapping from the configuration. assetData_InstanceDataRef_t instanceRef = NULL; le_cfg_IteratorRef_t iterRef = le_cfg_CreateReadTxn(CFG_OBJECT_INFO_PATH); le_cfg_GoToNode(iterRef, appName); int instanceId = le_cfg_GetInt(iterRef, "oiid", -1); le_cfg_CancelTxn(iterRef); if (instanceId != -1) { LE_DEBUG("Was mapped to instance, %d.", instanceId); // Looks like there was a mapping. Try to get that instance and make sure it's not taken // by another application. If the instance was taken by another application, remap this // application to a new instance and update the mapping. if (LE_OK == assetData_GetInstanceRefById(LWM2M_NAME, LWM2M_SOFTWARE_UPDATE, instanceId, &instanceRef)) { char newName[MAX_APP_NAME_BYTES] = ""; LE_ASSERT(assetData_client_GetString(instanceRef, O9F_PKG_NAME, newName, sizeof(newName)) == LE_OK); if (strcmp(newName, appName) != 0) { LE_DEBUG("Instance has been taken by '%s', creating new.", newName); LE_ASSERT(assetData_CreateInstanceById(LWM2M_NAME, 9, -1, &instanceRef) == LE_OK); LE_ASSERT(assetData_client_SetString(instanceRef, O9F_PKG_NAME, appName) == LE_OK); if (mapIfNotFound) { LE_DEBUG("Recording new instance id."); SetObject9InstanceForApp(appName, instanceRef); } } else { LE_DEBUG("Instance is existing and has been reused."); } } else { LE_DEBUG("No instance found, creating new as mapped."); LE_ASSERT(assetData_CreateInstanceById(LWM2M_NAME, 9, instanceId, &instanceRef) == LE_OK); LE_ASSERT(assetData_client_SetString(instanceRef, O9F_PKG_NAME, appName) == LE_OK); } } else { LE_DEBUG("No instance mapping found, creating new."); // A mapping was not found. So create a new object, and let the data store assign an // instance Id. If desired, at this point record the instance mapping for later use. LE_ASSERT(assetData_CreateInstanceById(LWM2M_NAME, 9, -1, &instanceRef) == LE_OK); LE_ASSERT(assetData_client_SetString(instanceRef, O9F_PKG_NAME, appName) == LE_OK); if (mapIfNotFound) { LE_DEBUG("Recording new instance id."); SetObject9InstanceForApp(appName, instanceRef); } } return instanceRef; }
//-------------------------------------------------------------------------------------------------- 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"); }