bool App::aboutToExec(xmlParserSettings *pXmlParserSettings, Settings* pSettings)
{
TRACE();
FILE_LOG
(logINFO
) <<
"App: created: thread id = " <<
QThread::currentThreadId();
// Save off pointers to local XML file parser and content
m_pXmlParserSettings = pXmlParserSettings;
m_pSettings = pSettings;
// Check for multiple instances of lmd
int countOfProcesses = System::getProcessIdsByProcessName(szLmdProgramName, listOfPids);
if (countOfProcesses > 1)
{
FILE_LOG(logERROR) << "Only one instance of the Link Manager can run at the same time";
return false;
}
// Process contents of the local configuration XML file
processLocalSettings(pSettings);
// Process command line arguments (will override local XML file settings)
if (!parseArgs())
{
return false;
}
// Allow user to ask for help without being root, but must be root hereafter
#ifdef Q_OS_LINUX
if (geteuid() != 0)
{
// NOTE: SNMP Subagent connection and PTP operation when controlled requires root privilege
FILE_LOG(logERROR) << "Link Manager requires ROOT permisssions to execute";
printf("Link Manager requires ROOT permisssions to execute\n");
return false;
}
#endif
// Perform lazy initialization of singletons prior to thread execution (to ensure thread safe creation)
pSnmpInterface->onReset(restoreDefaults);
pMdlInterface->onReset(restoreDefaults);
pPtpdInterface->onReset(restoreDefaults);
pRfnmProcessor->onReset(restoreDefaults);
// Create state machine content
FILE_LOG(logINFO) << "INIT: Creating state machine...";
// Hook up state entry and exit routines (TODO: remove some of these if eventually not used)
Q_ASSERT(QObject::connect(m_stateRoot,
SIGNAL(entered
()),
this,
SLOT(onStateRootEntered
())));
Q_ASSERT(QObject::connect(m_stateRoot,
SIGNAL(exited
()),
this,
SLOT(onStateRootExited
())));
Q_ASSERT(QObject::connect(m_stateInitialize,
SIGNAL(entered
()),
this,
SLOT(onStateInitializeEntered
())));
Q_ASSERT(QObject::connect(m_stateInitialize,
SIGNAL(exited
()),
this,
SLOT(onStateInitializeExited
())));
Q_ASSERT(QObject::connect(m_stateConfiguring,
SIGNAL(entered
()),
this,
SLOT(onStateConfiguringEntered
())));
Q_ASSERT(QObject::connect(m_stateConfiguring,
SIGNAL(exited
()),
this,
SLOT(onStateConfiguringExited
())));
Q_ASSERT(QObject::connect(m_stateUnconfigured,
SIGNAL(entered
()),
this,
SLOT(onStateUnconfiguredEntered
())));
Q_ASSERT(QObject::connect(m_stateUnconfigured,
SIGNAL(exited
()),
this,
SLOT(onStateUnconfiguredExited
())));
Q_ASSERT(QObject::connect(m_stateRunning,
SIGNAL(entered
()),
this,
SLOT(onStateRunningEntered
())));
Q_ASSERT(QObject::connect(m_stateRunning,
SIGNAL(exited
()),
this,
SLOT(onStateRunningExited
())));
Q_ASSERT(QObject::connect(m_stateIdle,
SIGNAL(entered
()),
this,
SLOT(onStateIdleEntered
())));
Q_ASSERT(QObject::connect(m_stateIdle,
SIGNAL(exited
()),
this,
SLOT(onStateIdleExited
())));
Q_ASSERT(QObject::connect(m_stateInitiatedBIT,
SIGNAL(entered
()),
this,
SLOT(onStateInitiatedBITEntered
())));
Q_ASSERT(QObject::connect(m_stateInitiatedBIT,
SIGNAL(exited
()),
this,
SLOT(onStateInitiatedBITExited
())));
Q_ASSERT(QObject::connect(m_stateDone,
SIGNAL(entered
()),
this,
SLOT(onStateDoneEntered
())));
Q_ASSERT(QObject::connect(m_stateDone,
SIGNAL(exited
()),
this,
SLOT(onStateDoneExited
())));
// Set initial state of root state with common exit for all children states
m_stateRoot->setInitialState(m_stateInitialize);
// Make done state the transition target for application exit from any state
Q_ASSERT(m_stateRoot->addTransition(this, SIGNAL(aboutToQuit()), m_stateDone) != 0);
// Add states to machine
m_machine->addState(m_stateRoot);
m_machine->addState(m_stateDone);
// Add state transitions:
// Transition from stateInitialize to stateUnconfigured after initialization. This ensures SNMP
// thread is active to send out traps
//Q_ASSERT(m_stateInitialize->addTransition(m_stateInitialize, SIGNAL(entered()), m_stateUnconfigured) != 0);
Q_ASSERT(m_stateInitialize->addTransition(this, SIGNAL(initializationDone()), m_stateUnconfigured) != 0);
// SNMP configured() signal responsive states
Q_ASSERT(m_stateUnconfigured->addTransition(pSnmpInterface, SIGNAL(configured()), m_stateConfiguring) != 0);
Q_ASSERT(m_stateUnconfigured->addTransition(this, SIGNAL(configurationSucceeded()), m_stateIdle) != 0); // MDL file load at boot
Q_ASSERT(m_stateIdle->addTransition(pSnmpInterface, SIGNAL(configured()), m_stateConfiguring) != 0);
Q_ASSERT(m_stateRunning->addTransition(pSnmpInterface, SIGNAL(configured()), m_stateConfiguring) != 0);
// Configuration success or failure internal signals from Configuring state
Q_ASSERT(m_stateConfiguring->addTransition(this, SIGNAL(configurationSucceeded()), m_stateIdle) != 0);
Q_ASSERT(m_stateConfiguring->addTransition(this, SIGNAL(configurationFailed()), m_stateUnconfigured) != 0);
// SNMP bitInitiated() signal responsive states
// NOTE: call setBitReturnState in each state entry to specify return state from BIT
Q_ASSERT(m_stateUnconfigured->addTransition(pSnmpInterface, SIGNAL(bitInitiated()), m_stateInitiatedBIT) != 0);
Q_ASSERT(m_stateConfiguring->addTransition(pSnmpInterface, SIGNAL(bitInitiated()), m_stateInitiatedBIT) != 0);
Q_ASSERT(m_stateIdle->addTransition(pSnmpInterface, SIGNAL(bitInitiated()), m_stateInitiatedBIT) != 0);
Q_ASSERT(m_stateRunning->addTransition(pSnmpInterface, SIGNAL(bitInitiated()), m_stateInitiatedBIT) != 0);
// Transition to and from run state
Q_ASSERT(m_stateIdle->addTransition(pRfnmProcessor, SIGNAL(run()), m_stateRunning) != 0);
Q_ASSERT(m_stateRunning->addTransition(pRfnmProcessor, SIGNAL(stop()), m_stateIdle) != 0);
// SNMP reset() responsive states
Q_ASSERT(m_stateConfiguring->addTransition(pSnmpInterface, SIGNAL(reset()), m_stateInitialize) != 0);
Q_ASSERT(m_stateUnconfigured->addTransition(pSnmpInterface, SIGNAL(reset()), m_stateInitialize) != 0);
Q_ASSERT(m_stateRunning->addTransition(pSnmpInterface, SIGNAL(reset()), m_stateInitialize) != 0);
Q_ASSERT(m_stateIdle->addTransition(pSnmpInterface, SIGNAL(reset()), m_stateInitialize) != 0);
Q_ASSERT(m_stateInitiatedBIT->addTransition(pSnmpInterface, SIGNAL(reset()), m_stateInitialize) != 0);
// SNMP set epoch
Q_ASSERT(QObject::connect(pSnmpInterface,
SIGNAL(setEpochMicroseconds
(unsigned int)),
this,
SLOT(setEpochMicroseconds
(unsigned int))));
// Connect state machine exit to application exit
Q_ASSERT(QObject::connect(m_machine,
SIGNAL(finished
()),
this,
SLOT(quit
())));
// Start up state machine
m_machine->setInitialState(m_stateRoot);
m_machine->start();
// Create processes and secondary thread objects (TODO: add others here)
.
.
.
// Create secondary threads (TODO: add others here)
FILE_LOG(logINFO) << "INIT: Creating secondary threads...";
m_snmpSubAgentThread = new SnmpSubAgentThread(0);
m_tdmaThread = new TdmaThread(0);
// Start up secondary threads (TODO: add others here)
FILE_LOG(logINFO) << "INIT: Starting secondary threads...";
m_snmpSubAgentThread
->start
(QThread::NormalPriority);
return true;
}