in edge-agent/src/Microsoft.Azure.Devices.Edge.Agent.IoTHub/EdgeAgentConnection.cs [223:282]
async void OnConnectionStatusChanged(ConnectionStatus status, ConnectionStatusChangeReason reason)
{
try
{
UpstreamProtocol protocol =
this.ModuleConnection.GetModuleClient().Map(x => x.UpstreamProtocol).GetOrElse(UpstreamProtocol.Amqp);
Events.ConnectionStatusChanged(status, reason);
// We want to notify the IoT Edge daemon in the following two cases -
// 1. The device has been deprovisioned and might have been reprovisioned on another IoT hub.
// 2. The IoT Hub that the device belongs to is no longer in existence and the device might have been
// moved to a different IoT hub.
//
// When the Amqp or AmqpWs protocol is used, the SDK returns a connection status change reason of
// Device_Disabled when a device is either disabled or deleted in IoT hub.
// For the Mqtt and MqttWs protocol however, the SDK returns a Bad_Credential status as it's not
// possible for IoT hub to distinguish between 'device does not exist', 'device is disabled' and
// 'device exists but wrong credentials were supplied' cases.
//
// When an IoT hub is no longer in existence (i.e., it has been deleted), the SDK returns the
// connection status change reason of Bad_Credential for all the Amqp and Mqtt protocols.
if ((reason == ConnectionStatusChangeReason.Device_Disabled &&
(protocol == UpstreamProtocol.Amqp || protocol == UpstreamProtocol.AmqpWs)) ||
reason == ConnectionStatusChangeReason.Bad_Credential)
{
await this.deviceManager.ReprovisionDeviceAsync();
}
if (this.pullOnReconnect && this.initTask.IsCompleted && status == ConnectionStatus.Connected)
{
var delayedTwinPull = true;
using (await this.twinLock.LockAsync())
{
var now = DateTime.Now;
if (now - this.lastTwinPullOnConnect > this.twinPullOnConnectThrottleTime && !this.isDelayedTwinPullInProgress.Get())
{
this.lastTwinPullOnConnect = now;
await this.RefreshTwinAsync();
delayedTwinPull = false;
}
}
if (delayedTwinPull)
{
if (this.isDelayedTwinPullInProgress.GetAndSet(true))
{
Interlocked.Increment(ref this.pullRequestCounter);
}
else
{
_ = this.DelayedRefreshTwinAsync();
}
}
}
}
catch (Exception ex) when (!ex.IsFatal())
{
Events.ConnectionStatusChangedHandlingError(ex);
}
}