diff --git a/definition/NetworkManager.json b/definition/NetworkManager.json
index fbde9789..b43c4c81 100644
--- a/definition/NetworkManager.json
+++ b/definition/NetworkManager.json
@@ -1299,9 +1299,35 @@
"success"
]
}
+ },
+ "SetHostname": {
+ "summary": "To configure a custom DHCP hostname instead of the default (which is typically the device name).",
+ "params": {
+ "type": "object",
+ "properties": {
+ "hostname": {
+ "summary": "The hostname to be set for the device (maximum 32 characters)",
+ "type": "string",
+ "example": "RDK-Device"
+ }
+ },
+ "required": [
+ "hostname"
+ ]
+ },
+ "result": {
+ "type": "object",
+ "properties": {
+ "success": {
+ "$ref": "#/definitions/success"
+ }
+ },
+ "required": [
+ "success"
+ ]
+ }
}
},
-
"events": {
"onInterfaceStateChange":{
"summary": "Triggered when an interface state is changed. The possible states are \n* 'INTERFACE_ADDED' \n* 'INTERFACE_LINK_UP' \n* 'INTERFACE_LINK_DOWN' \n* 'INTERFACE_ACQUIRING_IP' \n* 'INTERFACE_REMOVED' \n* 'INTERFACE_DISABLED' \n",
diff --git a/docs/NetworkManagerPlugin.md b/docs/NetworkManagerPlugin.md
index 93137805..4dcf7807 100644
--- a/docs/NetworkManagerPlugin.md
+++ b/docs/NetworkManagerPlugin.md
@@ -102,6 +102,7 @@ NetworkManager interface methods:
| [GetWiFiSignalQuality](#method.GetWiFiSignalQuality) | Get WiFi signal quality of currently connected SSID |
| [GetSupportedSecurityModes](#method.GetSupportedSecurityModes) | Returns the Wifi security modes that the device supports |
| [GetWifiState](#method.GetWifiState) | Returns the current Wifi State |
+| [SetHostname](#method.SetHostname) | To configure a custom DHCP hostname instead of the default (which is typically the device name). |
## *SetLogLevel [method](#head.Methods)*
@@ -1667,6 +1668,52 @@ This method takes no parameters.
}
```
+
+## *SetHostname [method](#head.Methods)*
+
+To configure a custom DHCP hostname instead of the default (which is typically the device name), note that the change will only take effect after a device reboot, creating a new Wi-Fi connection, reactivation of existing NetworkManager connection, or renewal of the DHCP lease.
+
+### Parameters
+
+| Name | Type | Description |
+| :-------- | :-------- | :-------- |
+| params | object | |
+| params.hostname | string | The hostname to be set for the device (maximum 32 characters) |
+
+### Result
+
+| Name | Type | Description |
+| :-------- | :-------- | :-------- |
+| result | object | |
+| result.success | boolean | Whether the request succeeded |
+
+### Example
+
+#### Request
+
+```json
+{
+ "jsonrpc": "2.0",
+ "id": 42,
+ "method": "org.rdk.NetworkManager.1.SetHostname",
+ "params": {
+ "hostname": "RDK-Device"
+ }
+}
+```
+
+#### Response
+
+```json
+{
+ "jsonrpc": "2.0",
+ "id": 42,
+ "result": {
+ "success": true
+ }
+}
+```
+
# Notifications
diff --git a/interface/INetworkManager.h b/interface/INetworkManager.h
index 65c982a2..edf369ff 100644
--- a/interface/INetworkManager.h
+++ b/interface/INetworkManager.h
@@ -233,6 +233,8 @@ namespace WPEFramework
/* @brief Request for trace get the response in as event. The GUID used in the request will be returned in the event. */
virtual uint32_t Trace (const string ipversion /* @in */, const string endpoint /* @in */, const uint32_t nqueries /* @in */, const string guid /* @in */, string& response /* @out */) = 0;
+ /* @brief Set the dhcp hostname */
+ virtual uint32_t SetHostname(const string& hostname /* @in */) = 0;
// WiFi Specific Methods
/* @brief Initiate a WIFI Scan; This is Async method and returns the scan results as Event */
diff --git a/plugin/NetworkManager.h b/plugin/NetworkManager.h
index 98007e8c..1abce8d0 100644
--- a/plugin/NetworkManager.h
+++ b/plugin/NetworkManager.h
@@ -250,6 +250,7 @@ namespace WPEFramework
uint32_t GetPublicIP(const JsonObject& parameters, JsonObject& response);
uint32_t Ping(const JsonObject& parameters, JsonObject& response);
uint32_t Trace(const JsonObject& parameters, JsonObject& response);
+ uint32_t SetHostname (const JsonObject& parameters, JsonObject& response);
uint32_t StartWiFiScan(const JsonObject& parameters, JsonObject& response);
uint32_t StopWiFiScan(const JsonObject& parameters, JsonObject& response);
uint32_t GetKnownSSIDs(const JsonObject& parameters, JsonObject& response);
diff --git a/plugin/NetworkManagerImplementation.h b/plugin/NetworkManagerImplementation.h
index d6077e8d..aff37e44 100644
--- a/plugin/NetworkManagerImplementation.h
+++ b/plugin/NetworkManagerImplementation.h
@@ -245,6 +245,9 @@ namespace WPEFramework
uint32_t GetSupportedSecurityModes(ISecurityModeIterator*& security /* @out */) const override;
+ /* @brief Set the dhcp hostname */
+ uint32_t SetHostname(const string& hostname /* @in */) override;
+
/* @brief Set the network manager plugin log level */
uint32_t SetLogLevel(const Logging& level /* @in */) override;
uint32_t GetLogLevel(Logging& level /* @out */) override;
diff --git a/plugin/NetworkManagerJsonRpc.cpp b/plugin/NetworkManagerJsonRpc.cpp
index 07a4fc30..5ac09c56 100644
--- a/plugin/NetworkManagerJsonRpc.cpp
+++ b/plugin/NetworkManagerJsonRpc.cpp
@@ -69,6 +69,7 @@ namespace WPEFramework
Register("GetPublicIP", &NetworkManager::GetPublicIP, this);
Register("Ping", &NetworkManager::Ping, this);
Register("Trace", &NetworkManager::Trace, this);
+ Register("SetHostname", &NetworkManager::SetHostname, this);
Register("StartWiFiScan", &NetworkManager::StartWiFiScan, this);
Register("StopWiFiScan", &NetworkManager::StopWiFiScan, this);
Register("GetKnownSSIDs", &NetworkManager::GetKnownSSIDs, this);
@@ -105,6 +106,7 @@ namespace WPEFramework
Unregister("GetPublicIP");
Unregister("Ping");
Unregister("Trace");
+ Unregister("SetHostname");
Unregister("StartWiFiScan");
Unregister("StopWiFiScan");
Unregister("GetKnownSSIDs");
@@ -608,6 +610,29 @@ namespace WPEFramework
returnJson(rc);
}
+ uint32_t NetworkManager::SetHostname (const JsonObject& parameters, JsonObject& response)
+ {
+ LOG_INPARAM();
+ uint32_t rc = Core::ERROR_GENERAL;
+ string hostname{};
+
+ if (parameters.HasLabel("hostname") && !parameters["hostname"].String().empty())
+ {
+ hostname = parameters["hostname"].String();
+ if (_networkManager)
+ rc = _networkManager->SetHostname(hostname);
+ else
+ rc = Core::ERROR_UNAVAILABLE;
+ }
+ else
+ {
+ NMLOG_ERROR("Invalid hostname length: %zu", hostname.length());
+ rc = Core::ERROR_BAD_REQUEST;
+ }
+
+ returnJson(rc);
+ }
+
uint32_t NetworkManager::StartWiFiScan(const JsonObject& parameters, JsonObject& response)
{
LOG_INPARAM();
diff --git a/plugin/gnome/NetworkManagerGnomeProxy.cpp b/plugin/gnome/NetworkManagerGnomeProxy.cpp
index 0a48feb3..1431fdc2 100644
--- a/plugin/gnome/NetworkManagerGnomeProxy.cpp
+++ b/plugin/gnome/NetworkManagerGnomeProxy.cpp
@@ -64,6 +64,191 @@ namespace WPEFramework
return deviceState;
}
+ static bool setHostname(NMConnection *connection, const std::string& hostname)
+ {
+ GError *error = NULL;
+ NMSettingIPConfig *sIPv4 = NULL;
+ NMSettingIPConfig *sIPv6 = NULL;
+ bool needChange = false;
+
+ if(connection == NULL) {
+ NMLOG_ERROR("Connection is NULL");
+ return false;
+ }
+
+ sIPv4 = nm_connection_get_setting_ip4_config(connection);
+ if (sIPv4) {
+ const char* existingHostname = nm_setting_ip_config_get_dhcp_hostname(sIPv4);
+ gboolean sendHostname = nm_setting_ip_config_get_dhcp_send_hostname(sIPv4);
+
+ if (!sendHostname || !existingHostname || hostname != existingHostname) {
+ needChange = true;
+ }
+ }
+ else
+ needChange = true;
+
+ sIPv6 = nm_connection_get_setting_ip6_config(connection);
+ if (sIPv6) {
+ const char* existingHostname = nm_setting_ip_config_get_dhcp_hostname(sIPv6);
+ gboolean sendHostname = nm_setting_ip_config_get_dhcp_send_hostname(sIPv6);
+
+ if (!sendHostname || !existingHostname || hostname != existingHostname) {
+ needChange = true;
+ }
+ }
+ else
+ needChange = true;
+
+ if (!needChange) {
+ NMLOG_DEBUG("Hostname already set to '%s', no changes needed", hostname.c_str());
+ return true;
+ }
+
+ NMLOG_DEBUG("Setting hostname to '%s' for connection '%s'", hostname.c_str(), nm_connection_get_id(connection));
+
+ if (!sIPv4) {
+ sIPv4 = NM_SETTING_IP_CONFIG(nm_setting_ip4_config_new());
+ nm_connection_add_setting(connection, NM_SETTING(sIPv4));
+ }
+ g_object_set(sIPv4,
+ NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, hostname.c_str(),
+ NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, TRUE,
+ NULL);
+
+ if (!sIPv6) {
+ sIPv6 = NM_SETTING_IP_CONFIG(nm_setting_ip6_config_new());
+ nm_connection_add_setting(connection, NM_SETTING(sIPv6));
+ }
+ g_object_set(sIPv6,
+ NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, hostname.c_str(),
+ NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, TRUE,
+ NULL);
+
+ nm_remote_connection_commit_changes(NM_REMOTE_CONNECTION(connection), TRUE, NULL, &error);
+ if(error) {
+ NMLOG_ERROR("Failed to commit changes: %s", error->message);
+ g_error_free(error);
+ return false;
+ }
+
+ return true;
+ }
+
+ static bool modifyDefaultConnConfig(NMClient *client)
+ {
+ GError *error = NULL;
+ const GPtrArray *connections = NULL;
+ NMConnection *connection = NULL;
+ std::string hostname{};
+
+ if (client == nullptr) {
+ NMLOG_ERROR("NMClient is NULL");
+ return false;
+ }
+
+ // read persistent hostname if exist
+ if(!nmUtils::readPersistentHostname(hostname))
+ {
+ hostname = nmUtils::deviceHostname(); // default hostname as device name
+ }
+
+ connections = nm_client_get_connections(client);
+ if (connections == NULL || connections->len == 0) {
+ NMLOG_ERROR("Could not get nm connections");
+ return false;
+ }
+
+ for (uint32_t i = 0; i < connections->len; i++)
+ {
+ connection = NM_CONNECTION(connections->pdata[i]);
+ if(connection == NULL)
+ {
+ NMLOG_ERROR("Connection at index %d is NULL", i);
+ continue;
+ }
+
+ const char *iface = nm_connection_get_interface_name(connection);
+ if(!iface)
+ {
+ NMLOG_WARNING("Failed to get connection interface name !");
+ continue;
+ }
+
+ std::string interface = iface;
+ if(interface != nmUtils::ethIface() && interface != nmUtils::wlanIface()) {
+ NMLOG_DEBUG("Skipping non-ethernet/wifi connection type: %s", interface.c_str());
+ continue;
+ }
+
+ if(!setHostname(connection, hostname)) {
+ NMLOG_WARNING("Failed to set hostname for connection at index %d", i);
+ }
+ }
+
+ return true;
+ }
+
+ /* @brief Set the dhcp hostname */
+ uint32_t NetworkManagerImplementation::SetHostname(const string& hostname /* @in */)
+ {
+ const GPtrArray *connections = NULL;
+ NMConnection *connection = NULL;
+
+ if (client == nullptr) {
+ NMLOG_ERROR("NMClient is NULL");
+ return Core::ERROR_GENERAL;
+ }
+
+ if(hostname.length() < 1 || hostname.length() > 32)
+ {
+ NMLOG_ERROR("Invalid hostname length: %zu", hostname.length());
+ return Core::ERROR_BAD_REQUEST;
+ }
+
+ connections = nm_client_get_connections(client);
+ if (connections == NULL || connections->len == 0)
+ {
+ NMLOG_ERROR("Could not get nm connections");
+ return Core::ERROR_GENERAL;
+ }
+
+ NMLOG_INFO("Setting DHCP hostname to %s", hostname.c_str());
+
+ for (uint32_t i = 0; i < connections->len; i++)
+ {
+ connection = NM_CONNECTION(connections->pdata[i]);
+ if(connection != NULL)
+ {
+ const char *iface = nm_connection_get_interface_name(connection);
+ if(!iface)
+ {
+ NMLOG_WARNING("Failed to get connection interface name !");
+ continue;
+ }
+
+ std::string interface = iface;
+ if(interface != nmUtils::ethIface() && interface != nmUtils::wlanIface()) {
+ NMLOG_DEBUG("Skipping non-ethernet/wifi connection type: %s", interface.c_str());
+ continue;
+ }
+
+ if(!setHostname(connection, hostname))
+ {
+ NMLOG_ERROR("Failed to set hostname for connection at index %d", i);
+ return Core::ERROR_GENERAL;
+ }
+ }
+ else
+ NMLOG_ERROR("Connection at index %d is NULL", i);
+ }
+
+ // Write the hostname to persistent storage
+ nmUtils::writePersistentHostname(hostname);
+
+ return Core::ERROR_NONE;
+ }
+
void NetworkManagerImplementation::platform_logging(const NetworkManagerLogger::LogLevel& level)
{
/* set networkmanager daemon log level based on current plugin log level */
@@ -76,7 +261,7 @@ namespace WPEFramework
{
::_instance = this;
GError *error = NULL;
-
+
// initialize the NMClient object
client = nm_client_new(NULL, &error);
if (client == NULL) {
@@ -87,7 +272,8 @@ namespace WPEFramework
return;
}
- nmUtils::getInterfacesName(); // get interface name form '/etc/device.proprties'
+ nmUtils::getDeviceProperties(); // get interface name form '/etc/device.proprties'
+ modifyDefaultConnConfig(client);
NMDeviceState ethState = ifaceState(client, nmUtils::ethIface());
if(ethState > NM_DEVICE_STATE_DISCONNECTED && ethState < NM_DEVICE_STATE_DEACTIVATING)
m_defaultInterface = nmUtils::ethIface();
diff --git a/plugin/gnome/NetworkManagerGnomeUtils.cpp b/plugin/gnome/NetworkManagerGnomeUtils.cpp
index 51aca0a2..3910b6c3 100644
--- a/plugin/gnome/NetworkManagerGnomeUtils.cpp
+++ b/plugin/gnome/NetworkManagerGnomeUtils.cpp
@@ -37,9 +37,11 @@ namespace WPEFramework
{
static std::string m_ethifname = "eth0";
static std::string m_wlanifname = "wlan0";
+ static std::string m_deviceHostname = "rdk-device"; // Device name can be empty if not set in /etc/device.properties
const char* nmUtils::wlanIface() {return m_wlanifname.c_str();}
const char* nmUtils::ethIface() {return m_ethifname.c_str();}
+ const char* nmUtils::deviceHostname() {return m_deviceHostname.c_str();}
uint8_t nmUtils::wifiSecurityModeFromAp(const std::string& ssid, guint32 flags, guint32 wpaFlags, guint32 rsnFlags, bool doPrint)
{
@@ -205,11 +207,12 @@ namespace WPEFramework
return upperStr1 == upperStr2;
}
- bool nmUtils::getInterfacesName()
+ bool nmUtils::getDeviceProperties()
{
std::string line;
std::string wifiIfname;
std::string ethIfname; // cached interface name
+ std::string deviceHostname;
std::ifstream file("/etc/device.properties");
if (!file.is_open()) {
@@ -243,12 +246,24 @@ namespace WPEFramework
wifiIfname = "wlan0_missing"; // means device doesnot have wifi interface
}
}
+
+ if (line.find("DEVICE_NAME=") != std::string::npos) {
+ deviceHostname = line.substr(line.find('=') + 1);
+ deviceHostname.erase(deviceHostname.find_last_not_of("\r\n\t") + 1);
+ deviceHostname.erase(0, deviceHostname.find_first_not_of("\r\n\t"));
+ if(deviceHostname.empty())
+ {
+ NMLOG_WARNING("DEVICE_NAME is empty in /etc/device.properties");
+ deviceHostname = ""; // set empty device name
+ }
+ }
}
file.close();
m_wlanifname = wifiIfname;
m_ethifname = ethIfname;
- NMLOG_INFO("/etc/device.properties eth: %s, wlan: %s", m_ethifname.c_str(), m_wlanifname.c_str());
+ m_deviceHostname = deviceHostname;
+ NMLOG_INFO("/etc/device.properties eth: %s, wlan: %s, device name: %s", m_ethifname.c_str(), m_wlanifname.c_str(), m_deviceHostname.c_str());
return true;
}
@@ -303,6 +318,8 @@ namespace WPEFramework
}
}
+
+
bool nmUtils::isInterfaceEnabled(const std::string& interface)
{
std::string markerFile;
@@ -322,5 +339,57 @@ namespace WPEFramework
return isAllowed;
}
+ bool nmUtils::writePersistentHostname(const std::string& hostname)
+ {
+ if (hostname.empty()) {
+ NMLOG_ERROR("Cannot write empty hostname to persistent storage");
+ return false;
+ }
+
+ std::ofstream file(HostnameFile);
+ if (!file.is_open()) {
+ NMLOG_ERROR("Failed to open %s for writing", HostnameFile);
+ return false;
+ }
+
+ file << hostname;
+ bool success = !file.fail();
+ file.close();
+
+ if (success)
+ NMLOG_DEBUG("Successfully wrote hostname '%s' to %s",hostname.c_str(), HostnameFile);
+ else
+ NMLOG_ERROR("Error writing hostname to %s", HostnameFile);
+
+ return success;
+ }
+
+ bool nmUtils::readPersistentHostname(std::string& hostname)
+ {
+ std::ifstream file(HostnameFile);
+ if (!file.is_open()) {
+ NMLOG_DEBUG("Could not open %s - file may not exist yet", HostnameFile);
+ hostname = "";
+ return false;
+ }
+
+ std::string line;
+ if (std::getline(file, line)) {
+ // Remove any whitespace, newlines, etc.
+ line.erase(line.find_last_not_of("\r\n\t") + 1);
+ line.erase(0, line.find_first_not_of("\r\n\t"));
+ hostname = line;
+ file.close();
+
+ NMLOG_INFO("Read persistent hostname: '%s'", hostname.c_str());
+ return true;
+ }
+
+ NMLOG_WARNING("Persistent hostname file exists but is empty");
+ hostname = "";
+ file.close();
+ return false;
+ }
+
} // Plugin
} // WPEFramework
diff --git a/plugin/gnome/NetworkManagerGnomeUtils.h b/plugin/gnome/NetworkManagerGnomeUtils.h
index 35688d46..aab7daf0 100644
--- a/plugin/gnome/NetworkManagerGnomeUtils.h
+++ b/plugin/gnome/NetworkManagerGnomeUtils.h
@@ -31,13 +31,15 @@ namespace WPEFramework
{
constexpr const char* EthernetDisableMarker = "/opt/persistent/ethernet.interface.disable";
constexpr const char* WiFiDisableMarker = "/opt/persistent/wifi.interface.disable";
+ constexpr const char* HostnameFile = "/opt/persistent/nm.plugin.hostname";
class nmUtils
{
public:
- static bool getInterfacesName();
+ static bool getDeviceProperties();
static const char* wlanIface();
static const char* ethIface();
+ static const char* deviceHostname();
static const char* convertPercentageToSignalStrengtStr(int percentage);
static bool caseInsensitiveCompare(const std::string& str1, const std::string& str2);
static uint8_t wifiSecurityModeFromAp(const std::string& ssid, guint32 flags, guint32 wpaFlags, guint32 rsnFlags, bool doPrint = true);
@@ -46,6 +48,8 @@ namespace WPEFramework
static bool setNetworkManagerlogLevelToTrace();
static void setMarkerFile(const char* filename, bool unmark = false);
static bool isInterfaceEnabled(const std::string& interface);
+ static bool writePersistentHostname(const std::string& hostname);
+ static bool readPersistentHostname(std::string& hostname);
};
}
}
diff --git a/plugin/gnome/NetworkManagerGnomeWIFI.cpp b/plugin/gnome/NetworkManagerGnomeWIFI.cpp
index 49454ba8..7d572556 100644
--- a/plugin/gnome/NetworkManagerGnomeWIFI.cpp
+++ b/plugin/gnome/NetworkManagerGnomeWIFI.cpp
@@ -630,14 +630,27 @@ namespace WPEFramework
}
}
- /* Build up the 'ipv4' Setting */
+ std::string hostname;
+ if(!nmUtils::readPersistentHostname(hostname))
+ {
+ hostname = nmUtils::deviceHostname();
+ NMLOG_DEBUG("no persistent hostname found taking device name as hostname !");
+ }
+
+ NMLOG_INFO("dhcp hostname: %s", hostname.c_str());
+
+ /* Build up the 'IPv4' Setting */
NMSettingIP4Config *sIpv4Conf = (NMSettingIP4Config *) nm_setting_ip4_config_new();
g_object_set(G_OBJECT(sIpv4Conf), NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); // autoconf = true
+ g_object_set(G_OBJECT(sIpv4Conf), NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, hostname.c_str(), NULL);
+ g_object_set(G_OBJECT(sIpv4Conf), NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, TRUE, NULL); // hostname send enabled
nm_connection_add_setting(m_connection, NM_SETTING(sIpv4Conf));
- /* Build up the 'ipv6' Setting */
+ /* Build up the 'IPv6' Setting */
NMSettingIP6Config *sIpv6Conf = (NMSettingIP6Config *) nm_setting_ip6_config_new();
g_object_set(G_OBJECT(sIpv6Conf), NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); // autoconf = true
+ g_object_set(G_OBJECT(sIpv6Conf), NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, hostname.c_str(), NULL);
+ g_object_set(G_OBJECT(sIpv6Conf), NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, TRUE, NULL); // hostname send enabled
nm_connection_add_setting(m_connection, NM_SETTING(sIpv6Conf));
return true;
}
diff --git a/plugin/rdk/NetworkManagerRDKProxy.cpp b/plugin/rdk/NetworkManagerRDKProxy.cpp
index e85ae4f9..543d014e 100644
--- a/plugin/rdk/NetworkManagerRDKProxy.cpp
+++ b/plugin/rdk/NetworkManagerRDKProxy.cpp
@@ -433,6 +433,13 @@ namespace WPEFramework
return;
}
+ /* @brief Set the dhcp hostname */
+ uint32_t NetworkManagerImplementation::SetHostname(const string& hostname /* @in */)
+ {
+ // TODO: Implement setting the DHCP hostname for netsrvmgr
+ return Core::ERROR_NONE;
+ }
+
void NetworkManagerImplementation::platform_init()
{
LOG_ENTRY_FUNCTION();
diff --git a/tests/mocks/INetworkManagerMock.h b/tests/mocks/INetworkManagerMock.h
index 7aad39b3..eb359627 100644
--- a/tests/mocks/INetworkManagerMock.h
+++ b/tests/mocks/INetworkManagerMock.h
@@ -50,6 +50,7 @@ class MockINetworkManager : public WPEFramework::Exchange::INetworkManager {
MOCK_METHOD(uint32_t, GetWiFiSignalQuality, (string& ssid, string& strength, string& noise, string& snr, WPEFramework::Exchange::INetworkManager::WiFiSignalQuality& quality), (override));
MOCK_METHOD(uint32_t, GetSupportedSecurityModes, (ISecurityModeIterator*& modes), (const));
MOCK_METHOD(uint32_t, SetLogLevel, (const Logging& level), (override));
+ MOCK_METHOD(uint32_t, SetHostname, (const string& hostname), (override));
MOCK_METHOD(uint32_t, GetLogLevel, (Logging& level), (override));
MOCK_METHOD(uint32_t, Configure, (WPEFramework::PluginHost::IShell* service), (override));
MOCK_METHOD(uint32_t, Register, (WPEFramework::Exchange::INetworkManager::INotification* notification), (override));