Skip to content
Merged

Sync #18

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 27 additions & 1 deletion definition/NetworkManager.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
47 changes: 47 additions & 0 deletions docs/NetworkManagerPlugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -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). |

<a name="method.SetLogLevel"></a>
## *SetLogLevel [<sup>method</sup>](#head.Methods)*
Expand Down Expand Up @@ -1667,6 +1668,52 @@ This method takes no parameters.
}
```

<a name="method.SetHostname"></a>
## *SetHostname [<sup>method</sup>](#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
}
}
```

<a name="head.Notifications"></a>
# Notifications

Expand Down
2 changes: 2 additions & 0 deletions interface/INetworkManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
1 change: 1 addition & 0 deletions plugin/NetworkManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions plugin/NetworkManagerImplementation.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
25 changes: 25 additions & 0 deletions plugin/NetworkManagerJsonRpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -105,6 +106,7 @@ namespace WPEFramework
Unregister("GetPublicIP");
Unregister("Ping");
Unregister("Trace");
Unregister("SetHostname");
Unregister("StartWiFiScan");
Unregister("StopWiFiScan");
Unregister("GetKnownSSIDs");
Expand Down Expand Up @@ -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();
Expand Down
190 changes: 188 additions & 2 deletions plugin/gnome/NetworkManagerGnomeProxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -76,7 +261,7 @@ namespace WPEFramework
{
::_instance = this;
GError *error = NULL;

// initialize the NMClient object
client = nm_client_new(NULL, &error);
if (client == NULL) {
Expand All @@ -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();
Expand Down
Loading
Loading