Skip to content

Commit

Permalink
use linked list and disconnect driver when no connected network config
Browse files Browse the repository at this point in the history
  • Loading branch information
DejinChen committed Aug 30, 2024
1 parent 9c1de6f commit 4749898
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 16 deletions.
43 changes: 36 additions & 7 deletions src/app/clusters/network-commissioning/network-commissioning.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1152,28 +1152,57 @@ void Instance::HandleQueryIdentity(HandlerContext & ctx, const Commands::QueryId
}
#endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI_PDC

Instance * Instance::NetworkRecord[CHIP_MAX_NETWORK_TYPES];
Instance::InstanceRecord * Instance::sInstanceRecord = nullptr;

void Instance::RecordNetwork(Instance * currentNetwork)
{
for (size_t i = 0; i < CHIP_MAX_NETWORK_TYPES; ++i)
InstanceRecord * curr = sInstanceRecord;
while (curr)
{
if (NetworkRecord[i] == nullptr)
if (curr->mInstance == currentNetwork)
{
NetworkRecord[i] = currentNetwork;
return;
}
curr = curr->next;
}

InstanceRecord * newInstanceRecord = reinterpret_cast<InstanceRecord *>(Platform::MemoryAlloc(sizeof(InstanceRecord)));
newInstanceRecord->mInstance = currentNetwork;
newInstanceRecord->next = sInstanceRecord;
sInstanceRecord = newInstanceRecord;
}

void Instance::DisconnectOtherNetworks(Instance * currentNetwork)
{
for (size_t i = 0; i < CHIP_MAX_NETWORK_TYPES; ++i)
InstanceRecord * curr = sInstanceRecord;
while (curr)
{
if (NetworkRecord[i] != nullptr && NetworkRecord[i] != currentNetwork && NetworkRecord[i]->mpWirelessDriver)
if (curr->mInstance != currentNetwork && curr->mInstance->mpWirelessDriver)
{
NetworkRecord[i]->mpWirelessDriver->DisconnectNetwork();
uint8_t networkNo = 0;
uint8_t maxNetworks = curr->mInstance->mpBaseDriver->GetMaxNetworks();
bool haveConnectedNetwork = false;
EnumerateAndRelease(curr->mInstance->mpBaseDriver->GetNetworks(), [&](const Network & network) {
if (network.connected)
{
haveConnectedNetwork = true;
return Loop::Break;
}
++networkNo;
return (networkNo == maxNetworks) ? Loop::Break : Loop::Continue;
});

if (!haveConnectedNetwork)
{
/* It's different to check the media driver connection state here.
* Check the `Connected` flag in `NetworkInfoStruct` in stead, if not set,
* exec `DisconnectDriver` for driver. However, the physical media connection
* may not necessarily exist in this case, such as after initialization.
*/
curr->mInstance->mpWirelessDriver->DisconnectDriver();
}
}
curr = curr->next;
}
}

Expand Down
37 changes: 30 additions & 7 deletions src/app/clusters/network-commissioning/network-commissioning.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ namespace app {
namespace Clusters {
namespace NetworkCommissioning {

#define CHIP_MAX_NETWORK_TYPES 3

// TODO: Use macro to disable some wifi or thread
class Instance : public CommandHandlerInterface,
public AttributeAccessInterface,
Expand Down Expand Up @@ -83,12 +81,19 @@ class Instance : public CommandHandlerInterface,
void SendNonConcurrentConnectNetworkResponse();
#endif

class InstanceRecord
{
public:
Instance * mInstance;
InstanceRecord * next;
};

// Array for recording NetworkCommissioningInstance.
static Instance * NetworkRecord[CHIP_MAX_NETWORK_TYPES];
static InstanceRecord * sInstanceRecord;
// Record current network.
static void RecordNetwork(Instance *currentNetwork);
static void RecordNetwork(Instance * currentNetwork);
// Disconnect networks (if connected) in the array other than the current network.
static void DisconnectOtherNetworks(Instance *currentNetwork);
static void DisconnectOtherNetworks(Instance * currentNetwork);

EndpointId mEndpointId = kInvalidEndpointId;
const BitFlags<Feature> mFeatureFlags;
Expand Down Expand Up @@ -142,8 +147,26 @@ class Instance : public CommandHandlerInterface,
Instance(EndpointId aEndpointId, DeviceLayer::NetworkCommissioning::WiFiDriver * apDelegate);
Instance(EndpointId aEndpointId, DeviceLayer::NetworkCommissioning::ThreadDriver * apDelegate);
Instance(EndpointId aEndpointId, DeviceLayer::NetworkCommissioning::EthernetDriver * apDelegate);
virtual ~Instance() = default;
};
virtual ~Instance()
{
InstanceRecord * prev = nullptr;
InstanceRecord * curr = sInstanceRecord;
while (curr && curr->mInstance != this)
{
prev = curr;
curr = curr->next;
}
if (!prev)
{
sInstanceRecord = curr->next;
}
else
{
prev->next = curr->next;
}
Platform::MemoryFree(curr);
}
}; // namespace NetworkCommissioning

// NetworkDriver for the devices that don't have / don't need a real network driver.
class NullNetworkDriver : public DeviceLayer::NetworkCommissioning::EthernetDriver
Expand Down
4 changes: 2 additions & 2 deletions src/include/platform/NetworkCommissioning.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,9 +219,9 @@ class WirelessDriver : public Internal::BaseDriver
virtual CHIP_ERROR RevertConfiguration() = 0;

/**
* @brief Disconnects network if it has connected.
* @brief Disconnects driver, but maybe it is not connected on media driver.
*/
virtual CHIP_ERROR DisconnectNetwork() { return CHIP_NO_ERROR; }
virtual CHIP_ERROR DisconnectDriver() { return CHIP_NO_ERROR; }

virtual uint8_t GetScanNetworkTimeoutSeconds() = 0;
virtual uint8_t GetConnectNetworkTimeoutSeconds() = 0;
Expand Down

0 comments on commit 4749898

Please sign in to comment.