in source/tunneling/SecureTunnelingFeature.cpp [144:223]
void SecureTunnelingFeature::OnSubscribeToTunnelsNotifyResponse(
SecureTunnelingNotifyResponse *response,
int ioErr)
{
LOG_DEBUG(TAG, "Received MQTT Tunnel Notification");
if (ioErr || !response)
{
LOGM_ERROR(TAG, "OnSubscribeToTunnelsNotifyResponse received error. ioErr=%d", ioErr);
return;
}
for (auto &c : mContexts)
{
if (c->IsDuplicateNotification(*response))
{
LOG_INFO(TAG, "Received duplicate MQTT Tunnel Notification. Ignoring...");
return;
}
}
string clientMode = response->ClientMode->c_str();
if (clientMode != "destination")
{
LOGM_ERROR(TAG, "Unexpected client mode: %s", clientMode.c_str());
return;
}
size_t nServices = response->Services->size();
if (nServices == 0)
{
LOG_ERROR(TAG, "no service requested");
return;
}
if (nServices > 1)
{
LOG_ERROR(
TAG,
"Received a multi-port tunnel request, but multi-port tunneling is not currently supported "
"by Device Client.");
return;
}
string accessToken = response->ClientAccessToken->c_str();
if (accessToken.empty())
{
LOG_ERROR(TAG, "access token cannot be empty");
return;
}
string region = response->Region->c_str();
if (region.empty())
{
LOG_ERROR(TAG, "region cannot be empty");
return;
}
string service = response->Services->at(0).c_str();
uint16_t port = GetPortFromService(service);
if (!IsValidPort(port))
{
LOGM_ERROR(TAG, "Requested service is not supported: %s", service.c_str());
return;
}
LOGM_DEBUG(TAG, "Region=%s, Service=%s", region.c_str(), service.c_str());
std::unique_ptr<SecureTunnelingContext> context =
unique_ptr<SecureTunnelingContext>(new SecureTunnelingContext(
mSharedCrtResourceManager,
mRootCa,
accessToken,
GetEndpoint(region),
port,
bind(&SecureTunnelingFeature::OnConnectionShutdown, this, placeholders::_1)));
if (context->ConnectToSecureTunnel())
{
mContexts.push_back(std::move(context));
}
}