Skip to content

Commit

Permalink
[Tizen] Eth driver for network commissioning cluster (#21151)
Browse files Browse the repository at this point in the history
* [Tizen] Eth driver for network commissioning cluster

* Static asserts for WiFi ssid and credentials len
  • Loading branch information
arkq authored and pull[bot] committed Sep 15, 2023
1 parent 10b99ba commit c5db447
Show file tree
Hide file tree
Showing 8 changed files with 259 additions and 10 deletions.
8 changes: 7 additions & 1 deletion examples/all-clusters-app/tizen/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,30 @@
#include <app/ConcreteAttributePath.h>
#include <app/clusters/network-commissioning/network-commissioning.h>
#include <app/util/af.h>
#include <platform/Tizen/NetworkCommissioningDriver.h>

#include <TizenServiceAppMain.h>
#include <binding-handler.h>

using namespace chip;
using namespace chip::app;
using namespace chip::app::Clusters;
using namespace chip::DeviceLayer;

// Network commissioning
namespace {
constexpr EndpointId kNetworkCommissioningEndpointMain = 0;
constexpr EndpointId kNetworkCommissioningEndpointSecondary = 0xFFFE;

NetworkCommissioning::TizenEthernetDriver sEthernetDriver;
Clusters::NetworkCommissioning::Instance sEthernetNetworkCommissioningInstance(kNetworkCommissioningEndpointMain, &sEthernetDriver);
} // namespace

void ApplicationInit()
{
// Enable secondary endpoint only when we need it.
emberAfEndpointEnableDisable(kNetworkCommissioningEndpointSecondary, false);

sEthernetNetworkCommissioningInstance.Init();
}

int main(int argc, char * argv[])
Expand Down
8 changes: 7 additions & 1 deletion examples/all-clusters-minimal-app/tizen/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,30 @@
#include <app/ConcreteAttributePath.h>
#include <app/clusters/network-commissioning/network-commissioning.h>
#include <app/util/af.h>
#include <platform/Tizen/NetworkCommissioningDriver.h>

#include <TizenServiceAppMain.h>
#include <binding-handler.h>

using namespace chip;
using namespace chip::app;
using namespace chip::app::Clusters;
using namespace chip::DeviceLayer;

// Network commissioning
namespace {
constexpr EndpointId kNetworkCommissioningEndpointMain = 0;
constexpr EndpointId kNetworkCommissioningEndpointSecondary = 0xFFFE;

NetworkCommissioning::TizenEthernetDriver sEthernetDriver;
Clusters::NetworkCommissioning::Instance sEthernetNetworkCommissioningInstance(kNetworkCommissioningEndpointMain, &sEthernetDriver);
} // namespace

void ApplicationInit()
{
// Enable secondary endpoint only when we need it.
emberAfEndpointEnableDisable(kNetworkCommissioningEndpointSecondary, false);

sEthernetNetworkCommissioningInstance.Init();
}

int main(int argc, char * argv[])
Expand Down
37 changes: 29 additions & 8 deletions src/platform/Tizen/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ import("${build_root}/config/linux/pkg_config.gni")

import("${chip_root}/src/platform/device.gni")

if (chip_enable_openthread) {
import("//build_overrides/openthread.gni")
import("//build_overrides/ot_br_posix.gni")
}

assert(chip_device_platform == "tizen")

static_library("Tizen") {
Expand All @@ -29,9 +34,6 @@ static_library("Tizen") {
"../SingletonConfigurationManager.cpp",
"AppPreference.cpp",
"AppPreference.h",
"BLEManagerImpl.cpp",
"BLEManagerImpl.h",
"BlePlatformConfig.h",
"CHIPDevicePlatformConfig.h",
"CHIPDevicePlatformEvent.h",
"CHIPPlatformConfig.h",
Expand All @@ -41,6 +43,8 @@ static_library("Tizen") {
"ConfigurationManagerImpl.h",
"ConnectivityManagerImpl.cpp",
"ConnectivityManagerImpl.h",
"ConnectivityUtils.cpp",
"ConnectivityUtils.h",
"DeviceInstanceInfoProviderImpl.cpp",
"DeviceInstanceInfoProviderImpl.h",
"DeviceNetworkProvisioningDelegateImpl.cpp",
Expand All @@ -54,16 +58,13 @@ static_library("Tizen") {
"MainLoop.cpp",
"MainLoop.h",
"NetworkCommissioningDriver.h",
"NetworkCommissioningThreadDriver.cpp",
"NetworkCommissioningWiFiDriver.cpp",
"NetworkCommissioningEthernetDriver.cpp",
"PlatformManagerImpl.cpp",
"PlatformManagerImpl.h",
"PosixConfig.cpp",
"PosixConfig.h",
"SystemPlatformConfig.h",
"SystemTimeSupport.cpp",
"WiFiManager.cpp",
"WiFiManager.h",
]

deps = [ "${chip_root}/src/setup_payload" ]
Expand All @@ -76,15 +77,35 @@ static_library("Tizen") {
public_configs = []

if (chip_mdns == "platform") {
sources += [ "DnssdImpl.cpp" ]
sources += [
"DnssdImpl.cpp",
"DnssdImpl.h",
]

deps += [ "${chip_root}/src/lib/dnssd:platform_header" ]
}

if (chip_enable_ble) {
sources += [
"BLEManagerImpl.cpp",
"BLEManagerImpl.h",
"BlePlatformConfig.h",
]
}

if (chip_enable_openthread) {
sources += [
"NetworkCommissioningThreadDriver.cpp",
"ThreadStackManagerImpl.cpp",
"ThreadStackManagerImpl.h",
]
}

if (chip_enable_wifi) {
sources += [
"NetworkCommissioningWiFiDriver.cpp",
"WiFiManager.cpp",
"WiFiManager.h",
]
}
}
81 changes: 81 additions & 0 deletions src/platform/Tizen/ConnectivityUtils.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
*
* Copyright (c) 2021 Project CHIP Authors
*
* 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.
*/

#include <platform/Tizen/ConnectivityUtils.h>
#include <platform/internal/CHIPDeviceLayerInternal.h>

// XXX: This is a workaround for a bug in the Tizen SDK header files. It is not
// possible to include both <net/if.h> and <linux/if.h> at the same time.
// This will cause warning that struct ifmap is redefined. On Linux, this
// is not a problem, because in <linux/if.h> the struct is guarded with
// ifdef. To prevent this, we will define _LINUX_IF_H, so the <linux/if.h>
// will not be included.
#define _LINUX_IF_H

#include <linux/ethtool.h>
#include <linux/sockios.h>
#include <linux/wireless.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>

using namespace ::chip::app::Clusters::GeneralDiagnostics;

namespace chip {
namespace DeviceLayer {
namespace Internal {

InterfaceType ConnectivityUtils::GetInterfaceConnectionType(const char * ifname)
{
InterfaceType ret = InterfaceType::EMBER_ZCL_INTERFACE_TYPE_UNSPECIFIED;
int sock = -1;

if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
ChipLogError(DeviceLayer, "Failed to open socket");
return ret;
}

// Test wireless extensions for CONNECTION_WIFI
struct iwreq pwrq = {};
strncpy(pwrq.ifr_name, ifname, IFNAMSIZ - 1);

if (ioctl(sock, SIOCGIWNAME, &pwrq) != -1)
{
ret = InterfaceType::EMBER_ZCL_INTERFACE_TYPE_WI_FI;
}
else if ((strncmp(ifname, "en", 2) == 0) || (strncmp(ifname, "eth", 3) == 0))
{
struct ethtool_cmd ecmd = {};
ecmd.cmd = ETHTOOL_GSET;
struct ifreq ifr = {};
ifr.ifr_data = reinterpret_cast<char *>(&ecmd);
strncpy(ifr.ifr_name, ifname, IFNAMSIZ - 1);

if (ioctl(sock, SIOCETHTOOL, &ifr) != -1)
ret = InterfaceType::EMBER_ZCL_INTERFACE_TYPE_ETHERNET;
}

close(sock);

return ret;
}

} // namespace Internal
} // namespace DeviceLayer
} // namespace chip
35 changes: 35 additions & 0 deletions src/platform/Tizen/ConnectivityUtils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
*
* Copyright (c) 2021 Project CHIP Authors
*
* 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.
*/

#pragma once

#include <platform/DiagnosticDataProvider.h>
#include <platform/internal/CHIPDeviceLayerInternal.h>

namespace chip {
namespace DeviceLayer {
namespace Internal {

class ConnectivityUtils
{
public:
static app::Clusters::GeneralDiagnostics::InterfaceType GetInterfaceConnectionType(const char * ifname);
};

} // namespace Internal
} // namespace DeviceLayer
} // namespace chip
23 changes: 23 additions & 0 deletions src/platform/Tizen/NetworkCommissioningDriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#pragma once

#include <platform/NetworkCommissioning.h>
#include <string>
#include <vector>

namespace chip {
Expand Down Expand Up @@ -125,6 +126,28 @@ class TizenThreadDriver final : public ThreadDriver

#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD

class TizenEthernetDriver final : public EthernetDriver
{
public:
class EthernetNetworkIterator final : public NetworkIterator
{
public:
EthernetNetworkIterator(TizenEthernetDriver * aDriver);
~EthernetNetworkIterator() override = default;
size_t Count() override { return mInterfaces.size(); }
bool Next(Network & item) override;
void Release() override { delete this; }

private:
TizenEthernetDriver * mDriver;
std::vector<std::string> mInterfaces;
size_t mInterfacesIdx = 0;
};

uint8_t GetMaxNetworks() override { return 1; };
NetworkIterator * GetNetworks() override { return new EthernetNetworkIterator(this); };
};

} // namespace NetworkCommissioning
} // namespace DeviceLayer
} // namespace chip
71 changes: 71 additions & 0 deletions src/platform/Tizen/NetworkCommissioningEthernetDriver.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
*
* Copyright (c) 2021 Project CHIP Authors
*
* 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.
*/

#include <lib/support/SafePointerCast.h>
#include <platform/CHIPDeviceLayer.h>
#include <platform/Tizen/ConnectivityUtils.h>
#include <platform/Tizen/NetworkCommissioningDriver.h>

#include <cerrno>
#include <ifaddrs.h>
#include <limits>
#include <string>
#include <vector>

using namespace chip::app::Clusters::GeneralDiagnostics;
using namespace chip::DeviceLayer::Internal;

namespace chip {
namespace DeviceLayer {
namespace NetworkCommissioning {

TizenEthernetDriver::EthernetNetworkIterator::EthernetNetworkIterator(TizenEthernetDriver * aDriver) : mDriver(aDriver)
{
struct ifaddrs * ifaddr = nullptr;
VerifyOrReturn(getifaddrs(&ifaddr) == 0, ChipLogError(DeviceLayer, "Failed to get network interfaces: %s", strerror(errno)));

for (const auto * ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next)
{
if (ConnectivityUtils::GetInterfaceConnectionType(ifa->ifa_name) == InterfaceType::EMBER_ZCL_INTERFACE_TYPE_ETHERNET)
{
mInterfaces.push_back(ifa->ifa_name);
if (mInterfaces.size() == mDriver->GetMaxNetworks())
{
break;
}
}
}

freeifaddrs(ifaddr);
}

bool TizenEthernetDriver::EthernetNetworkIterator::Next(Network & item)
{
VerifyOrReturnValue(mInterfacesIdx < mInterfaces.size(), false);

const auto & iface = mInterfaces[mInterfacesIdx++];
item.networkIDLen = std::min(iface.size(), kMaxNetworkIDLen);
memcpy(item.networkID, iface.c_str(), item.networkIDLen);
item.connected = true;

mInterfacesIdx++;
return true;
}

} // namespace NetworkCommissioning
} // namespace DeviceLayer
} // namespace chip
6 changes: 6 additions & 0 deletions src/platform/Tizen/NetworkCommissioningWiFiDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@ Status TizenWiFiDriver::AddOrUpdateNetwork(ByteSpan ssid, ByteSpan credentials,
outDebugText.reduce_size(0);
outNetworkIndex = 0;
VerifyOrReturnError(mStagingNetwork.ssidLen == 0 || NetworkMatch(mStagingNetwork, ssid), Status::kBoundsExceeded);

static_assert(sizeof(WiFiNetwork::ssid) <= std::numeric_limits<decltype(WiFiNetwork::ssidLen)>::max(),
"Max length of WiFi ssid exceeds the limit of ssidLen field");
static_assert(sizeof(WiFiNetwork::credentials) <= std::numeric_limits<decltype(WiFiNetwork::credentialsLen)>::max(),
"Max length of WiFi credentials exceeds the limit of credentialsLen field");

VerifyOrReturnError(credentials.size() <= sizeof(mStagingNetwork.credentials), Status::kOutOfRange);
VerifyOrReturnError(ssid.size() <= sizeof(mStagingNetwork.ssid), Status::kOutOfRange);

Expand Down

0 comments on commit c5db447

Please sign in to comment.