in source/main.cpp [269:463]
int main(int argc, char *argv[])
{
CliArgs cliArgs;
if (!Config::ParseCliArgs(argc, argv, cliArgs) || !config.init(cliArgs))
{
LoggerFactory::getLoggerInstance()->shutdown();
return 0;
}
if (!LoggerFactory::reconfigure(config.config) &&
dynamic_cast<StdOutLogger *>(LoggerFactory::getLoggerInstance().get()) == nullptr)
{
// We attempted to start a non-stdout logger and failed, so we should fall back to STDOUT
config.config.logConfig.deviceClientLogtype = config.config.logConfig.LOG_TYPE_STDOUT;
LoggerFactory::reconfigure(config.config);
}
EnvUtils envUtils;
if (envUtils.AppendCwdToPath())
{
// Failure to append current working directory is not a fatal error,
// but some features of device client such as standard job action
// might not work without explicitly setting path to handler in job document.
LOG_WARN(TAG, "Unable to append current working directory to PATH environment variable.");
}
LOGM_INFO(TAG, "Now running AWS IoT Device Client version %s", DEVICE_CLIENT_VERSION_FULL);
// Register for listening to interrupt signals
sigset_t sigset;
memset(&sigset, 0, sizeof(sigset_t));
int received_signal;
sigaddset(&sigset, SIGINT);
sigprocmask(SIG_BLOCK, &sigset, 0);
shared_ptr<DefaultClientBaseNotifier> listener =
shared_ptr<DefaultClientBaseNotifier>(new DefaultClientBaseNotifier);
resourceManager = shared_ptr<SharedCrtResourceManager>(new SharedCrtResourceManager);
if (!resourceManager.get()->initialize(config.config, &features))
{
LOGM_ERROR(TAG, "*** %s: Failed to initialize AWS CRT SDK.", DC_FATAL_ERROR);
LoggerFactory::getLoggerInstance()->shutdown();
deviceClientAbort("Failed to initialize AWS CRT SDK");
}
#if !defined(EXCLUDE_FP)
if (config.config.fleetProvisioning.enabled &&
!config.config.fleetProvisioningRuntimeConfig.completedFleetProvisioning)
{
/*
* Establish MQTT connection using claim certificates and private key to provision the device/thing.
*/
# if !defined(DISABLE_MQTT)
attemptConnection();
# endif
/*
* Provision Device, parse new runtime conf file and validate its content.
*/
FleetProvisioning fleetProvisioning;
if (!fleetProvisioning.ProvisionDevice(resourceManager, config.config) ||
!config.ParseConfigFile(Config::DEFAULT_FLEET_PROVISIONING_RUNTIME_CONFIG_FILE, true) ||
!config.ValidateAndStoreRuntimeConfig())
{
LOGM_ERROR(
TAG,
"*** %s: Failed to Provision thing or validate newly created resources. "
"Please verify your AWS IoT credentials, "
"configuration, Fleet Provisioning Template, claim certificate and policy used. ***",
DC_FATAL_ERROR);
LoggerFactory::getLoggerInstance()->shutdown();
deviceClientAbort("Fleet provisioning failed");
}
resourceManager->disconnect();
}
#endif
/*
* Establish MQTT connection using permanent certificate and private key to start and run AWS IoT Device Client
* features.
*/
#if !defined(DISABLE_MQTT)
attemptConnection();
#endif
#if !defined(EXCLUDE_SHADOW)
# if !defined(EXCLUDE_CONFIG_SHADOW)
if (config.config.configShadow.enabled)
{
LOG_INFO(TAG, "Config shadow is enabled");
ConfigShadow configShadow;
configShadow.reconfigureWithConfigShadow(resourceManager, config.config);
resourceManager->disconnect();
attemptConnection();
}
# endif
#endif
featuresReadWriteLock.lock(); // LOCK
#if !defined(EXCLUDE_JOBS)
unique_ptr<JobsFeature> jobs;
if (config.config.jobs.enabled)
{
LOG_INFO(TAG, "Jobs is enabled");
jobs = unique_ptr<JobsFeature>(new JobsFeature());
jobs->init(resourceManager, listener, config.config);
features.push_back(jobs.get());
}
else
{
LOG_INFO(TAG, "Jobs is disabled");
}
#endif
#if !defined(EXCLUDE_ST)
unique_ptr<SecureTunnelingFeature> tunneling;
if (config.config.tunneling.enabled)
{
LOG_INFO(TAG, "Secure Tunneling is enabled");
tunneling = unique_ptr<SecureTunnelingFeature>(new SecureTunnelingFeature());
tunneling->init(resourceManager, listener, config.config);
features.push_back(tunneling.get());
}
else
{
LOG_INFO(TAG, "Secure Tunneling is disabled");
}
#endif
#if !defined(EXCLUDE_DD)
unique_ptr<DeviceDefenderFeature> deviceDefender;
if (config.config.deviceDefender.enabled)
{
LOG_INFO(TAG, "Device Defender is enabled");
deviceDefender = unique_ptr<DeviceDefenderFeature>(new DeviceDefenderFeature());
deviceDefender->init(resourceManager, listener, config.config);
features.push_back(deviceDefender.get());
}
else
{
LOG_INFO(TAG, "Device Defender is disabled");
}
#endif
#if !defined(EXCLUDE_SHADOW)
# if !defined(EXCLUDE_SAMPLE_SHADOW)
unique_ptr<SampleShadowFeature> sampleShadow;
if (config.config.sampleShadow.enabled)
{
LOG_INFO(TAG, "Sample shadow is enabled");
sampleShadow = unique_ptr<SampleShadowFeature>(new SampleShadowFeature());
sampleShadow->init(resourceManager, listener, config.config);
features.push_back(sampleShadow.get());
}
else
{
LOG_INFO(TAG, "Sample shadow is disabled");
}
# endif
#endif
#if !defined(EXCLUDE_SAMPLES)
# if !defined(EXCLUDE_PUBSUB)
unique_ptr<PubSubFeature> pubSub;
if (config.config.pubSub.enabled)
{
LOG_INFO(TAG, "PubSub is enabled");
pubSub = unique_ptr<PubSubFeature>(new PubSubFeature());
pubSub->init(resourceManager, listener, config.config);
features.push_back(pubSub.get());
}
else
{
LOG_INFO(TAG, "Pub Sub is disabled");
}
# endif
#endif
resourceManager->startDeviceClientFeatures();
featuresReadWriteLock.unlock(); // UNLOCK
// Now allow this thread to sleep until it's interrupted by a signal
while (true)
{
sigwait(&sigset, &received_signal);
LOGM_INFO(TAG, "Received signal: (%d)", received_signal);
if (SIGINT == received_signal)
{
shutdown();
}
}
return 0;
}