blob: 8035549b75c6b55ad811fddb9ecb29b8bce4e369 [file] [log] [blame]
/*
*
* Copyright (c) 2013-2017 Nest Labs, Inc.
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file
* This file implements a derived unsolicited responder
* (i.e., server) for the Weave Network Provisioning profile used
* for the Weave mock device command line functional testing
* tool.
*
*/
#define __STDC_LIMIT_MACROS
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#include <limits.h>
#include <stdio.h>
#include "ToolCommon.h"
#include "MockNPServer.h"
#include <Weave/Support/CodeUtils.h>
#include <Weave/Core/WeaveTLV.h>
#include <Weave/Profiles/WeaveProfiles.h>
#include <Weave/Profiles/common/CommonProfile.h>
#include "MockOpActions.h"
extern MockOpActions OpActions;
using namespace nl::Weave::TLV;
using namespace nl::Weave::Profiles;
using namespace nl::Weave::Profiles::NetworkProvisioning;
MockNetworkProvisioningServer::MockNetworkProvisioningServer()
{
NextNetworkId = 1;
// NOTE: If you change this code, be sure to adjust MockNetworkProvisioningServer::Preconfig()
// accordingly.
ScanResults[0].NetworkType = kNetworkType_WiFi;
ScanResults[0].WiFiSSID = strdup("Wireless-1");
ScanResults[0].WiFiMode = kWiFiMode_Managed;
ScanResults[0].WiFiRole = kWiFiRole_Station;
ScanResults[0].WiFiSecurityType = kWiFiSecurityType_None;
ScanResults[0].WirelessSignalStrength = 30;
ScanResults[1].NetworkType = kNetworkType_WiFi;
ScanResults[1].WiFiSSID = strdup("Wireless-2");
ScanResults[1].WiFiMode = kWiFiMode_Managed;
ScanResults[1].WiFiRole = kWiFiRole_Station;
ScanResults[1].WiFiSecurityType = kWiFiSecurityType_WEP;
ScanResults[1].WirelessSignalStrength = 10;
ScanResults[2].NetworkType = kNetworkType_WiFi;
ScanResults[2].WiFiSSID = strdup("Wireless-3");
ScanResults[2].WiFiMode = kWiFiMode_Managed;
ScanResults[2].WiFiRole = kWiFiRole_Station;
ScanResults[2].WiFiSecurityType = kWiFiSecurityType_WPAPersonal;
ScanResults[2].WirelessSignalStrength = -11;
ScanResults[3].NetworkType = kNetworkType_Thread;
ScanResults[3].ThreadNetworkName = strdup("Thread-1");
ScanResults[3].ThreadExtendedPANId = (uint8_t *)malloc(8);
for (int i = 0; i < 8; i++)
ScanResults[3].ThreadExtendedPANId[i] = i + 1;
}
WEAVE_ERROR MockNetworkProvisioningServer::Init(WeaveExchangeManager *exchangeMgr)
{
WEAVE_ERROR err;
err = this->NetworkProvisioningServer::Init(exchangeMgr);
SuccessOrExit(err);
SetDelegate(this);
exit:
return err;
}
WEAVE_ERROR MockNetworkProvisioningServer::Shutdown()
{
return this->NetworkProvisioningServer::Shutdown();
}
void MockNetworkProvisioningServer::Reset()
{
for (int i = 0; i < kMaxProvisionedNetworks; i++)
ProvisionedNetworks[i].Clear();
for (int i = 0; i < kMaxScanResults; i++)
ScanResults[i].NetworkId = -1;
NextNetworkId = 1;
}
void MockNetworkProvisioningServer::Preconfig()
{
Reset();
ProvisionedNetworks[0].NetworkId = NextNetworkId++;
ProvisionedNetworks[0].NetworkType = kNetworkType_WiFi;
ProvisionedNetworks[0].WiFiSSID = strdup("Wireless-3");
ProvisionedNetworks[0].WiFiMode = kWiFiMode_Managed;
ProvisionedNetworks[0].WiFiRole = kWiFiRole_Station;
ProvisionedNetworks[0].WiFiSecurityType = kWiFiSecurityType_WPAPersonal;
ProvisionedNetworks[0].WiFiKey = (uint8_t *)strdup("apassword");
ProvisionedNetworks[0].WiFiKeyLen = strlen((const char *)ProvisionedNetworks[0].WiFiKey);
ProvisionedNetworks[1].NetworkId = NextNetworkId++;
ProvisionedNetworks[1].NetworkType = kNetworkType_Thread;
ProvisionedNetworks[1].ThreadNetworkName = strdup("Thread-1");
ProvisionedNetworks[1].ThreadExtendedPANId = (uint8_t *)malloc(8);
for (int i = 0; i < 8; i++)
ProvisionedNetworks[1].ThreadExtendedPANId[i] = i + 1;
ProvisionedNetworks[1].ThreadNetworkKey = (uint8_t *)strdup("thisisathreadkey"); // must be 16 bytes
ProvisionedNetworks[1].ThreadNetworkKeyLen = strlen((const char *)ProvisionedNetworks[1].ThreadNetworkKey);
}
WEAVE_ERROR MockNetworkProvisioningServer::HandleScanNetworks(uint8_t networkType)
{
{
char ipAddrStr[64];
mCurOp->PeerAddr.ToString(ipAddrStr, sizeof(ipAddrStr));
printf("ScanNetworks request received from node %" PRIX64 " (%s)\n", mCurOp->PeerNodeId, ipAddrStr);
printf(" Requested Network Type: %d\n", networkType);
}
mOpArgs.networkType = networkType;
CompleteOrDelayCurrentOp("scan-networks");
return WEAVE_NO_ERROR;
}
WEAVE_ERROR MockNetworkProvisioningServer::ValidateNetworkConfig(NetworkInfo& netConfig)
{
WEAVE_ERROR err = WEAVE_NO_ERROR;
if (netConfig.NetworkType == kNetworkType_NotSpecified)
{
printf("Invalid network configuration: network type not specified\n");
err = SendStatusReport(kWeaveProfile_NetworkProvisioning, kStatusCode_InvalidNetworkConfiguration);
SuccessOrExit(err);
ExitNow(err = WEAVE_ERROR_INVALID_ARGUMENT);
}
if (netConfig.NetworkType == kNetworkType_WiFi)
{
if (netConfig.WiFiSSID == NULL)
{
printf("Invalid network configuration: Missing WiFi SSID\n");
err = SendStatusReport(kWeaveProfile_NetworkProvisioning, kStatusCode_InvalidNetworkConfiguration);
SuccessOrExit(err);
ExitNow(err = WEAVE_ERROR_INVALID_ARGUMENT);
}
if (netConfig.WiFiMode == kWiFiMode_NotSpecified)
{
printf("Invalid network configuration: Missing WiFi Mode\n");
err = SendStatusReport(kWeaveProfile_NetworkProvisioning, kStatusCode_InvalidNetworkConfiguration);
SuccessOrExit(err);
ExitNow(err = WEAVE_ERROR_INVALID_ARGUMENT);
}
if (netConfig.WiFiRole == kWiFiRole_NotSpecified)
{
printf("Invalid network configuration: Missing WiFi Role\n");
err = SendStatusReport(kWeaveProfile_NetworkProvisioning, kStatusCode_InvalidNetworkConfiguration);
SuccessOrExit(err);
ExitNow(err = WEAVE_ERROR_INVALID_ARGUMENT);
}
if (netConfig.WiFiSecurityType == kWiFiSecurityType_NotSpecified)
{
printf("Invalid network configuration: Missing WiFi Security Type\n");
err = SendStatusReport(kWeaveProfile_NetworkProvisioning, kStatusCode_InvalidNetworkConfiguration);
SuccessOrExit(err);
ExitNow(err = WEAVE_ERROR_INVALID_ARGUMENT);
}
if (netConfig.WiFiMode != kWiFiMode_Managed)
{
printf("Unsupported WiFi Mode: %d\n", netConfig.WiFiMode);
err = SendStatusReport(kWeaveProfile_NetworkProvisioning, kStatusCode_UnsupportedWiFiMode);
SuccessOrExit(err);
ExitNow(err = WEAVE_ERROR_INVALID_ARGUMENT);
}
if (netConfig.WiFiRole != kWiFiRole_Station)
{
printf("Unsupported WiFi Role: %d\n", netConfig.WiFiRole);
err = SendStatusReport(kWeaveProfile_NetworkProvisioning, kStatusCode_UnsupportedWiFiRole);
SuccessOrExit(err);
ExitNow(err = WEAVE_ERROR_INVALID_ARGUMENT);
}
if (netConfig.WiFiSecurityType != kWiFiSecurityType_None && netConfig.WiFiSecurityType != kWiFiSecurityType_WEP
&& netConfig.WiFiSecurityType != kWiFiSecurityType_WPAPersonal
&& netConfig.WiFiSecurityType != kWiFiSecurityType_WPA2Personal
&& netConfig.WiFiSecurityType != kWiFiSecurityType_WPA2MixedPersonal)
{
printf("Unsupported WiFi Security Type: %d\n", netConfig.WiFiSecurityType);
err = SendStatusReport(kWeaveProfile_NetworkProvisioning, kStatusCode_UnsupportedWiFiSecurityType);
SuccessOrExit(err);
ExitNow(err = WEAVE_ERROR_INVALID_ARGUMENT);
}
if (netConfig.WiFiSecurityType != kWiFiSecurityType_None && netConfig.WiFiKey == NULL)
{
printf("Invalid network configuration: Missing WiFi Key\n");
err = SendStatusReport(kWeaveProfile_NetworkProvisioning, kStatusCode_InvalidNetworkConfiguration);
SuccessOrExit(err);
ExitNow(err = WEAVE_ERROR_INVALID_ARGUMENT);
}
}
else if (netConfig.NetworkType == kNetworkType_Thread)
{
if (netConfig.ThreadNetworkName == NULL)
{
printf("Invalid network configuration: Missing Thread network name\n");
err = SendStatusReport(kWeaveProfile_NetworkProvisioning, kStatusCode_InvalidNetworkConfiguration);
SuccessOrExit(err);
ExitNow(err = WEAVE_ERROR_INVALID_ARGUMENT);
}
if (netConfig.ThreadExtendedPANId == NULL)
{
printf("Invalid network configuration: Missing Thread extended PAN id\n");
err = SendStatusReport(kWeaveProfile_NetworkProvisioning, kStatusCode_InvalidNetworkConfiguration);
SuccessOrExit(err);
ExitNow(err = WEAVE_ERROR_INVALID_ARGUMENT);
}
if (netConfig.ThreadNetworkKey == NULL || netConfig.ThreadNetworkKeyLen == 0)
{
printf("Invalid network configuration: Missing Thread network key\n");
err = SendStatusReport(kWeaveProfile_NetworkProvisioning, kStatusCode_InvalidNetworkConfiguration);
SuccessOrExit(err);
ExitNow(err = WEAVE_ERROR_INVALID_ARGUMENT);
}
if (netConfig.ThreadNetworkKeyLen == 0)
{
printf("Invalid network configuration: Zero-length Thread network key\n");
err = SendStatusReport(kWeaveProfile_NetworkProvisioning, kStatusCode_InvalidNetworkConfiguration);
SuccessOrExit(err);
ExitNow(err = WEAVE_ERROR_INVALID_ARGUMENT);
}
}
else
{
printf("Unsupported network type: %d\n", netConfig.NetworkType);
err = SendStatusReport(kWeaveProfile_NetworkProvisioning, kStatusCode_UnsupportedNetworkType);
SuccessOrExit(err);
ExitNow(err = WEAVE_ERROR_INVALID_ARGUMENT);
}
printf("Network configuration valid\n");
exit:
return err;
}
WEAVE_ERROR MockNetworkProvisioningServer::HandleAddNetwork(PacketBuffer* networkInfoTLV)
{
{
char ipAddrStr[64];
mCurOp->PeerAddr.ToString(ipAddrStr, sizeof(ipAddrStr));
printf("AddNetwork request received from node %" PRIX64 " (%s)\n", mCurOp->PeerNodeId, ipAddrStr);
}
mOpArgs.networkInfoTLV = networkInfoTLV;
CompleteOrDelayCurrentOp("add-network");
return WEAVE_NO_ERROR;
}
WEAVE_ERROR MockNetworkProvisioningServer::HandleUpdateNetwork(PacketBuffer* networkInfoTLV)
{
{
char ipAddrStr[64];
mCurOp->PeerAddr.ToString(ipAddrStr, sizeof(ipAddrStr));
printf("UpdateNetwork request received from node %" PRIX64 " (%s)\n", mCurOp->PeerNodeId, ipAddrStr);
}
mOpArgs.networkInfoTLV = networkInfoTLV;
CompleteOrDelayCurrentOp("update-network");
return WEAVE_NO_ERROR;
}
WEAVE_ERROR MockNetworkProvisioningServer::HandleRemoveNetwork(uint32_t networkId)
{
{
char ipAddrStr[64];
mCurOp->PeerAddr.ToString(ipAddrStr, sizeof(ipAddrStr));
printf("RemoveNetwork request received from node %" PRIX64 " (%s)\n", mCurOp->PeerNodeId, ipAddrStr);
printf(" Network Id: %u\n", networkId);
}
mOpArgs.networkId = networkId;
CompleteOrDelayCurrentOp("remove-network");
return WEAVE_NO_ERROR;
}
WEAVE_ERROR MockNetworkProvisioningServer::HandleGetNetworks(uint8_t flags)
{
{
char ipAddrStr[64];
mCurOp->PeerAddr.ToString(ipAddrStr, sizeof(ipAddrStr));
printf("GetNetworks request received from node %" PRIX64 " (%s)\n", mCurOp->PeerNodeId, ipAddrStr);
printf(" Flags: %d\n", flags);
}
mOpArgs.flags = flags;
CompleteOrDelayCurrentOp("get-networks");
return WEAVE_NO_ERROR;
}
WEAVE_ERROR MockNetworkProvisioningServer::HandleEnableNetwork(uint32_t networkId)
{
{
char ipAddrStr[64];
mCurOp->PeerAddr.ToString(ipAddrStr, sizeof(ipAddrStr));
printf("EnableNetwork request received from node %" PRIX64 " (%s)\n", mCurOp->PeerNodeId, ipAddrStr);
printf(" Network Id: %u\n", networkId);
}
mOpArgs.networkId = networkId;
CompleteOrDelayCurrentOp("enable-network");
return WEAVE_NO_ERROR;
}
WEAVE_ERROR MockNetworkProvisioningServer::HandleDisableNetwork(uint32_t networkId)
{
{
char ipAddrStr[64];
mCurOp->PeerAddr.ToString(ipAddrStr, sizeof(ipAddrStr));
printf("DisableNetwork request received from node %" PRIX64 " (%s)\n", mCurOp->PeerNodeId, ipAddrStr);
printf(" Network Id: %u\n", networkId);
}
mOpArgs.networkId = networkId;
CompleteOrDelayCurrentOp("disable-network");
return WEAVE_NO_ERROR;
}
WEAVE_ERROR MockNetworkProvisioningServer::HandleTestConnectivity(uint32_t networkId)
{
{
char ipAddrStr[64];
mCurOp->PeerAddr.ToString(ipAddrStr, sizeof(ipAddrStr));
printf("TestConnectivity request received from node %" PRIX64 " (%s)\n", mCurOp->PeerNodeId, ipAddrStr);
printf(" Network Id: %u\n", networkId);
}
mOpArgs.networkId = networkId;
CompleteOrDelayCurrentOp("test-connectivity");
return WEAVE_NO_ERROR;
}
WEAVE_ERROR MockNetworkProvisioningServer::HandleSetRendezvousMode(uint16_t rendezvousMode)
{
{
char ipAddrStr[64];
mCurOp->PeerAddr.ToString(ipAddrStr, sizeof(ipAddrStr));
printf("SetRendezvousMode request received from node %" PRIX64 " (%s)\n", mCurOp->PeerNodeId, ipAddrStr);
printf(" Rendezvous Mode: %u\n", rendezvousMode);
}
mOpArgs.rendezvousMode = rendezvousMode;
CompleteOrDelayCurrentOp("set-rendezvous-mode");
return WEAVE_NO_ERROR;
}
void MockNetworkProvisioningServer::EnforceAccessControl(nl::Weave::ExchangeContext *ec, uint32_t msgProfileId, uint8_t msgType,
const nl::Weave::WeaveMessageInfo *msgInfo, AccessControlResult& result)
{
if (sSuppressAccessControls)
{
result = kAccessControlResult_Accepted;
}
NetworkProvisioningDelegate::EnforceAccessControl(ec, msgProfileId, msgType, msgInfo, result);
}
bool MockNetworkProvisioningServer::IsPairedToAccount() const
{
return (gCASEOptions.ServiceConfig != NULL);
}
void MockNetworkProvisioningServer::HandleOpDelayComplete(System::Layer* lSystemLayer, void* aAppState, System::Error aError)
{
MockNetworkProvisioningServer* lServer = reinterpret_cast<MockNetworkProvisioningServer*>(aAppState);
lServer->CompleteCurrentOp();
}
void MockNetworkProvisioningServer::CompleteOrDelayCurrentOp(const char *opName)
{
uint32_t delay = OpActions.GetDelay(opName);
if (delay > 0)
{
printf("Delaying operation by %lums\n", (unsigned long)delay);
::SystemLayer.StartTimer(delay, HandleOpDelayComplete, this);
}
else
CompleteCurrentOp();
}
void MockNetworkProvisioningServer::CompleteCurrentOp()
{
WEAVE_ERROR err;
switch (mCurOpType)
{
case NetworkProvisioning::kMsgType_AddNetwork:
err = CompleteAddNetwork(mOpArgs.networkInfoTLV);
break;
case NetworkProvisioning::kMsgType_DisableNetwork:
err = CompleteDisableNetwork(mOpArgs.networkId);
break;
case NetworkProvisioning::kMsgType_EnableNetwork:
err = CompleteEnableNetwork(mOpArgs.networkId);
break;
case NetworkProvisioning::kMsgType_GetNetworks:
err = CompleteGetNetworks(mOpArgs.flags);
break;
case NetworkProvisioning::kMsgType_RemoveNetwork:
err = CompleteRemoveNetwork(mOpArgs.networkId);
break;
case NetworkProvisioning::kMsgType_ScanNetworks:
err = CompleteScanNetworks(mOpArgs.networkType);
break;
case NetworkProvisioning::kMsgType_SetRendezvousMode:
err = CompleteSetRendezvousMode(mOpArgs.rendezvousMode);
break;
case NetworkProvisioning::kMsgType_TestConnectivity:
err = CompleteTestConnectivity(mOpArgs.networkId);
break;
case NetworkProvisioning::kMsgType_UpdateNetwork:
err = CompleteUpdateNetwork(mOpArgs.networkInfoTLV);
break;
default:
err = WEAVE_ERROR_INVALID_MESSAGE_TYPE;
break;
}
if (err != WEAVE_NO_ERROR)
SendStatusReport(kWeaveProfile_Common, Common::kStatus_InternalError, err);
}
WEAVE_ERROR MockNetworkProvisioningServer::CompleteScanNetworks(uint8_t networkType)
{
WEAVE_ERROR err = WEAVE_NO_ERROR;
PacketBuffer *respBuf = NULL;
TLVWriter writer;
uint16_t resultCount = 0;
char ipAddrStr[64];
mCurOp->PeerAddr.ToString(ipAddrStr, sizeof(ipAddrStr));
if (networkType != kNetworkType_WiFi && networkType != kNetworkType_Thread)
{
SendStatusReport(kWeaveProfile_NetworkProvisioning, kStatusCode_UnsupportedNetworkType);
ExitNow();
}
// Make the network ids in the scan results match the ids assigned in the provisioned networks list.
for (int i = 0; i < kMaxScanResults; i++)
if (ScanResults[i].NetworkType != kNetworkType_NotSpecified)
{
ScanResults[i].NetworkId = -1;
for (int j = 0; j < kMaxProvisionedNetworks; j++)
if (ScanResults[i].NetworkType == kNetworkType_WiFi
&& ProvisionedNetworks[j].NetworkType == kNetworkType_WiFi
&& strcmp(ScanResults[i].WiFiSSID, ProvisionedNetworks[j].WiFiSSID) == 0
&& ScanResults[i].WiFiMode == ProvisionedNetworks[j].WiFiMode
&& ScanResults[i].WiFiRole == ProvisionedNetworks[j].WiFiRole
&& ScanResults[i].WiFiSecurityType == ProvisionedNetworks[j].WiFiSecurityType)
{
ScanResults[i].NetworkId = ProvisionedNetworks[j].NetworkId;
break;
}
else if (ScanResults[i].NetworkType == kNetworkType_Thread
&& ProvisionedNetworks[j].NetworkType == kNetworkType_Thread
&& strcmp(ScanResults[i].ThreadNetworkName, ProvisionedNetworks[j].ThreadNetworkName) == 0
&& ScanResults[i].ThreadExtendedPANId == ProvisionedNetworks[j].ThreadExtendedPANId)
{
ScanResults[i].NetworkId = ProvisionedNetworks[j].NetworkId;
break;
}
}
respBuf = PacketBuffer::New();
VerifyOrExit(respBuf != NULL, err = WEAVE_ERROR_NO_MEMORY);
writer.Init(respBuf);
err = NetworkInfo::EncodeList(writer, kMaxScanResults, ScanResults, (NetworkType)networkType, NetworkInfo::kEncodeFlag_All, resultCount);
SuccessOrExit(err);
err = writer.Finalize();
SuccessOrExit(err);
printf("Sending NetworkScanComplete response\n");
printf(" Network Count: %d\n", resultCount);
err = SendNetworkScanComplete(resultCount, respBuf);
respBuf = NULL;
SuccessOrExit(err);
return WEAVE_NO_ERROR;
exit:
if (respBuf != NULL)
PacketBuffer::Free(respBuf);
return err;
}
WEAVE_ERROR MockNetworkProvisioningServer::CompleteAddNetwork(PacketBuffer* networkInfoTLV)
{
WEAVE_ERROR err = WEAVE_NO_ERROR;
NetworkInfo newNetworkConfig;
NetworkInfo *targetNetworkConfig = NULL;
TLVReader reader;
reader.Init(networkInfoTLV);
err = reader.Next();
SuccessOrExit(err);
err = newNetworkConfig.Decode(reader);
SuccessOrExit(err);
printf(" Network Config:\n");
PrintNetworkInfo(newNetworkConfig, " ");
newNetworkConfig.WirelessSignalStrength = INT16_MIN;
err = ValidateNetworkConfig(newNetworkConfig);
if (err == WEAVE_ERROR_INVALID_ARGUMENT)
ExitNow(err = WEAVE_NO_ERROR);
SuccessOrExit(err);
for (int i = 0; i < kMaxProvisionedNetworks; i++)
{
NetworkInfo& curElem = ProvisionedNetworks[i];
if (curElem.NetworkType == kNetworkType_NotSpecified)
{
if (targetNetworkConfig == NULL)
targetNetworkConfig = &curElem;
continue;
}
if (newNetworkConfig.NetworkType == kNetworkType_WiFi && curElem.NetworkType == kNetworkType_WiFi
&& strcmp(curElem.WiFiSSID, newNetworkConfig.WiFiSSID) == 0
&& curElem.WiFiMode == newNetworkConfig.WiFiMode && curElem.WiFiRole == newNetworkConfig.WiFiRole
&& curElem.WiFiSecurityType == newNetworkConfig.WiFiSecurityType)
{
targetNetworkConfig = &curElem;
break;
}
if (newNetworkConfig.NetworkType == kNetworkType_Thread && curElem.NetworkType == kNetworkType_Thread
&& strcmp(curElem.ThreadNetworkName, newNetworkConfig.ThreadNetworkName) == 0
&& memcmp(curElem.ThreadExtendedPANId, newNetworkConfig.ThreadExtendedPANId, 8) == 0)
{
targetNetworkConfig = &curElem;
break;
}
}
if (targetNetworkConfig == NULL)
{
err = SendStatusReport(kWeaveProfile_NetworkProvisioning, kStatusCode_TooManyNetworks);
ExitNow();
}
if (targetNetworkConfig->NetworkType != kNetworkType_NotSpecified)
newNetworkConfig.NetworkId = targetNetworkConfig->NetworkId;
else
newNetworkConfig.NetworkId = NextNetworkId++;
newNetworkConfig.CopyTo(*targetNetworkConfig);
printf("Sending AddNetworkComplete response\n");
printf(" Network Id: %lu\n", (unsigned long)targetNetworkConfig->NetworkId);
err = SendAddNetworkComplete(targetNetworkConfig->NetworkId);
SuccessOrExit(err);
exit:
PacketBuffer::Free(networkInfoTLV);
return err;
}
WEAVE_ERROR MockNetworkProvisioningServer::CompleteUpdateNetwork(PacketBuffer* networkInfoTLV)
{
WEAVE_ERROR err = WEAVE_NO_ERROR;
NetworkInfo networkConfigUpdate, updatedNetworkConfig;
NetworkInfo *existingNetworkConfig = NULL;
TLVReader reader;
reader.Init(networkInfoTLV);
err = reader.Next();
SuccessOrExit(err);
err = networkConfigUpdate.Decode(reader);
SuccessOrExit(err);
printf(" Updated Network Config:\n");
PrintNetworkInfo(networkConfigUpdate, " ");
if (networkConfigUpdate.NetworkId == -1)
{
err = SendStatusReport(kWeaveProfile_NetworkProvisioning, kStatusCode_InvalidNetworkConfiguration);
ExitNow();
}
for (int i = 0; i < kMaxProvisionedNetworks; i++)
if (ProvisionedNetworks[i].NetworkType != kNetworkType_NotSpecified
&& ProvisionedNetworks[i].NetworkId == networkConfigUpdate.NetworkId)
{
existingNetworkConfig = &ProvisionedNetworks[i];
break;
}
if (existingNetworkConfig == NULL)
{
printf("Specified network id not found\n");
err = SendStatusReport(kWeaveProfile_NetworkProvisioning, kStatusCode_UnknownNetwork);
ExitNow();
}
err = existingNetworkConfig->CopyTo(updatedNetworkConfig);
SuccessOrExit(err);
err = networkConfigUpdate.MergeTo(updatedNetworkConfig);
SuccessOrExit(err);
err = ValidateNetworkConfig(updatedNetworkConfig);
if (err == WEAVE_ERROR_INVALID_ARGUMENT)
ExitNow(err = WEAVE_NO_ERROR);
SuccessOrExit(err);
err = updatedNetworkConfig.CopyTo(*existingNetworkConfig);
SuccessOrExit(err);
err = SendSuccessResponse();
SuccessOrExit(err);
exit:
PacketBuffer::Free(networkInfoTLV);
return err;
}
WEAVE_ERROR MockNetworkProvisioningServer::CompleteRemoveNetwork(uint32_t networkId)
{
WEAVE_ERROR err = WEAVE_NO_ERROR;
NetworkInfo *existingNetworkConfig = NULL;
for (int i = 0; i < kMaxProvisionedNetworks; i++)
if (ProvisionedNetworks[i].NetworkType != kNetworkType_NotSpecified
&& ProvisionedNetworks[i].NetworkId == networkId)
{
existingNetworkConfig = &ProvisionedNetworks[i];
break;
}
if (existingNetworkConfig == NULL)
{
printf("Specified network id not found\n");
err = SendStatusReport(kWeaveProfile_NetworkProvisioning, kStatusCode_UnknownNetwork);
ExitNow();
}
existingNetworkConfig->Clear();
err = SendSuccessResponse();
SuccessOrExit(err);
exit:
return err;
}
WEAVE_ERROR MockNetworkProvisioningServer::CompleteGetNetworks(uint8_t flags)
{
WEAVE_ERROR err = WEAVE_NO_ERROR;
PacketBuffer *respBuf = NULL;
TLVWriter writer;
uint16_t resultCount = 0;
char ipAddrStr[64];
mCurOp->PeerAddr.ToString(ipAddrStr, sizeof(ipAddrStr));
respBuf = PacketBuffer::New();
VerifyOrExit(respBuf != NULL, err = WEAVE_ERROR_NO_MEMORY);
writer.Init(respBuf);
err = NetworkInfo::EncodeList(writer, kMaxProvisionedNetworks, ProvisionedNetworks, kNetworkType_NotSpecified, flags, resultCount);
SuccessOrExit(err);
err = writer.Finalize();
SuccessOrExit(err);
printf("Sending GetNetworksComplete response\n");
printf(" Network Count: %d\n", resultCount);
err = SendGetNetworksComplete(resultCount, respBuf);
respBuf = NULL;
SuccessOrExit(err);
return WEAVE_NO_ERROR;
exit:
if (respBuf != NULL)
PacketBuffer::Free(respBuf);
return err;
}
WEAVE_ERROR MockNetworkProvisioningServer::CompleteEnableNetwork(uint32_t networkId)
{
WEAVE_ERROR err = WEAVE_NO_ERROR;
NetworkInfo *existingNetworkConfig = NULL;
for (int i = 0; i < kMaxProvisionedNetworks; i++)
if (ProvisionedNetworks[i].NetworkType != kNetworkType_NotSpecified
&& ProvisionedNetworks[i].NetworkId == networkId)
{
existingNetworkConfig = &ProvisionedNetworks[i];
break;
}
if (existingNetworkConfig == NULL)
{
printf("Specified network id not found\n");
err = SendStatusReport(kWeaveProfile_NetworkProvisioning, kStatusCode_UnknownNetwork);
ExitNow();
}
err = SendSuccessResponse();
SuccessOrExit(err);
exit:
return err;
}
WEAVE_ERROR MockNetworkProvisioningServer::CompleteDisableNetwork(uint32_t networkId)
{
WEAVE_ERROR err = WEAVE_NO_ERROR;
NetworkInfo *existingNetworkConfig = NULL;
for (int i = 0; i < kMaxProvisionedNetworks; i++)
if (ProvisionedNetworks[i].NetworkType != kNetworkType_NotSpecified
&& ProvisionedNetworks[i].NetworkId == networkId)
{
printf("Specified network id not found\n");
existingNetworkConfig = &ProvisionedNetworks[i];
break;
}
if (existingNetworkConfig == NULL)
{
err = SendStatusReport(kWeaveProfile_NetworkProvisioning, kStatusCode_UnknownNetwork);
ExitNow();
}
err = SendSuccessResponse();
SuccessOrExit(err);
exit:
return err;
}
WEAVE_ERROR MockNetworkProvisioningServer::CompleteTestConnectivity(uint32_t networkId)
{
WEAVE_ERROR err = WEAVE_NO_ERROR;
NetworkInfo *existingNetworkConfig = NULL;
for (int i = 0; i < kMaxProvisionedNetworks; i++)
if (ProvisionedNetworks[i].NetworkType != kNetworkType_NotSpecified
&& ProvisionedNetworks[i].NetworkId == networkId)
{
existingNetworkConfig = &ProvisionedNetworks[i];
break;
}
if (existingNetworkConfig == NULL)
{
printf("Specified network id not found\n");
err = SendStatusReport(kWeaveProfile_NetworkProvisioning, kStatusCode_UnknownNetwork);
ExitNow();
}
err = SendSuccessResponse();
SuccessOrExit(err);
exit:
return err;
}
WEAVE_ERROR MockNetworkProvisioningServer::CompleteSetRendezvousMode(uint16_t rendezvousMode)
{
WEAVE_ERROR err = WEAVE_NO_ERROR;
{
char ipAddrStr[64];
mCurOp->PeerAddr.ToString(ipAddrStr, sizeof(ipAddrStr));
printf("SetRendezvousMode request received from node %" PRIX64 " (%s)\n", mCurOp->PeerNodeId, ipAddrStr);
printf(" Rendezvous Mode: %u\n", rendezvousMode);
}
err = SendSuccessResponse();
SuccessOrExit(err);
exit:
return err;
}
void MockNetworkProvisioningServer::PrintNetworkInfo(NetworkInfo& netInfo, const char *prefix)
{
printf("%sNetwork Type: %d\n", prefix, (int)netInfo.NetworkType);
if (netInfo.NetworkId != -1)
printf("%sNetwork Id: %ld\n", prefix, (long)netInfo.NetworkId);
if (netInfo.WiFiSSID != NULL)
printf("%sWiFi SSID: %s\n", prefix, netInfo.WiFiSSID);
if (netInfo.WiFiMode != -1)
printf("%sWiFi Mode: %d\n", prefix, (int)netInfo.WiFiMode);
if (netInfo.WiFiRole != -1)
printf("%sWiFi Role: %d\n", prefix, (int)netInfo.WiFiRole);
if (netInfo.WiFiSecurityType != -1)
printf("%sWiFi Security Type: %d\n", prefix, (int)netInfo.WiFiSecurityType);
if (netInfo.WiFiKey != NULL)
{
char keyBuf[256];
uint32_t i = (netInfo.WiFiKeyLen < sizeof(keyBuf)) ? netInfo.WiFiKeyLen : sizeof(keyBuf) - 1;
memcpy(keyBuf, netInfo.WiFiKey, i);
keyBuf[i] = 0;
printf("%sWiFi Key: %s\n", prefix, keyBuf);
}
if (netInfo.ThreadNetworkName != NULL)
printf("%sThread Network Name: %s\n", prefix, netInfo.ThreadNetworkName);
if (netInfo.ThreadExtendedPANId != NULL)
{
printf("%sThread Extended PAN Id: ", prefix);
for (int i = 0; i < 8; i++)
printf("%02X", netInfo.ThreadExtendedPANId[i]);
printf("\n");
}
if (netInfo.ThreadNetworkKey != NULL)
{
printf("%sThread Network Key: ", prefix);
for (uint32_t i = 0; i < netInfo.ThreadNetworkKeyLen; i++)
printf("%02X", netInfo.ThreadNetworkKey[i]);
printf("\n");
}
if (netInfo.WirelessSignalStrength != INT16_MIN)
printf("%sWireless Signal Strength: %d\n", prefix, (int)netInfo.WirelessSignalStrength);
}
WEAVE_ERROR MockNetworkProvisioningServer::SendStatusReport(uint32_t statusProfileId, uint16_t statusCode, WEAVE_ERROR sysError)
{
if (statusProfileId == kWeaveProfile_Common && statusCode == Common::kStatus_Success)
printf("Sending StatusReport: Success\n");
else if (sysError == WEAVE_NO_ERROR)
printf("Sending StatusReport: Status code = %u, Status profile = %lu\n", statusCode, (unsigned long)statusProfileId);
else
printf("Sending StatusReport: Status code = %u, Status profile = %lu, System error = %d\n", statusCode, (unsigned long)statusProfileId, sysError);
return this->NetworkProvisioningServer::SendStatusReport(statusProfileId, statusCode, sysError);
}