From 8b1163348050e60b13bd07de4a9e8e3f8994a4e4 Mon Sep 17 00:00:00 2001 From: RAFI <103924677+cmuhammedrafi@users.noreply.github.com> Date: Mon, 18 Nov 2024 07:24:26 +0530 Subject: [PATCH] RDKEMW-234: [RDKE][GNOME] Not getting values for WIFI interface on GetAvailableInterfaces method (#31) * Gnome issue fix for following api wifiConnect addtoknownssid removeknowssid getavilablessid getwifisiganlstrength GetAvailableInterfaces GetPrimaryInterface GetInterfaceState GetIPSettings * onAddressChange event modified * Posting event even if interface already connected before plugin start * Update NetworkManagerGnomeEvents.cpp Signed-off-by: cmuhammedrafi --- NetworkManagerGnomeEvents.cpp | 98 ++--- NetworkManagerGnomeProxy.cpp | 439 +++++++++++++--------- NetworkManagerGnomeUtils.cpp | 187 +++++----- NetworkManagerGnomeUtils.h | 6 +- NetworkManagerGnomeWIFI.cpp | 676 ++++++++++++++++++---------------- NetworkManagerGnomeWIFI.h | 4 +- NetworkManagerJsonRpc.cpp | 4 +- NetworkManagerRDKProxy.cpp | 2 +- WiFiSignalStrengthMonitor.cpp | 2 +- 9 files changed, 781 insertions(+), 637 deletions(-) diff --git a/NetworkManagerGnomeEvents.cpp b/NetworkManagerGnomeEvents.cpp index bd12c341..0e0321fd 100644 --- a/NetworkManagerGnomeEvents.cpp +++ b/NetworkManagerGnomeEvents.cpp @@ -47,24 +47,27 @@ namespace WPEFramework const char *connectionTyp = NULL; primaryConn = nm_client_get_primary_connection(client); nmEvents->activeConn = primaryConn; + std::string newIface ="unknown"; if (primaryConn) { activeConnId = nm_active_connection_get_id(primaryConn); connectionTyp = nm_active_connection_get_connection_type(primaryConn); NMLOG_INFO("active connection - %s (%s)", activeConnId, connectionTyp); - std::string newIface =""; if (0 == strncmp("802-3-ethernet", connectionTyp, sizeof("802-3-ethernet"))) - newIface = "eth0"; + newIface = nmUtils::ethIface(); else if(0 == strncmp("802-11-wireless", connectionTyp, sizeof("802-11-wireless"))) - newIface = "wlan0"; + newIface = nmUtils::wlanIface(); else NMLOG_WARNING("active connection not an ethernet/wifi %s", connectionTyp); GnomeNetworkManagerEvents::onActiveInterfaceChangeCb(newIface); } else - NMLOG_ERROR("now there's no active connection"); + { + GnomeNetworkManagerEvents::onActiveInterfaceChangeCb(newIface); + NMLOG_WARNING("now there's no active connection"); + } } static void deviceStateChangeCb(NMDevice *device, GParamSpec *pspec, NMEvents *nmEvents) @@ -134,7 +137,7 @@ namespace WPEFramework GnomeNetworkManagerEvents::onWIFIStateChanged(Exchange::INetworkManager::WIFI_STATE_CONNECTING); break; case NM_DEVICE_STATE_IP_CHECK: - GnomeNetworkManagerEvents::onInterfaceStateChangeCb(Exchange::INetworkManager::INTERFACE_ACQUIRING_IP,"wlan0"); + GnomeNetworkManagerEvents::onInterfaceStateChangeCb(Exchange::INetworkManager::INTERFACE_ACQUIRING_IP, nmUtils::wlanIface()); break; case NM_DEVICE_STATE_ACTIVATED: wifiState = "WIFI_STATE_CONNECTED"; @@ -150,10 +153,11 @@ namespace WPEFramework break; case NM_DEVICE_STATE_NEED_AUTH: //GnomeNetworkManagerEvents::onWIFIStateChanged(Exchange::INetworkManager::WIFI_STATE_CONNECTION_INTERRUPTED); - //wifiState = "WIFI_STATE_CONNECTION_INTERRUPTED"; + wifiState = "WIFI_STATE_CONNECTION_INTERRUPTED"; break; default: - wifiState = "Un handiled"; + wifiState = "Un handiled: " ; + wifiState += std::to_string(deviceState); } } } @@ -165,23 +169,23 @@ namespace WPEFramework { case NM_DEVICE_STATE_UNKNOWN: case NM_DEVICE_STATE_UNMANAGED: - GnomeNetworkManagerEvents::onInterfaceStateChangeCb(Exchange::INetworkManager::INTERFACE_DISABLED, "eth0"); + GnomeNetworkManagerEvents::onInterfaceStateChangeCb(Exchange::INetworkManager::INTERFACE_DISABLED, nmUtils::ethIface()); break; case NM_DEVICE_STATE_UNAVAILABLE: case NM_DEVICE_STATE_DISCONNECTED: - GnomeNetworkManagerEvents::onInterfaceStateChangeCb(Exchange::INetworkManager::INTERFACE_LINK_DOWN, "eth0"); + GnomeNetworkManagerEvents::onInterfaceStateChangeCb(Exchange::INetworkManager::INTERFACE_LINK_DOWN, nmUtils::ethIface()); break; case NM_DEVICE_STATE_PREPARE: - GnomeNetworkManagerEvents::onInterfaceStateChangeCb(Exchange::INetworkManager::INTERFACE_LINK_UP, "eth0"); + GnomeNetworkManagerEvents::onInterfaceStateChangeCb(Exchange::INetworkManager::INTERFACE_LINK_UP, nmUtils::ethIface()); break; case NM_DEVICE_STATE_IP_CONFIG: - GnomeNetworkManagerEvents::onInterfaceStateChangeCb(Exchange::INetworkManager::INTERFACE_ACQUIRING_IP,"eth0"); + GnomeNetworkManagerEvents::onInterfaceStateChangeCb(Exchange::INetworkManager::INTERFACE_ACQUIRING_IP, nmUtils::ethIface()); case NM_DEVICE_STATE_NEED_AUTH: case NM_DEVICE_STATE_SECONDARIES: case NM_DEVICE_STATE_ACTIVATED: case NM_DEVICE_STATE_DEACTIVATING: default: - NMLOG_WARNING("Unhandiled state change"); + NMLOG_WARNING("Unhandiled state change %d", deviceState); } } @@ -256,10 +260,17 @@ namespace WPEFramework for (guint i = 0; i < addresses->len; ++i) { NMIPAddress *address = (NMIPAddress *)g_ptr_array_index(addresses, i); if (nm_ip_address_get_family(address) == AF_INET6) { - const char *ipAddress = nm_ip_address_get_address(address); + const char *ipaddr = nm_ip_address_get_address(address); //int prefix = nm_ip_address_get_prefix(address); - if(ipAddress != NULL) { + if(ipaddr != NULL) { + std::string ipAddress = ipaddr; + if (ipAddress.compare(0, 5, "fe80:") == 0 || + ipAddress.compare(0, 6, "fe80::") == 0) { + NMLOG_DEBUG("%s It's link-local ip", ipAddress.c_str()); + continue; // It's link-local so skiping + } GnomeNetworkManagerEvents::onAddressChangeCb(iface, ipAddress, true, true); + break; // SLAAC protocol may include multip ipv6 address posting only one Global address } } } @@ -272,10 +283,10 @@ namespace WPEFramework { std::string ifname = nm_device_get_iface(device); if(ifname == nmEvents->ifnameWlan0) { - GnomeNetworkManagerEvents::onInterfaceStateChangeCb(Exchange::INetworkManager::INTERFACE_ADDED, "wlan0"); + GnomeNetworkManagerEvents::onInterfaceStateChangeCb(Exchange::INetworkManager::INTERFACE_ADDED, nmUtils::wlanIface()); } else if(ifname == nmEvents->ifnameEth0) { - GnomeNetworkManagerEvents::onInterfaceStateChangeCb(Exchange::INetworkManager::INTERFACE_ADDED, "eth0"); + GnomeNetworkManagerEvents::onInterfaceStateChangeCb(Exchange::INetworkManager::INTERFACE_ADDED, nmUtils::ethIface()); } /* ip events added only for eth0 and wlan0 */ @@ -304,11 +315,11 @@ namespace WPEFramework { std::string ifname = nm_device_get_iface(device); if(ifname == nmEvents->ifnameWlan0) { - GnomeNetworkManagerEvents::onInterfaceStateChangeCb(Exchange::INetworkManager::INTERFACE_REMOVED,"wlan0"); + GnomeNetworkManagerEvents::onInterfaceStateChangeCb(Exchange::INetworkManager::INTERFACE_REMOVED, nmUtils::wlanIface()); g_signal_handlers_disconnect_by_func(device, (gpointer)deviceStateChangeCb, nmEvents); } else if(ifname == nmEvents->ifnameEth0) { - GnomeNetworkManagerEvents::onInterfaceStateChangeCb(Exchange::INetworkManager::INTERFACE_REMOVED, "eth0"); + GnomeNetworkManagerEvents::onInterfaceStateChangeCb(Exchange::INetworkManager::INTERFACE_REMOVED, nmUtils::ethIface()); g_signal_handlers_disconnect_by_func(device, (gpointer)deviceStateChangeCb, nmEvents); } } @@ -380,10 +391,12 @@ namespace WPEFramework NMIPConfig *ipv4Config = nm_device_get_ip4_config(device); NMIPConfig *ipv6Config = nm_device_get_ip6_config(device); if (ipv4Config) { + ip4ChangedCb(ipv4Config, NULL, device); // posting event if interface already connected g_signal_connect(ipv4Config, "notify::addresses", G_CALLBACK(ip4ChangedCb), device); } if (ipv6Config) { + ip6ChangedCb(ipv6Config, NULL, device); g_signal_connect(ipv6Config, "notify::addresses", G_CALLBACK(ip6ChangedCb), device); } @@ -393,7 +406,7 @@ namespace WPEFramework } } else - NMLOG_DEBUG("device type not eth/wifi"); + NMLOG_DEBUG("device type not eth/wifi %s", ifname.c_str()); } } @@ -453,12 +466,6 @@ namespace WPEFramework GnomeNetworkManagerEvents::GnomeNetworkManagerEvents() { NMLOG_DEBUG("GnomeNetworkManagerEvents"); - std::string wifiInterface = "wlan0", ethernetInterface = "eth0"; - if(!nmUtils::GetInterfacesName(wifiInterface, ethernetInterface)) - { - NMLOG_FATAL("GetInterfacesName failed"); - return; - } GError *error = NULL; nmEvents.client = nm_client_new(NULL, &error); if(!nmEvents.client || error ) @@ -478,8 +485,8 @@ namespace WPEFramework return; } _nmEventInstance = this; - nmEvents.ifnameEth0 = ethernetInterface; - nmEvents.ifnameWlan0 = wifiInterface; + nmEvents.ifnameEth0 = nmUtils::ethIface(); + nmEvents.ifnameWlan0 = nmUtils::wlanIface(); } /* Gnome networkmanger new events */ @@ -539,28 +546,35 @@ namespace WPEFramework static std::map ipv6Map; static std::map ipv4Map; - if (isIPv6) + if(acquired) { - if (ipAddress.empty()) { - ipAddress = ipv6Map[iface]; - ipv6Map[iface].clear(); - } - else { + if (isIPv6) + { if (ipv6Map[iface].find(ipAddress) == std::string::npos) { // same ip comes multiple time so avoding that - if (!ipv6Map[iface].empty()) - ipv6Map[iface] += " "; - ipv6Map[iface] += ipAddress; // SLAAC protocol may include multip ipv6 address + ipv6Map[iface] = ipAddress; } - else - return; // skip same ip event posting + else // same ip not posting + return; + } + else + { + ipv4Map[iface] = ipAddress; } } else { - if (ipAddress.empty()) - ipAddress = ipv4Map[iface]; + if (isIPv6) + { + ipAddress = ipv6Map[iface]; + ipv6Map[iface].clear(); + } else - ipv4Map[iface] = ipAddress; + { + ipAddress = ipv4Map[iface]; + ipv4Map[iface].clear(); + } + if(ipAddress.empty()) + return; // empty ip address not posting event } Exchange::INetworkManager::IPStatus ipStatus{}; @@ -569,7 +583,7 @@ namespace WPEFramework if(_instance != nullptr) _instance->ReportIPAddressChange(iface, isIPv6?"IPv6":"IPv4", ipAddress, ipStatus); - NMLOG_INFO("iface:%s - ipaddress:%s - %s - isIPv6:%s", iface.c_str(), ipAddress.c_str(), acquired?"acquired":"lost", isIPv6?"true":"false"); + NMLOG_INFO("iface:%s - ipaddress:%s - %s - %s", iface.c_str(), ipAddress.c_str(), acquired?"acquired":"lost", isIPv6?"isIPv6":"isIPv4"); } void GnomeNetworkManagerEvents::onAvailableSSIDsCb(NMDeviceWifi *wifiDevice, GParamSpec *pspec, gpointer userData) diff --git a/NetworkManagerGnomeProxy.cpp b/NetworkManagerGnomeProxy.cpp index bb32fc81..b8780aaa 100644 --- a/NetworkManagerGnomeProxy.cpp +++ b/NetworkManagerGnomeProxy.cpp @@ -31,14 +31,23 @@ namespace WPEFramework { ::_instance = this; GError *error = NULL; + // initialize the NMClient object client = nm_client_new(NULL, &error); if (client == NULL) { - NMLOG_DEBUG("Error initializing NMClient: %s", error->message); + NMLOG_FATAL("Error initializing NMClient: %s", error->message); g_error_free(error); return; } + nmUtils::getInterfacesName(); // get interface name form '/etc/device.proprties' + NMDeviceState ethState = nmUtils::ifaceState(client, nmUtils::ethIface()); + if(ethState > NM_DEVICE_STATE_DISCONNECTED && ethState < NM_DEVICE_STATE_DEACTIVATING) + m_defaultInterface = nmUtils::ethIface(); + else + m_defaultInterface = nmUtils::wlanIface(); + + NMLOG_INFO("default interface is %s", m_defaultInterface.c_str()); nmEvent = GnomeNetworkManagerEvents::getInstance(); nmEvent->startNetworkMangerEventMonitor(); wifi = wifiManager::getInstance(); @@ -47,47 +56,59 @@ namespace WPEFramework uint32_t NetworkManagerImplementation::GetAvailableInterfaces (Exchange::INetworkManager::IInterfaceDetailsIterator*& interfacesItr/* @out */) { - uint32_t rc = Core::ERROR_RPC_CALL_FAILED; - NMDeviceType type; - NMDeviceState state; - NMDevice *device = NULL; - static std::vector interfaceList; + uint32_t rc = Core::ERROR_GENERAL; + std::vector interfaceList; + std::string wifiname = nmUtils::wlanIface(), ethname = nmUtils::ethIface(); - if(interfaceList.empty()) + if(client == nullptr) { + NMLOG_FATAL("client connection null:"); + return Core::ERROR_GENERAL; + } + + GPtrArray *devices = const_cast(nm_client_get_devices(client)); + if (devices == NULL) { + NMLOG_ERROR("Failed to get device list."); + return Core::ERROR_GENERAL; + } + + for (guint j = 0; j < devices->len; j++) { - std::string interfaces[2]; - if(!nmUtils::GetInterfacesName(interfaces[0], interfaces[1])) - { - NMLOG_WARNING("GetInterface Name Error !"); - return Core::ERROR_GENERAL; - } - for (size_t i = 0; i < 2; i++) + NMDevice *device = NM_DEVICE(devices->pdata[j]); + if(device != NULL) { - if(!interfaces[i].empty()) + const char* ifacePtr = nm_device_get_iface(device); + if(ifacePtr == nullptr) + continue; + std::string ifaceStr = ifacePtr; + if(ifaceStr == wifiname || ifaceStr == ethname) // only wifi and ethenet taking { - Exchange::INetworkManager::InterfaceDetails tmp; - device = nm_client_get_device_by_iface(client, interfaces[i].c_str()); - if (device) - { - if(i == 0) - tmp.type = Exchange::INetworkManager::INTERFACE_TYPE_WIFI; - else - tmp.type = Exchange::INetworkManager::INTERFACE_TYPE_ETHERNET; - tmp.name = interfaces[i].c_str(); - tmp.mac = nm_device_get_hw_address(device); - state = nm_device_get_state(device); - tmp.enabled = (state > NM_DEVICE_STATE_UNAVAILABLE) ? true : false; - tmp.connected = (state > NM_DEVICE_STATE_DISCONNECTED) ? true : false; - interfaceList.push_back(tmp); - //g_clear_object(&device); + NMDeviceState deviceState = NM_DEVICE_STATE_UNKNOWN; + Exchange::INetworkManager::InterfaceDetails interface; + if(ifaceStr == wifiname) { + interface.type = INTERFACE_TYPE_WIFI; + interface.name = wifiname; + } + if(ifaceStr == ethname) { + interface.type = INTERFACE_TYPE_ETHERNET; + interface.name = ethname; + } + interface.mac = nm_device_get_hw_address(device); + deviceState = nm_device_get_state(device); + interface.enabled = (deviceState >= NM_DEVICE_STATE_UNAVAILABLE) ? true : false; + if(deviceState > NM_DEVICE_STATE_DISCONNECTED && deviceState < NM_DEVICE_STATE_DEACTIVATING){ + interface.connected = true; + m_defaultInterface = interface.name; } + else + interface.connected = false; + interfaceList.push_back(interface); + rc = Core::ERROR_NONE; } } } using Implementation = RPC::IteratorType; interfacesItr = Core::Service::Create(interfaceList); - rc = Core::ERROR_NONE; return rc; } @@ -98,6 +119,8 @@ namespace WPEFramework GError *error = NULL; NMActiveConnection *activeConn = NULL; NMRemoteConnection *remoteConn = NULL; + std::string wifiname = nmUtils::wlanIface(), ethname = nmUtils::ethIface(); + if(client == nullptr) { NMLOG_WARNING("client connection null:"); @@ -106,26 +129,35 @@ namespace WPEFramework activeConn = nm_client_get_primary_connection(client); if (activeConn == NULL) { - NMLOG_ERROR("No active activeConn Interface found"); - return Core::ERROR_GENERAL; + NMLOG_WARNING("no active activeConn Interface found"); + NMDeviceState ethState = nmUtils::ifaceState(client, nmUtils::ethIface()); + /* if ethernet is connected but not completely activate then ethernet is taken as primary else wifi */ + if(ethState > NM_DEVICE_STATE_DISCONNECTED && ethState < NM_DEVICE_STATE_DEACTIVATING) + m_defaultInterface = interface = ethname; + else + m_defaultInterface = interface = wifiname; // default is wifi + return Core::ERROR_NONE; } + remoteConn = nm_active_connection_get_connection(activeConn); if(remoteConn == NULL) { - NMLOG_WARNING("remote connection error"); + NMLOG_ERROR("remote connection error"); return Core::ERROR_GENERAL; } - interface.clear(); + const char *ifacePtr = nm_connection_get_interface_name(NM_CONNECTION(remoteConn)); if(ifacePtr == NULL) { NMLOG_ERROR("nm_connection_get_interface_name is failed"); return Core::ERROR_GENERAL; } + interface = ifacePtr; - if(interface != "eth0" && interface != "wlan0") + m_defaultInterface = interface; + if(interface != wifiname && interface != ethname) { - NMLOG_DEBUG("interface name is unknow"); + NMLOG_ERROR("primary interface is not eth/wlan"); interface.clear(); } else @@ -138,30 +170,26 @@ namespace WPEFramework uint32_t NetworkManagerImplementation::SetPrimaryInterface (const string& interface/* @in */) { uint32_t rc = Core::ERROR_RPC_CALL_FAILED; + std::string wifiname = nmUtils::wlanIface(), ethname = nmUtils::ethIface(); + if(client == nullptr) { NMLOG_WARNING("client connection null:"); return Core::ERROR_RPC_CALL_FAILED; } - std::string iface = "eth0"; - std::string eth, wifi; - if(!nmUtils::GetInterfacesName(wifi, eth)) + if(interface.empty() || (wifiname != interface && ethname != interface)) { - NMLOG_WARNING("GetInterface Name Error !"); + NMLOG_FATAL("interface is not valied %s", interface.c_str()!=nullptr? interface.c_str():"empty"); return Core::ERROR_GENERAL; } - else if(interface == "wlan0" || nmUtils::caseInsensitiveCompare(interface,"WIFI")) - iface = wifi; - else if(interface == "eth0" || nmUtils::caseInsensitiveCompare(interface,"ETHERNET")) - iface = eth; - - NMDevice *device = nm_client_get_device_by_iface(client, iface.c_str()); + NMDevice *device = nm_client_get_device_by_iface(client, interface.c_str()); if (device == NULL) { - NMLOG_WARNING("no interface found "); + NMLOG_FATAL("libnm doesn't have device corresponding to %s", interface.c_str()); return Core::ERROR_GENERAL; } + const GPtrArray *connections = nm_client_get_connections(client); NMConnection *conn = NULL; NMSettingConnection *settings; @@ -171,7 +199,7 @@ namespace WPEFramework settings = nm_connection_get_setting_connection(connection); /* Check if the interface name matches */ - if (g_strcmp0(nm_setting_connection_get_interface_name(settings), iface.c_str()) == 0) { + if (g_strcmp0(nm_setting_connection_get_interface_name(settings), interface.c_str()) == 0) { conn = connection; break; } @@ -196,71 +224,103 @@ namespace WPEFramework uint32_t NetworkManagerImplementation::SetInterfaceState(const string& interface/* @in */, const bool enabled /* @in */) { - uint32_t rc = Core::ERROR_NONE; + std::string wifiname = nmUtils::wlanIface(), ethname = nmUtils::ethIface(); + if(client == nullptr) { NMLOG_WARNING("client connection null:"); return Core::ERROR_RPC_CALL_FAILED; } - std::string iface = "eth0"; - std::string eth, wifi; - if(!nmUtils::GetInterfacesName(wifi, eth)) + if(interface.empty() || (wifiname != interface && ethname != interface)) { - NMLOG_WARNING("GetInterface Name Error !"); + NMLOG_ERROR("interface: %s; not valied", interface.c_str()!=nullptr? interface.c_str():"empty"); return Core::ERROR_GENERAL; } - else if(interface == "wlan0" || nmUtils::caseInsensitiveCompare(interface,"WIFI")) - iface = wifi; - else if(interface == "eth0" || nmUtils::caseInsensitiveCompare(interface,"ETHERNET")) - iface = eth; - - const GPtrArray *devices = nm_client_get_devices(client); - NMDevice *device = NULL; - - for (guint i = 0; i < devices->len; ++i) { - device = NM_DEVICE(g_ptr_array_index(devices, i)); - const char *name = nm_device_get_iface(device); - if (g_strcmp0(name, iface.c_str()) == 0) { - nm_device_set_managed(device, enabled); - NMLOG_INFO("Interface %s status set to %s", iface.c_str(), enabled ? "Enabled" : "Disabled"); - } + NMDevice *device = nm_client_get_device_by_iface(client, interface.c_str()); + if (device == NULL) { + NMLOG_FATAL("libnm doesn't have device corresponding to %s", interface.c_str()); + return Core::ERROR_GENERAL; } - // if(device) - // g_clear_object(&device); - return rc; + nm_device_set_managed(device, enabled); + NMLOG_INFO("interface %s state: %s", interface.c_str(), enabled ? "enabled" : "disabled"); + return Core::ERROR_NONE; } uint32_t NetworkManagerImplementation::GetInterfaceState(const string& interface/* @in */, bool& isEnabled /* @out */) { - uint32_t rc = Core::ERROR_NONE; -#if 0 //FIXME - const GPtrArray *devices = nm_client_get_devices(client); - NMDevice *device = NULL; + isEnabled = false; + bool isIfaceFound = false; + std::string wifiname = nmUtils::wlanIface(), ethname = nmUtils::ethIface(); - for (guint i = 0; i < devices->len; ++i) { - device = NM_DEVICE(g_ptr_array_index(devices, i)); + if(client == nullptr) + { + NMLOG_WARNING("client connection null:"); + return Core::ERROR_RPC_CALL_FAILED; + } - // Get the device details - const char *name = nm_device_get_iface(device); + if(interface.empty() || (wifiname != interface && ethname != interface)) + { + NMLOG_ERROR("interface: %s; not valied", interface.c_str()!=nullptr? interface.c_str():"empty"); + return Core::ERROR_GENERAL; + } - // Check if the device name matches - if (g_strcmp0(name, interface.c_str()) == 0) { - nm_device_set_managed(device, false); + GPtrArray *devices = const_cast(nm_client_get_devices(client)); + if (devices == NULL) { + NMLOG_ERROR("Failed to get device list."); + return Core::ERROR_GENERAL; + } - NMLOG_DEBUG("Interface %s status set to disabled", - interface.c_str()); + for (guint j = 0; j < devices->len; j++) + { + NMDevice *device = NM_DEVICE(devices->pdata[j]); + if(device != NULL) + { + const char* iface = nm_device_get_iface(device); + if(iface != NULL) + { + std::string ifaceStr; + ifaceStr.assign(iface); + NMDeviceState deviceState = NM_DEVICE_STATE_UNKNOWN; + if(ifaceStr == interface) + { + isIfaceFound = true; + deviceState = nm_device_get_state(device); + isEnabled = (deviceState > NM_DEVICE_STATE_UNAVAILABLE) ? true : false; + NMLOG_INFO("%s : %s", ifaceStr.c_str(), isEnabled?"enabled":"disabled"); + break; + } + } } } - - // Cleanup - if(device) - g_clear_object(&device); -#endif - return rc; - } + + if(isIfaceFound) + return Core::ERROR_NONE; + else + NMLOG_ERROR("%s : not found", interface.c_str()); + return Core::ERROR_GENERAL; + } + + bool static isAutoConnectEnabled(NMActiveConnection* activeConn) + { + NMConnection *connection = NM_CONNECTION(nm_active_connection_get_connection(activeConn)); + if(connection == NULL) + return false; + + NMSettingIPConfig *ipConfig = nm_connection_get_setting_ip4_config(connection); + if(ipConfig) + { + const char* ipConfMethod = nm_setting_ip_config_get_method (ipConfig); + if(ipConfMethod != NULL && g_strcmp0(ipConfMethod, "auto") == 0) + return true; + else + NMLOG_WARNING("ip configuration: %s", ipConfMethod != NULL? ipConfMethod: "null"); + } + + return false; + } /* @brief Get IP Address Of the Interface */ uint32_t NetworkManagerImplementation::GetIPSettings(string& interface /* @inout */, const string &ipversion /* @in */, IPAddress& result /* @out */) @@ -270,148 +330,180 @@ namespace WPEFramework NMIPConfig *ip4_config = NULL; NMIPConfig *ip6_config = NULL; const gchar *gateway = NULL; - char **dns_arr = NULL; + char **dnsArr = NULL; NMDhcpConfig *dhcp4_config = NULL; NMDhcpConfig *dhcp6_config = NULL; const char* dhcpserver; NMSettingConnection *settings; - NMIPAddress *address = NULL; NMDevice *device = NULL; + std::string wifiname = nmUtils::wlanIface(), ethname = nmUtils::ethIface(); + if(client == nullptr) { NMLOG_WARNING("client connection null:"); return Core::ERROR_RPC_CALL_FAILED; } - std::string iface = "eth0"; - std::string ethIface, wifiIface; - if(!nmUtils::GetInterfacesName(wifiIface, ethIface)) - { - NMLOG_WARNING("GetInterface Name Error !"); - return Core::ERROR_GENERAL; - } - - else if(interface == "wlan0" || nmUtils::caseInsensitiveCompare(interface,"WIFI")) - iface = wifiIface; - else if(interface == "eth0" || nmUtils::caseInsensitiveCompare(interface,"ETHERNET")) - iface = ethIface; - else + if(interface.empty() || interface == "null") { - if(Core::ERROR_NONE != GetPrimaryInterface(iface)) + if(Core::ERROR_NONE != GetPrimaryInterface(interface)) { - NMLOG_WARNING("interface is not specified and default interface get failed"); - return Core::ERROR_GENERAL; + NMLOG_WARNING("default interface get failed"); + return Core::ERROR_NONE; } + if(interface.empty()) + { + NMLOG_DEBUG("default interface return empty default is wlan0"); + interface = wifiname; + } + } + else if(wifiname != interface && ethname != interface) + { + NMLOG_ERROR("interface: %s; not valied", interface.c_str()); + return Core::ERROR_GENERAL; } - device = nm_client_get_device_by_iface(client, iface.c_str()); + device = nm_client_get_device_by_iface(client, interface.c_str()); if (device == NULL) { - NMLOG_WARNING("no interface found / wifi not connected no ip found"); + NMLOG_FATAL("libnm doesn't have device corresponding to %s", interface.c_str()); return Core::ERROR_GENERAL; } NMDeviceState deviceState = NM_DEVICE_STATE_UNKNOWN; deviceState = nm_device_get_state(device); - if(deviceState != NM_DEVICE_STATE_ACTIVATED) + if(deviceState < NM_DEVICE_STATE_DISCONNECTED) { - NMLOG_WARNING("device state is not activated state: (%d)", deviceState); + NMLOG_WARNING("Device state is not a valid state: (%d)", deviceState); return Core::ERROR_GENERAL; } if(ipversion.empty()) - NMLOG_WARNING("ipversion is empty default value IPV4"); + NMLOG_WARNING("ipversion is empty default value IPv4"); const GPtrArray *connections = nm_client_get_active_connections(client); if(connections == NULL) { - NMLOG_WARNING("nm_client_get_active_connections error"); + NMLOG_WARNING("no active connection; ip is not assigned to interface"); return Core::ERROR_GENERAL; } - for (guint i = 0; i < connections->len; i++){ + + for (guint i = 0; i < connections->len; i++) + { NMActiveConnection *connection = NM_ACTIVE_CONNECTION(connections->pdata[i]); + if (connection == nullptr) + continue; settings = nm_connection_get_setting_connection(NM_CONNECTION(nm_active_connection_get_connection(connection))); - /* Check if the interface name matches */ - if (g_strcmp0(nm_setting_connection_get_interface_name(settings), iface.c_str()) == 0) { + if (g_strcmp0(nm_setting_connection_get_interface_name(settings), interface.c_str()) == 0) { conn = connection; break; } } + if (conn == NULL) { - NMLOG_ERROR("no active connection found"); + NMLOG_WARNING("no active connection on %s interface", interface.c_str()); return Core::ERROR_GENERAL; } - if(ipversion.empty()||nmUtils::caseInsensitiveCompare(ipversion,"IPV4")) + result.autoconfig = isAutoConnectEnabled(conn); + if(ipversion.empty() || ipversion == "null" || nmUtils::caseInsensitiveCompare(ipversion, "IPV4")) // default ipversion ipv4 { ip4_config = nm_active_connection_get_ip4_config(conn); + NMIPAddress *ipAddr = NULL; + std::string ipStr; if (ip4_config != NULL) { - const GPtrArray *p; - int i; - p = nm_ip_config_get_addresses(ip4_config); - for (i = 0; i < p->len; i++) { - address = static_cast(p->pdata[i]); + const GPtrArray *ipByte; + ipByte = nm_ip_config_get_addresses(ip4_config); + for (int i = 0; i < ipByte->len; i++) { + ipAddr = static_cast(ipByte->pdata[i]); + if(ipAddr) + ipStr = nm_ip_address_get_address(ipAddr); + if(!ipStr.empty()) + { + result.ipaddress = nm_ip_address_get_address(ipAddr); + result.prefix = nm_ip_address_get_prefix(ipAddr); + NMLOG_INFO("IPv4 addr: %s/%d", result.ipaddress.c_str(), result.prefix); + result.ipversion = "IPv4"; // if null add as default + } } gateway = nm_ip_config_get_gateway(ip4_config); - } - dns_arr = (char **)nm_ip_config_get_nameservers(ip4_config); + } + dnsArr = (char **)nm_ip_config_get_nameservers(ip4_config); dhcp4_config = nm_active_connection_get_dhcp4_config(conn); - dhcpserver = nm_dhcp_config_get_one_option (dhcp4_config, - "dhcp_server_identifier"); - if(!ipversion.empty()) - result.ipversion = ipversion.c_str(); - else - result.ipversion = "IPv4"; + if(dhcp4_config) + dhcpserver = nm_dhcp_config_get_one_option (dhcp4_config, "dhcp_server_identifier"); if(dhcpserver) result.dhcpserver = dhcpserver; - result.ula = ""; - result.ipaddress = nm_ip_address_get_address(address); - result.prefix = nm_ip_address_get_prefix(address); - result.gateway = gateway; - if((*(&dns_arr[0]))!=NULL) - result.primarydns = *(&dns_arr[0]); - if((*(&dns_arr[1]))!=NULL ) - result.secondarydns = *(&dns_arr[1]); + result.ula = ""; + if(gateway) + result.gateway = gateway; + if((*(&dnsArr[0]))!=NULL) + result.primarydns = *(&dnsArr[0]); + if((*(&dnsArr[1]))!=NULL ) + result.secondarydns = *(&dnsArr[1]); rc = Core::ERROR_NONE; } - else if(nmUtils::caseInsensitiveCompare(ipversion,"IPV6")) + else if(nmUtils::caseInsensitiveCompare(ipversion, "IPV6")) { - NMIPAddress *a; + result.ipversion = ipversion.c_str(); + NMIPAddress *ipAddr = nullptr; ip6_config = nm_active_connection_get_ip6_config(conn); - if (ip6_config != NULL) { - const GPtrArray *p; - int i; - p = nm_ip_config_get_addresses(ip6_config); - for (i = 0; i < p->len; i++) { - a = static_cast(p->pdata[i]); - result.ipaddress = nm_ip_address_get_address(a); - NMLOG_DEBUG("\tinet6 %s/%d\n", nm_ip_address_get_address(a), nm_ip_address_get_prefix(a)); + if(ip6_config == nullptr) + { + NMLOG_WARNING("no ipv6 config found"); + rc = Core::ERROR_GENERAL; + } + else + { + std::string ipStr; + const GPtrArray *ipArray = nullptr; + ipArray = nm_ip_config_get_addresses(ip6_config); + for (int i = 0; i < ipArray->len; i++) + { + ipAddr = static_cast(ipArray->pdata[i]); + if(ipAddr) + ipStr = nm_ip_address_get_address(ipAddr); + if(!ipStr.empty()) + { + if (ipStr.compare(0, 5, "fe80:") == 0 || ipStr.compare(0, 6, "fe80::") == 0) { + result.ula = ipStr; + NMLOG_INFO("link-local ip: %s", result.ula.c_str()); + } + else { + result.prefix = nm_ip_address_get_prefix(ipAddr); + if(result.ipaddress.empty()) // SLAAC mutiple ip not added + result.ipaddress = ipStr; + NMLOG_INFO("global ip %s/%d", ipStr.c_str(), result.prefix); + } + } } - gateway = nm_ip_config_get_gateway(ip6_config); - dns_arr = (char **)nm_ip_config_get_nameservers(ip6_config); + gateway = nm_ip_config_get_gateway(ip6_config); + if(gateway) + result.gateway= gateway; + dnsArr = (char **)nm_ip_config_get_nameservers(ip6_config); + if((*(&dnsArr[0]))!= NULL) + result.primarydns = *(&dnsArr[0]); + if((*(&dnsArr[1]))!=NULL ) + result.secondarydns = *(&dnsArr[1]); dhcp6_config = nm_active_connection_get_dhcp6_config(conn); - dhcpserver = nm_dhcp_config_get_one_option (dhcp6_config, - "dhcp_server_identifier"); - result.ipversion = ipversion.c_str(); - if(dhcpserver) - result.dhcpserver = dhcpserver; - result.ula = ""; - result.prefix = 0; - result.gateway = gateway; - if((*(&dns_arr[0]))!=NULL) - result.primarydns = *(&dns_arr[0]); - if((*(&dns_arr[1]))!=NULL ) - result.secondarydns = *(&dns_arr[1]); + if(dhcp6_config) + { + dhcpserver = nm_dhcp_config_get_one_option (dhcp6_config, "dhcp_server_identifier"); + if(dhcpserver) { + result.dhcpserver = dhcpserver; + } + } + result.ipversion = "IPv6"; + rc = Core::ERROR_NONE; } - rc = Core::ERROR_NONE; } else - NMLOG_WARNING("ipversion is not IPV4 orIPV6"); + NMLOG_WARNING("ipversion error IPv4/IPv6"); return rc; } @@ -503,7 +595,7 @@ namespace WPEFramework else { //FIXME : Add IPv6 support here - printf("Setting IPv6 is not supported at this point in time. This is just a place holder\n"); + NMLOG_WARNING("Setting IPv6 is not supported at this point in time. This is just a place holder"); rc = Core::ERROR_NOT_SUPPORTED; } } @@ -592,6 +684,7 @@ namespace WPEFramework uint32_t NetworkManagerImplementation::AddToKnownSSIDs(const WiFiConnectTo& ssid /* @in */) { uint32_t rc = Core::ERROR_GENERAL; + NMLOG_WARNING("ssid security %d", ssid.security); if(wifi->addToKnownSSIDs(ssid)) rc = Core::ERROR_NONE; return rc; @@ -613,15 +706,17 @@ namespace WPEFramework NMLOG_WARNING("ssid is invalied"); return rc; } - // Check the last scanning time and if it exceeds 10 sec do a rescanning + + // Check the last scanning time and if it exceeds 5 sec do a rescanning if(!wifi->isWifiScannedRecently()) { - nmEvent->setwifiScanOptions(false, true); // not notify scan result but print logs - if(!wifi->wifiScanRequest("", ssid.ssid)) + nmEvent->setwifiScanOptions(false, false); + if(!wifi->wifiScanRequest()) { NMLOG_WARNING("scanning failed but try to connect"); } } + if(wifi->wifiConnect(ssid)) rc = Core::ERROR_NONE; return rc; diff --git a/NetworkManagerGnomeUtils.cpp b/NetworkManagerGnomeUtils.cpp index e5368393..d6099c6d 100644 --- a/NetworkManagerGnomeUtils.cpp +++ b/NetworkManagerGnomeUtils.cpp @@ -17,86 +17,104 @@ namespace WPEFramework { namespace Plugin { - static const char* ifnameEth = "eth0"; - static const char* ifnameWlan = "wlan0"; + static std::string m_ethifname = "eth0"; + static std::string m_wlanifname = "wlan0"; - uint8_t nmUtils::wifiSecurityModeFromAp(guint32 flags, guint32 wpaFlags, guint32 rsnFlags) - { - uint8_t security = Exchange::INetworkManager::WIFI_SECURITY_NONE; - if ((flags == NM_802_11_AP_FLAGS_NONE) && (wpaFlags == NM_802_11_AP_SEC_NONE) && (rsnFlags == NM_802_11_AP_SEC_NONE)) - { - security = Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_NONE; - } - else if( (flags & NM_802_11_AP_FLAGS_PRIVACY) && ((wpaFlags & NM_802_11_AP_SEC_PAIR_WEP40) || (rsnFlags & NM_802_11_AP_SEC_PAIR_WEP40)) ) - { - security = Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WEP_64; - } - else if( (flags & NM_802_11_AP_FLAGS_PRIVACY) && ((wpaFlags & NM_802_11_AP_SEC_PAIR_WEP104) || (rsnFlags & NM_802_11_AP_SEC_PAIR_WEP104)) ) - { - security = Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WEP_128; - } - else if((wpaFlags & NM_802_11_AP_SEC_PAIR_TKIP) || (rsnFlags & NM_802_11_AP_SEC_PAIR_TKIP)) - { - security = Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WPA_PSK_TKIP; - } - else if((wpaFlags & NM_802_11_AP_SEC_PAIR_CCMP) || (rsnFlags & NM_802_11_AP_SEC_PAIR_CCMP)) - { - security = Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WPA_PSK_AES; - } - else if ((rsnFlags & NM_802_11_AP_SEC_KEY_MGMT_PSK) && (rsnFlags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) - { - security = Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WPA_WPA2_ENTERPRISE; - } - else if(rsnFlags & NM_802_11_AP_SEC_KEY_MGMT_PSK) - { - security = Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WPA_WPA2_PSK; - } - else if((wpaFlags & NM_802_11_AP_SEC_GROUP_CCMP) || (rsnFlags & NM_802_11_AP_SEC_GROUP_CCMP)) - { - security = Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WPA2_PSK_AES; - } - else if((wpaFlags & NM_802_11_AP_SEC_GROUP_TKIP) || (rsnFlags & NM_802_11_AP_SEC_GROUP_TKIP)) - { - security = Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WPA2_PSK_TKIP; + const char* nmUtils::wlanIface() {return m_wlanifname.c_str();} + const char* nmUtils::ethIface() {return m_ethifname.c_str();} + + NMDeviceState nmUtils::ifaceState(NMClient *client, const char* interface) + { + NMDeviceState deviceState = NM_DEVICE_STATE_UNKNOWN; + NMDevice *device = NULL; + if(client == NULL) + return deviceState; + + device = nm_client_get_device_by_iface(client, interface); + if (device == NULL) { + NMLOG_FATAL("libnm doesn't have device corresponding to %s", interface); + return deviceState; } - else if((rsnFlags & NM_802_11_AP_SEC_KEY_MGMT_OWE) || (rsnFlags & NM_802_11_AP_SEC_KEY_MGMT_OWE_TM)) - { - security = Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WPA3_SAE; + + deviceState = nm_device_get_state(device); + return deviceState; + } + + uint8_t nmUtils::wifiSecurityModeFromAp(guint32 flags, guint32 wpaFlags, guint32 rsnFlags) + { + uint8_t security = Exchange::INetworkManager::WIFI_SECURITY_NONE; + if ((flags == NM_802_11_AP_FLAGS_NONE) && (wpaFlags == NM_802_11_AP_SEC_NONE) && (rsnFlags == NM_802_11_AP_SEC_NONE)) + security = Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_NONE; + else if( (flags & NM_802_11_AP_FLAGS_PRIVACY) && ((wpaFlags & NM_802_11_AP_SEC_PAIR_WEP40) || (rsnFlags & NM_802_11_AP_SEC_PAIR_WEP40)) ) + security = Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WEP_64; + else if( (flags & NM_802_11_AP_FLAGS_PRIVACY) && ((wpaFlags & NM_802_11_AP_SEC_PAIR_WEP104) || (rsnFlags & NM_802_11_AP_SEC_PAIR_WEP104)) ) + security = Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WEP_128; + else if((wpaFlags & NM_802_11_AP_SEC_PAIR_TKIP) || (rsnFlags & NM_802_11_AP_SEC_PAIR_TKIP)) + security = Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WPA_PSK_TKIP; + else if((wpaFlags & NM_802_11_AP_SEC_PAIR_CCMP) || (rsnFlags & NM_802_11_AP_SEC_PAIR_CCMP)) + security = Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WPA_PSK_AES; + else if ((rsnFlags & NM_802_11_AP_SEC_KEY_MGMT_PSK) && (rsnFlags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) + security = Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WPA_WPA2_ENTERPRISE; + else if(rsnFlags & NM_802_11_AP_SEC_KEY_MGMT_PSK) + security = Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WPA_WPA2_PSK; + else if((wpaFlags & NM_802_11_AP_SEC_GROUP_CCMP) || (rsnFlags & NM_802_11_AP_SEC_GROUP_CCMP)) + security = Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WPA2_PSK_AES; + else if((wpaFlags & NM_802_11_AP_SEC_GROUP_TKIP) || (rsnFlags & NM_802_11_AP_SEC_GROUP_TKIP)) + security = Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WPA2_PSK_TKIP; + else if((rsnFlags & NM_802_11_AP_SEC_KEY_MGMT_OWE) || (rsnFlags & NM_802_11_AP_SEC_KEY_MGMT_OWE_TM)) + security = Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WPA3_SAE; + else + NMLOG_WARNING("security mode not defined (flag: %d, wpaFlags: %d, rsnFlags: %d)", flags, wpaFlags, rsnFlags); + return security; + } + + // Function to convert percentage (0-100) to dBm string + const char* nmUtils::convertPercentageToSignalStrengtStr(int percentage) { + + if (percentage <= 0 || percentage > 100) { + return ""; } - else - NMLOG_WARNING("security mode not defined (flag: %d, wpaFlags: %d, rsnFlags: %d)", flags, wpaFlags, rsnFlags); - return security; - } - std::string nmUtils::getSecurityModeString(guint32 flags, guint32 wpaFlags, guint32 rsnFlags) + /* + * -30 dBm to -50 dBm: Excellent signal strength. + * -50 dBm to -60 dBm: Very good signal strength. + * -60 dBm to -70 dBm: Good signal strength; acceptable for basic internet browsing. + * -70 dBm to -80 dBm: Weak signal; performance may degrade, slower speeds, and possible dropouts. + * -80 dBm to -90 dBm: Very poor signal; likely unusable or highly unreliable. + * Below -90 dBm: Disconnected or too weak to establish a stable connection. + */ + + // dBm range: -30 dBm (strong) to -90 dBm (weak) + const int max_dBm = -30; + const int min_dBm = -90; + int dBm_value = max_dBm + ((min_dBm - max_dBm) * (100 - percentage)) / 100; + static char result[8]={0}; + snprintf(result, sizeof(result), "%d", dBm_value); + return result; + } + + std::string nmUtils::getSecurityModeString(guint32 flag, guint32 wpaFlags, guint32 rsnFlags) { - switch(flags) + std::string securityStr = "[AP type: "; + if (flag == NM_802_11_AP_FLAGS_NONE) + securityStr += "NONE "; + else { - case NM_802_11_AP_FLAGS_NONE: - NMLOG_DEBUG("ap type : point has no special capabilities"); - break; - case NM_802_11_AP_FLAGS_PRIVACY: - NMLOG_DEBUG("ap type : access point requires authentication and encryption"); - break; - case NM_802_11_AP_FLAGS_WPS: - NMLOG_DEBUG("ap type : access point supports some WPS method"); - break; - case NM_802_11_AP_FLAGS_WPS_PBC: - NMLOG_DEBUG("ap type : access point supports push-button WPS"); - break; - case NM_802_11_AP_FLAGS_WPS_PIN: - NMLOG_DEBUG("ap type : access point supports PIN-based WPS"); - break; - default: - NMLOG_ERROR("ap type : 802.11 flags unknown!"); + if ((flag & NM_802_11_AP_FLAGS_PRIVACY) != 0) + securityStr += "PRIVACY "; + if ((flag & NM_802_11_AP_FLAGS_WPS) != 0) + securityStr += "WPS "; + if ((flag & NM_802_11_AP_FLAGS_WPS_PBC) != 0) + securityStr += "WPS_PBC "; + if ((flag & NM_802_11_AP_FLAGS_WPS_PIN) != 0) + securityStr += "WPS_PIN "; } + securityStr += "] "; - std::string securityStr; - - if (!(flags & NM_802_11_AP_FLAGS_PRIVACY) && (wpaFlags != NM_802_11_AP_SEC_NONE) && (rsnFlags != NM_802_11_AP_SEC_NONE)) + if (!(flag & NM_802_11_AP_FLAGS_PRIVACY) && (wpaFlags != NM_802_11_AP_SEC_NONE) && (rsnFlags != NM_802_11_AP_SEC_NONE)) securityStr += ("Encrypted: "); - if ((flags & NM_802_11_AP_FLAGS_PRIVACY) && (wpaFlags == NM_802_11_AP_SEC_NONE) + if ((flag & NM_802_11_AP_FLAGS_PRIVACY) && (wpaFlags == NM_802_11_AP_SEC_NONE) && (rsnFlags == NM_802_11_AP_SEC_NONE)) securityStr += ("WEP "); if (wpaFlags != NM_802_11_AP_SEC_NONE) @@ -124,7 +142,7 @@ namespace WPEFramework } uint32_t flags[2] = { wpaFlags, rsnFlags }; - securityStr += "[ WPA Flags: "; + securityStr += "[WPA: "; for (int i = 0; i < 2; ++i) { @@ -158,10 +176,10 @@ namespace WPEFramework securityStr += "wpa-eap-suite-b-192 "; if (i == 0) { - securityStr += "] [ RSN Flags: "; + securityStr += "] [RSN: "; } } - securityStr +="]"; + securityStr +="] "; return securityStr; } @@ -263,22 +281,11 @@ namespace WPEFramework return upperStr1 == upperStr2; } - bool nmUtils::GetInterfacesName(std::string &wifiIfname ,std::string ðIfname) + bool nmUtils::getInterfacesName() { std::string line; - static bool fileParsingCompleted = false; - static std::string m_wifiIfname; - static std::string m_ethIfname; // cached interface name - wifiIfname.clear(); - ethIfname.clear(); - if(fileParsingCompleted) - { - if(!m_wifiIfname.empty()) - wifiIfname = m_wifiIfname; - if(!m_ethIfname.empty()) - ethIfname = m_ethIfname; - return true; - } + std::string wifiIfname; + std::string ethIfname; // cached interface name std::ifstream file("/etc/device.properties"); if (!file.is_open()) { @@ -308,9 +315,9 @@ namespace WPEFramework NMLOG_FATAL("Could not find any interface name in /etc/device.properties"); return false; } - m_wifiIfname = wifiIfname; - m_ethIfname = ethIfname; - fileParsingCompleted = true; + m_wlanifname = wifiIfname; + m_ethifname = ethIfname; + NMLOG_INFO("/etc/device.properties eth: %s, wlan: %s", m_ethifname.c_str(), m_wlanifname.c_str()); return true; } } // Plugin diff --git a/NetworkManagerGnomeUtils.h b/NetworkManagerGnomeUtils.h index c52a5a73..f55e808f 100644 --- a/NetworkManagerGnomeUtils.h +++ b/NetworkManagerGnomeUtils.h @@ -33,13 +33,17 @@ namespace WPEFramework { public: - static bool GetInterfacesName(std::string &wifiIfname ,std::string ðIfname); + static bool getInterfacesName(); + static const char* wlanIface(); + static const char* ethIface(); + static const char* convertPercentageToSignalStrengtStr(int percentage); static bool caseInsensitiveCompare(const std::string& str1, const std::string& str2); static uint8_t wifiSecurityModeFromAp(guint32 flags, guint32 wpaFlags, guint32 rsnFlags); static std::string wifiFrequencyFromAp(guint32 apFreq); static std::string getSecurityModeString(guint32 flags, guint32 wpaFlags, guint32 rsnFlags); static JsonObject apToJsonObject(NMAccessPoint *ap); static void printActiveSSIDsOnly(NMDeviceWifi *wifiDevice); + static NMDeviceState ifaceState(NMClient *client, const char* interface); }; } diff --git a/NetworkManagerGnomeWIFI.cpp b/NetworkManagerGnomeWIFI.cpp index b2ae798b..a16b4456 100644 --- a/NetworkManagerGnomeWIFI.cpp +++ b/NetworkManagerGnomeWIFI.cpp @@ -28,6 +28,7 @@ #include "INetworkManager.h" #include "NetworkManagerGnomeWIFI.h" #include "NetworkManagerGnomeUtils.h" +#include "NetworkManagerImplementation.h" using namespace std; namespace WPEFramework @@ -48,6 +49,7 @@ namespace WPEFramework }; namespace Plugin { + extern NetworkManagerImplementation* _instance; wifiManager::wifiManager() : client(nullptr), loop(nullptr), createNewConnection(false) { NMLOG_INFO("wifiManager"); @@ -131,9 +133,14 @@ namespace WPEFramework return wifiDevice; } - for (guint j = 0; j < devices->len; j++) { + for (guint j = 0; j < devices->len; j++) + { NMDevice *device = NM_DEVICE(devices->pdata[j]); - if (nm_device_get_device_type(device) == NM_DEVICE_TYPE_WIFI) + const char* interface = nm_device_get_iface(device); + if(interface == nullptr) + continue; + std::string iface = interface; + if (iface == nmUtils::wlanIface()) { wifiDevice = device; //NMLOG_DEBUG("Wireless Device found ifce : %s !", nm_device_get_iface (wifiDevice)); @@ -228,7 +235,7 @@ namespace WPEFramework wifiInfo.rate = std::to_string(bitrate); NMLOG_DEBUG("bitrate : %s kbit/s", wifiInfo.rate.c_str()); //TODO signal strenght to dBm - wifiInfo.strength = std::to_string(static_cast(strength)); + wifiInfo.strength = std::string(nmUtils::convertPercentageToSignalStrengtStr(strength)); NMLOG_DEBUG("sterngth: %s %%", wifiInfo.strength.c_str()); wifiInfo.security = static_cast(nmUtils::wifiSecurityModeFromAp(flags, wpaFlags, rsnFlags)); NMLOG_DEBUG("security %s", nmUtils::getSecurityModeString(flags, wpaFlags, rsnFlags).c_str()); @@ -248,7 +255,7 @@ namespace WPEFramework NMAccessPoint *activeAP = nm_device_wifi_get_active_access_point(wifiDevice); if(activeAP == NULL) { - NMLOG_ERROR("No active access point found !"); + NMLOG_DEBUG("No active access point found !"); return false; } else @@ -269,7 +276,7 @@ namespace WPEFramework NMAccessPoint *activeAP = nm_device_wifi_get_active_access_point(wifiDevice); if(activeAP == NULL) { - NMLOG_ERROR("No active access point found !"); + NMLOG_DEBUG("No active access point found !"); return false; } else @@ -309,39 +316,39 @@ namespace WPEFramework NMDevice *wifiNMDevice = getNmDevice(); if(wifiNMDevice == NULL) { - NMLOG_DEBUG("NMDeviceWifi NULL !"); + NMLOG_ERROR("NMDeviceWifi NULL !"); return false; } nm_device_disconnect_async(wifiNMDevice, NULL, wifiDisconnectCb, this); wait(loop); - NMLOG_DEBUG("Exit"); return isSuccess; } - static NMAccessPoint *checkSSIDAvailable(NMDevice *device, const GPtrArray *aps, const char *ssid) + static NMAccessPoint *checkSSIDAvailable(NMDevice *device, const char *ssid) { - NMAccessPoint *AccessPoint = NULL; + NMAccessPoint *AccessPoint = NULL; + const GPtrArray *aps = NULL; + if(ssid == NULL) + return NULL; + aps = nm_device_wifi_get_access_points(NM_DEVICE_WIFI(device)); for (guint i = 0; i < aps->len; i++) { - NMAccessPoint *candidate_ap = static_cast(g_ptr_array_index(aps, i)); - if (ssid) + NMAccessPoint *ap = static_cast(g_ptr_array_index(aps, i)); + GBytes *ssidGBytes; + ssidGBytes = nm_access_point_get_ssid(ap); + if (!ssidGBytes) + continue; + gsize size; + const guint8 *ssidData = static_cast(g_bytes_get_data(ssidGBytes, &size)); + std::string ssidstr(reinterpret_cast(ssidData), size); + //g_bytes_unref(ssidGBytes); + // NMLOG_DEBUG("ssid < %s >", ssidstr.c_str()); + if (strcmp(ssid, ssidstr.c_str()) == 0) { - GBytes *ssidGBytes; - ssidGBytes = nm_access_point_get_ssid(candidate_ap); - if (!ssidGBytes) - continue; - gsize size; - const guint8 *ssidData = static_cast(g_bytes_get_data(ssidGBytes, &size)); - std::string ssidstr(reinterpret_cast(ssidData), size); - //g_bytes_unref(ssidGBytes); - // NMLOG_DEBUG("ssid < %s >", ssidstr.c_str()); - if (strcmp(ssid, ssidstr.c_str()) == 0) - { - AccessPoint = candidate_ap; - break; - } + AccessPoint = ap; + break; } } @@ -376,6 +383,24 @@ namespace WPEFramework g_main_loop_quit(_wifiManager->loop); } + static void removeKnownSSIDCb(GObject *client, GAsyncResult *result, gpointer user_data) + { + GError *error = NULL; + wifiManager *_wifiManager = (static_cast(user_data)); + NMRemoteConnection *connection = NM_REMOTE_CONNECTION(client); + if (!nm_remote_connection_delete_finish(connection, result, &error)) { + NMLOG_ERROR("RemoveKnownSSID failed %s", error->message); + _wifiManager->isSuccess = false; + } + else + { + NMLOG_INFO ("RemoveKnownSSID is success"); + _wifiManager->isSuccess = true; + } + + _wifiManager->quit(NULL); + } + static void wifiConnectionUpdate(GObject *rmObject, GAsyncResult *res, gpointer user_data) { NMRemoteConnection *remote_con = NM_REMOTE_CONNECTION(rmObject); @@ -397,245 +422,236 @@ namespace WPEFramework _wifiManager->client, NM_CONNECTION(remote_con), _wifiManager->wifidevice, _wifiManager->objectPath, NULL, wifiConnectCb, _wifiManager); } - bool wifiManager::wifiConnect(Exchange::INetworkManager::WiFiConnectTo wifiData) + static bool connectionBuilder(const Exchange::INetworkManager::WiFiConnectTo& ssidinfo, NMConnection *m_connection) { - const char *ssid_in = wifiData.ssid.c_str(); - const char* password_in = wifiData.passphrase.c_str(); - NMAccessPoint *AccessPoint = NULL; - GPtrArray *allaps = NULL; - const char *conName = ssid_in; - NMConnection *connection = NULL; - NMSettingConnection *sConnection = NULL; - NMSetting8021x *s8021X = NULL; - NMSettingWireless *sWireless = NULL; - NMSettingWirelessSecurity *sSecurity = NULL; - NM80211ApFlags apFlags; - NM80211ApSecurityFlags apWpaFlags; - NM80211ApSecurityFlags apRsnFlags; - const char *ifname = NULL; - const GPtrArray *availableConnections; - bool SSIDmatch = false; - Exchange::INetworkManager::WiFiSSIDInfo apinfo; - - if(!createClientNewConnection()) - return false; - - if (strlen(ssid_in) > 32) + if(ssidinfo.ssid.empty() || ssidinfo.ssid.length() > 32) { - NMLOG_WARNING("ssid length grater than 32"); + NMLOG_WARNING("ssid name is missing or invalied"); return false; } + /* Build up the 'connection' Setting */ + NMSettingConnection *sConnection = (NMSettingConnection *) nm_setting_connection_new(); + const char *uuid = nm_utils_uuid_generate(); + g_object_set(G_OBJECT(sConnection), NM_SETTING_CONNECTION_UUID, uuid, NULL); // uuid + g_object_set(G_OBJECT(sConnection), NM_SETTING_CONNECTION_ID, ssidinfo.ssid.c_str(), NULL); // connection id = ssid + g_object_set(G_OBJECT(sConnection), NM_SETTING_CONNECTION_INTERFACE_NAME, "wlan0", NULL); // interface name + g_object_set(G_OBJECT(sConnection), NM_SETTING_CONNECTION_TYPE, "802-11-wireless", NULL); // type 802.11wireless + nm_connection_add_setting(m_connection, NM_SETTING(sConnection)); - NMDevice *device = NULL; - device = getNmDevice(); - if(device == NULL) - return false; - wifidevice = device; + /* Build up the '802-11-wireless-security' settings */ + NMSettingWireless *sWireless = NULL; + sWireless = (NMSettingWireless *)nm_setting_wireless_new(); + nm_connection_add_setting(m_connection, NM_SETTING(sWireless)); + GBytes *ssid = g_bytes_new(ssidinfo.ssid.c_str(), strlen(ssidinfo.ssid.c_str())); + g_object_set(G_OBJECT(sWireless), NM_SETTING_WIRELESS_SSID, ssid, NULL); // ssid in Gbyte + g_object_set(G_OBJECT(sWireless), NM_SETTING_WIRELESS_MODE, NM_SETTING_WIRELESS_MODE_INFRA, NULL); // infra mode + g_object_set(G_OBJECT(sWireless), NM_SETTING_WIRELESS_HIDDEN, true, NULL); // hidden = true + // 'bssid' parameter is used to restrict the connection only to the BSSID + // g_object_set(s_wifi, NM_SETTING_WIRELESS_BSSID, bssid, NULL); - std::string activeSSID; - if(getConnectedSSID(NM_DEVICE_WIFI(wifidevice), activeSSID)) + NMSettingWirelessSecurity *sSecurity = NULL; + switch(ssidinfo.security) { - if(strcmp(ssid_in, activeSSID.c_str()) == 0) + case Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WPA_PSK_AES: + case Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WPA_WPA2_PSK: + case Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WPA_PSK_TKIP: + case Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WPA2_PSK_AES: + case Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WPA2_PSK_TKIP: + case Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WPA3_SAE: { - NMLOG_WARNING("ssid already connected !"); - return true; + if(ssidinfo.passphrase.empty() || ssidinfo.passphrase.length() < 8) + { + NMLOG_WARNING("password legth should be > 8"); + return false; + } + + sSecurity = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new(); + nm_connection_add_setting(m_connection, NM_SETTING(sSecurity)); + if(Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WPA3_SAE == ssidinfo.security) + { + NMLOG_INFO("key-mgmt: %s", "sae"); + g_object_set(G_OBJECT(sSecurity), NM_SETTING_WIRELESS_SECURITY_KEY_MGMT,"sae", NULL); + } + else + { + NMLOG_INFO("key-mgmt: %s", "wpa-psk"); + g_object_set(G_OBJECT(sSecurity), NM_SETTING_WIRELESS_SECURITY_KEY_MGMT,"wpa-psk", NULL); + } + g_object_set(G_OBJECT(sSecurity), NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", NULL); + g_object_set(G_OBJECT(sSecurity), NM_SETTING_WIRELESS_SECURITY_PSK, ssidinfo.passphrase.c_str(), NULL); + break; } - else + case Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WPA_ENTERPRISE_TKIP: + case Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WPA_ENTERPRISE_AES: + case Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WPA2_ENTERPRISE_TKIP: + case Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WPA2_ENTERPRISE_AES: + case Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WPA_WPA2_ENTERPRISE: { - NMLOG_WARNING("wifi already connected with %s AP", activeSSID.c_str()); - } - } - //NMLOG_DEBUG("Wireless Device found ifce : %s !", ifname = nm_device_get_iface(device)); - AccessPoint = checkSSIDAvailable(device, allaps, ssid_in); - // TODO Scann hidden ssid also for lnf - if(AccessPoint == NULL) { - NMLOG_WARNING("No network with SSID '%s' found !", ssid_in); - // TODO send SSID NO AVAILABLE event - return false; - } - - getApInfo(AccessPoint, apinfo); + NMSetting8021x *s8021X = NULL; + GError *error = NULL; + + NMLOG_INFO("key-mgmt: %s", "802.1X"); + NMLOG_DEBUG("802.1x Identity : %s", ssidinfo.eap_identity.c_str()); + NMLOG_DEBUG("802.1x CA cert path : %s", ssidinfo.ca_cert.c_str()); + NMLOG_DEBUG("802.1x Client cert path : %s", ssidinfo.client_cert.c_str()); + NMLOG_DEBUG("802.1x Private key path : %s", ssidinfo.private_key.c_str()); + NMLOG_DEBUG("802.1x Private key psswd : %s", ssidinfo.private_key_passwd.c_str()); + + s8021X = (NMSetting8021x *) nm_setting_802_1x_new(); + nm_connection_add_setting(m_connection, NM_SETTING(s8021X)); + g_object_set(s8021X, NM_SETTING_802_1X_IDENTITY, ssidinfo.eap_identity.c_str(), NULL); + nm_setting_802_1x_add_eap_method(s8021X, "tls"); + if(!ssidinfo.ca_cert.empty() && !nm_setting_802_1x_set_ca_cert(s8021X, + ssidinfo.ca_cert.c_str(), + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, + &error)) + { + NMLOG_ERROR("ca certificate add failed: %s", error->message); + g_error_free(error); + return false; + } - availableConnections = nm_device_get_available_connections(device); - for (guint i = 0; i < availableConnections->len; i++) - { - NMConnection *currentConnection = static_cast(g_ptr_array_index(availableConnections, i)); - const char *id = nm_connection_get_id(NM_CONNECTION(currentConnection)); + if(!ssidinfo.client_cert.empty() && !nm_setting_802_1x_set_client_cert(s8021X, + ssidinfo.client_cert.c_str(), + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, + &error)) + { + NMLOG_ERROR("client certificate add failed: %s", error->message); + g_error_free(error); + return false; + } - if (conName) { - if (!id || strcmp(id, conName)) - continue; + if(!ssidinfo.private_key.empty() && !nm_setting_802_1x_set_private_key(s8021X, + ssidinfo.private_key.c_str(), + ssidinfo.private_key_passwd.c_str(), + NM_SETTING_802_1X_CK_SCHEME_PATH, + NULL, + &error)) + { + NMLOG_ERROR("client private key add failed: %s", error->message); + g_error_free(error); + return false; + } - SSIDmatch = TRUE; + sSecurity = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new(); + nm_connection_add_setting(m_connection, NM_SETTING(sSecurity)); + g_object_set(G_OBJECT(sSecurity), NM_SETTING_WIRELESS_SECURITY_KEY_MGMT,"wpa-eap", NULL); + break; } - - if (nm_access_point_connection_valid(AccessPoint, NM_CONNECTION(currentConnection))) { - connection = g_object_ref(currentConnection); - NMLOG_DEBUG("Connection '%s' exists !", conName); + case Exchange::INetworkManager::WIFI_SECURITY_NONE: + { + NMLOG_INFO("key-mgmt: %s", "none"); + sSecurity = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new(); + nm_connection_add_setting(m_connection, NM_SETTING(sSecurity)); + g_object_set(G_OBJECT(sSecurity), NM_SETTING_WIRELESS_SECURITY_KEY_MGMT,"none", NULL); + NMLOG_WARNING("open wifi network configuration"); break; } + default: + { + NMLOG_ERROR("wifi securtity type not supported %d", ssidinfo.security); + return false; + } } - if (SSIDmatch && !connection) - { - NMLOG_ERROR("Connection '%s' exists but properties don't match", conName); - //TODO Remove Connection - return false; - } + /* 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 + nm_connection_add_setting(m_connection, NM_SETTING(sIpv4Conf)); - if (!connection) - { - NMLOG_DEBUG("creating new connection '%s' ", conName); - connection = nm_simple_connection_new(); - if (conName) { - sConnection = (NMSettingConnection *) nm_setting_connection_new(); - nm_connection_add_setting(connection, NM_SETTING(sConnection)); - const char *uuid = nm_utils_uuid_generate();; - - g_object_set(G_OBJECT(sConnection), - NM_SETTING_CONNECTION_UUID, - uuid, - NM_SETTING_CONNECTION_ID, - conName, - NM_SETTING_CONNECTION_TYPE, - "802-11-wireless", - NULL); - } + /* 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 + nm_connection_add_setting(m_connection, NM_SETTING(sIpv6Conf)); + return true; + } - sWireless = (NMSettingWireless *)nm_setting_wireless_new(); - GBytes *ssid = g_bytes_new(ssid_in, strlen(ssid_in)); - g_object_set(G_OBJECT(sWireless), - NM_SETTING_WIRELESS_SSID, - ssid, - NULL); - //g_bytes_unref(ssid); - /* For lnf network need to include - * - * 'bssid' parameter is used to restrict the connection only to the BSSID - * g_object_set(s_wifi, NM_SETTING_WIRELESS_BSSID, bssid, NULL); - * g_object_set(s_wifi, NM_SETTING_WIRELESS_SSID, ssid, NM_SETTING_WIRELESS_HIDDEN, hidden, NULL); - */ - nm_connection_add_setting(connection, NM_SETTING(sWireless)); - } - - apFlags = nm_access_point_get_flags(AccessPoint); - apWpaFlags = nm_access_point_get_wpa_flags(AccessPoint); - apRsnFlags = nm_access_point_get_rsn_flags(AccessPoint); - - // check ap flag ty securti we supporting - if(apFlags != NM_802_11_AP_FLAGS_NONE && strlen(password_in) < 1 && !(apFlags & NM_802_11_AP_FLAGS_WPS)) - { - NMLOG_ERROR("This ap(%s) security need password please add password!", ssid_in); - return false; - } + bool wifiManager::wifiConnect(Exchange::INetworkManager::WiFiConnectTo ssidInfo) + { + NMAccessPoint *AccessPoint = NULL; + NMConnection *m_connection = NULL; + const GPtrArray *availableConnections; + bool SSIDmatch = false; + isSuccess = false; - if ( (apRsnFlags & NM_802_11_AP_SEC_KEY_MGMT_OWE) || (apRsnFlags & NM_802_11_AP_SEC_KEY_MGMT_OWE_TM)) { + if(!createClientNewConnection()) + return false; - NMLOG_ERROR("Ap wifi security OWE"); + NMDevice *device = getNmDevice(); + if(device == NULL) return false; - } - if( (apWpaFlags & NM_802_11_AP_SEC_KEY_MGMT_802_1X) || (apRsnFlags & NM_802_11_AP_SEC_KEY_MGMT_802_1X) ) + std::string activeSSID; + if(getConnectedSSID(NM_DEVICE_WIFI(device), activeSSID)) { - GError *error = NULL; - NMLOG_INFO("Ap securtity mode is 802.1X"); - - NMLOG_DEBUG("802.1x Identity : %s", wifiData.eap_identity.c_str()); - NMLOG_DEBUG("802.1x CA cert path : %s", wifiData.ca_cert.c_str()); - NMLOG_DEBUG("802.1x Client cert path : %s", wifiData.client_cert.c_str()); - NMLOG_DEBUG("802.1x Private key path : %s", wifiData.private_key.c_str()); - NMLOG_DEBUG("802.1x Private key psswd : %s", wifiData.private_key_passwd.c_str()); - - s8021X = (NMSetting8021x *) nm_setting_802_1x_new(); - nm_connection_add_setting(connection, NM_SETTING(s8021X)); - - g_object_set(s8021X, NM_SETTING_802_1X_IDENTITY, wifiData.eap_identity.c_str(), NULL); - nm_setting_802_1x_add_eap_method(s8021X, "tls"); - if(!wifiData.ca_cert.empty() && !nm_setting_802_1x_set_ca_cert(s8021X, - wifiData.ca_cert.c_str(), - NM_SETTING_802_1X_CK_SCHEME_PATH, - NULL, - &error)) + if(ssidInfo.ssid == activeSSID) { - NMLOG_ERROR("ca certificate add failed: %s", error->message); - g_error_free(error); - return false; + NMLOG_INFO("ssid already connected !"); + return true; } + else + NMLOG_DEBUG("wifi already connected with %s AP", activeSSID.c_str()); + } - if(!wifiData.client_cert.empty() && !nm_setting_802_1x_set_client_cert(s8021X, - wifiData.client_cert.c_str(), - NM_SETTING_802_1X_CK_SCHEME_PATH, - NULL, - &error)) - { - NMLOG_ERROR("client certificate add failed: %s", error->message); - g_error_free(error); - return false; - } + AccessPoint = checkSSIDAvailable(device, ssidInfo.ssid.c_str()); + if(AccessPoint == NULL) { + NMLOG_WARNING("SSID '%s' not found !", ssidInfo.ssid.c_str()); + if(_instance != nullptr) + _instance->ReportWiFiStateChange(Exchange::INetworkManager::WIFI_STATE_SSID_NOT_FOUND); + return false; + } - if(!wifiData.private_key.empty() && !nm_setting_802_1x_set_private_key(s8021X, - wifiData.private_key.c_str(), - wifiData.private_key_passwd.c_str(), - NM_SETTING_802_1X_CK_SCHEME_PATH, - NULL, - &error)) - { - NMLOG_ERROR("client private key add failed: %s", error->message); - g_error_free(error); - return false; - } + Exchange::INetworkManager::WiFiSSIDInfo apinfo; + getApInfo(AccessPoint, apinfo); - sSecurity = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new(); - nm_connection_add_setting(connection, NM_SETTING(sSecurity)); - g_object_set(G_OBJECT(sSecurity), NM_SETTING_WIRELESS_SECURITY_KEY_MGMT,"wpa-eap", NULL); - } - else if ((apFlags & NM_802_11_AP_FLAGS_PRIVACY) || (apWpaFlags != NM_802_11_AP_SEC_NONE )|| (apRsnFlags != NM_802_11_AP_SEC_NONE )) + availableConnections = nm_device_get_available_connections(device); + for (guint i = 0; i < availableConnections->len; i++) { - NMLOG_INFO("%s ap securtity mode (%s) supported !", ssid_in, nmUtils::getSecurityModeString(apFlags,apWpaFlags,apRsnFlags).c_str()); - - if (password_in) + NMConnection *connection = static_cast(g_ptr_array_index(availableConnections, i)); + const char *connId = nm_connection_get_id(NM_CONNECTION(connection)); + if (connId != NULL && strcmp(connId, ssidInfo.ssid.c_str()) == 0) { - sSecurity = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new(); - nm_connection_add_setting(connection, NM_SETTING(sSecurity)); - - if (apWpaFlags == NM_802_11_AP_SEC_NONE && apRsnFlags == NM_802_11_AP_SEC_NONE) - { - nm_setting_wireless_security_set_wep_key(sSecurity, 0, password_in); - NMLOG_ERROR("wifi security WEP mode not supported ! need to add wep-key-type"); - return false; + if (nm_access_point_connection_valid(AccessPoint, NM_CONNECTION(connection))) { + m_connection = g_object_ref(connection); + NMLOG_DEBUG("connection '%s' exists !", ssidInfo.ssid.c_str()); + if (m_connection == NULL) + { + NMLOG_ERROR("m_connection == NULL smothing went worng"); + return false; + } + break; } - else if ((apWpaFlags & NM_802_11_AP_SEC_KEY_MGMT_PSK) - || (apRsnFlags & NM_802_11_AP_SEC_KEY_MGMT_PSK) || (apRsnFlags & NM_802_11_AP_SEC_KEY_MGMT_SAE)) { - - g_object_set(G_OBJECT(sSecurity), NM_SETTING_WIRELESS_SECURITY_KEY_MGMT,"wpa-psk", NULL); - g_object_set(G_OBJECT(sSecurity), NM_SETTING_WIRELESS_SECURITY_PSK, password_in, NULL); + else + { + if (NM_IS_REMOTE_CONNECTION(connection)) + { + /* + * libnm reuses the existing connection if new settings match the AP properties; + * remove the old one because now only one connection per SSID is supported. + */ + NMLOG_WARNING(" '%s' connection exist but properties miss match; deleting...", ssidInfo.ssid.c_str()); + nm_remote_connection_delete_async(NM_REMOTE_CONNECTION(connection), + NULL, + removeKnownSSIDCb, + this); + } } } - else - { - NMLOG_ERROR("This AccessPoint(%s) need password please add password!", ssid_in); - return false; - } } - else + + if (NM_IS_REMOTE_CONNECTION(m_connection)) { - /* for open network every flag value will be zero */ - if (apFlags == NM_802_11_AP_FLAGS_NONE && apWpaFlags == NM_802_11_AP_SEC_NONE && apRsnFlags == NM_802_11_AP_SEC_NONE) { - NMLOG_INFO("open network no password requied"); - } - else { - NMLOG_ERROR("wifi security mode not supported !"); + if(!connectionBuilder(ssidInfo, m_connection)) + { + NMLOG_ERROR("connection builder failed"); return false; } - } - - objectPath = nm_object_get_path(NM_OBJECT(AccessPoint)); - GVariant *nmDbusConnection = nm_connection_to_dbus(connection, NM_CONNECTION_SERIALIZE_ALL); - if (NM_IS_REMOTE_CONNECTION(connection)) - { - nm_remote_connection_update2(NM_REMOTE_CONNECTION(connection), - nmDbusConnection, - NM_SETTINGS_UPDATE2_FLAG_BLOCK_AUTOCONNECT, // autoconnect right away + GVariant *connSettings = nm_connection_to_dbus(m_connection, NM_CONNECTION_SERIALIZE_ALL); + nm_remote_connection_update2(NM_REMOTE_CONNECTION(m_connection), + connSettings, + NM_SETTINGS_UPDATE2_FLAG_BLOCK_AUTOCONNECT, // block auto connect becuse manualy activate NULL, NULL, wifiConnectionUpdate, @@ -643,27 +659,57 @@ namespace WPEFramework } else { + NMLOG_DEBUG("creating new connection '%s' ", ssidInfo.ssid.c_str()); + m_connection = nm_simple_connection_new(); + objectPath = nm_object_get_path(NM_OBJECT(AccessPoint)); + if(!connectionBuilder(ssidInfo, m_connection)) + { + NMLOG_ERROR("connection builder failed"); + return false; + } createNewConnection = true; - nm_client_add_and_activate_connection_async(client, connection, device, objectPath, NULL, wifiConnectCb, this); + nm_client_add_and_activate_connection_async(client, m_connection, device, objectPath, NULL, wifiConnectCb, this); } wait(loop); return isSuccess; } - static void addToKnownSSIDsCb(GObject *client, GAsyncResult *result, gpointer user_data) + static void addToKnownSSIDsUpdateCb(GObject *rmObject, GAsyncResult *res, gpointer user_data) { + NMRemoteConnection *remote_con = NM_REMOTE_CONNECTION(rmObject); + wifiManager *_wifiManager = (static_cast(user_data)); + GVariant *ret = NULL; + GError *error = NULL; + ret = nm_remote_connection_update2_finish(remote_con, res, &error); + + if (!ret) { + NMLOG_ERROR("Error: %s.", error->message); + g_error_free(error); + _wifiManager->isSuccess = false; + NMLOG_ERROR("AddToKnownSSIDs failed"); + } + else + { + _wifiManager->isSuccess = true; + NMLOG_INFO("AddToKnownSSIDs success"); + } + _wifiManager->quit(NULL); + } + + static void addToKnownSSIDsCb(GObject *client, GAsyncResult *result, gpointer user_data) + { GError *error = NULL; wifiManager *_wifiManager = (static_cast(user_data)); - //NMRemoteConnection *connection = NM_REMOTE_CONNECTION(s); - if (!nm_client_add_connection_finish(NM_CLIENT(client), result, &error)) { - NMLOG_ERROR ("AddToKnownSSIDs Failed"); + GVariant **outResult = NULL; + if (!nm_client_add_connection2_finish(NM_CLIENT(client), result, outResult, &error)) { + NMLOG_ERROR("AddToKnownSSIDs Failed"); _wifiManager->isSuccess = false; } else { - NMLOG_DEBUG ("AddToKnownSSIDs is success"); + NMLOG_INFO("AddToKnownSSIDs success"); _wifiManager->isSuccess = true; } @@ -672,129 +718,108 @@ namespace WPEFramework bool wifiManager::addToKnownSSIDs(const Exchange::INetworkManager::WiFiConnectTo ssidinfo) { + isSuccess = false; + NMConnection *m_connection = NULL; + if(!createClientNewConnection()) return false; - NMSettingWirelessSecurity *nmSettingsWifiSec; - NMSettingWireless *nmSettingsWifi; - const char *uuid = nm_utils_uuid_generate(); + NMDevice *device = getNmDevice(); + if(device == NULL) + return false; - nmSettingsWifiSec = (NMSettingWirelessSecurity *)nm_setting_wireless_security_new(); - NMSettingConnection *nmConnSec = (NMSettingConnection *)nm_setting_connection_new(); - g_object_set(G_OBJECT(nmConnSec), - NM_SETTING_CONNECTION_UUID, - uuid, - NM_SETTING_CONNECTION_ID, - ssidinfo.ssid.c_str(), - NM_SETTING_CONNECTION_TYPE, - "802-11-wireless", - NULL); - NMConnection *connection = nm_simple_connection_new(); - nm_connection_add_setting(connection, NM_SETTING(nmConnSec)); - nmSettingsWifi = (NMSettingWireless *)nm_setting_wireless_new(); - GString *ssidStr = g_string_new(ssidinfo.ssid.c_str()); - g_object_set(G_OBJECT(nmSettingsWifi), NM_SETTING_WIRELESS_SSID, ssidStr, NULL); - - nm_connection_add_setting(connection, NM_SETTING(nmSettingsWifi)); - nmSettingsWifiSec = (NMSettingWirelessSecurity *)nm_setting_wireless_security_new(); - // TODO chek different securtity mode and portocol and add settings - switch(ssidinfo.security) + const GPtrArray *availableConnections = nm_device_get_available_connections(device); + for (guint i = 0; i < availableConnections->len; i++) { - case Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WPA_PSK_AES: - case Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WPA_WPA2_PSK: - case Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WPA_PSK_TKIP: - case Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WPA2_PSK_AES: - case Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WPA2_PSK_TKIP: - case Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WPA3_SAE: + NMConnection *connection = static_cast(g_ptr_array_index(availableConnections, i)); + const char *connId = nm_connection_get_id(NM_CONNECTION(connection)); + if (connId != NULL && strcmp(connId, ssidinfo.ssid.c_str()) == 0) { - g_object_set(G_OBJECT(nmSettingsWifiSec), NM_SETTING_WIRELESS_SECURITY_KEY_MGMT,"wpa-psk", NULL); - if(!ssidinfo.passphrase.empty()) - g_object_set(G_OBJECT(nmSettingsWifiSec), NM_SETTING_WIRELESS_SECURITY_PSK, ssidinfo.passphrase.c_str(), NULL); - break; + m_connection = g_object_ref(connection); } - case Exchange::INetworkManager::WIFI_SECURITY_NONE: - NMLOG_INFO("open wifi network configuration"); - break; - default: + } + + if (NM_IS_REMOTE_CONNECTION(m_connection)) + { + if(!connectionBuilder(ssidinfo, m_connection)) { - NMLOG_WARNING("connection wifi securtity type not supported"); + NMLOG_ERROR("connection builder failed"); return false; } - } - - nm_connection_add_setting(connection, NM_SETTING(nmSettingsWifiSec)); - nm_client_add_connection_async(client, connection, true, NULL, addToKnownSSIDsCb, this); - //wait(loop); - // TODO change to GmainLoooprun - g_main_loop_unref(loop); - return isSuccess; - } - - static void removeKnownSSIDCb(GObject *client, GAsyncResult *result, gpointer user_data) - { - GError *error = NULL; - wifiManager *_wifiManager = (static_cast(user_data)); - NMRemoteConnection *connection = NM_REMOTE_CONNECTION(client); - if (!nm_remote_connection_delete_finish(connection, result, &error)) { - NMLOG_ERROR("RemoveKnownSSID failed %s", error->message); - _wifiManager->isSuccess = false; + NMLOG_DEBUG("update exsisting connection '%s' ", ssidinfo.ssid.c_str()); + GVariant *connSettings = nm_connection_to_dbus(m_connection, NM_CONNECTION_SERIALIZE_ALL); + nm_remote_connection_update2(NM_REMOTE_CONNECTION(m_connection), + connSettings, + NM_SETTINGS_UPDATE2_FLAG_TO_DISK, + NULL, + NULL, + addToKnownSSIDsUpdateCb, + this); } else { - NMLOG_INFO ("RemoveKnownSSID is success"); - _wifiManager->isSuccess = true; + NMLOG_DEBUG("creating new connection '%s' ", ssidinfo.ssid.c_str()); + m_connection = nm_simple_connection_new(); + if(!connectionBuilder(ssidinfo, m_connection)) + { + NMLOG_ERROR("connection builder failed"); + return false; + } + createNewConnection = true; + GVariant *connSettings = nm_connection_to_dbus(m_connection, NM_CONNECTION_SERIALIZE_ALL); + nm_client_add_connection2(client, + connSettings, + NM_SETTINGS_ADD_CONNECTION2_FLAG_TO_DISK, + NULL, TRUE, NULL, + addToKnownSSIDsCb, this); } - - g_main_loop_quit(_wifiManager->loop); + wait(loop); + return isSuccess; } bool wifiManager::removeKnownSSID(const string& ssid) { + NMConnection *m_connection = NULL; + isSuccess = false; if(!createClientNewConnection()) return false; if(ssid.empty()) + { + NMLOG_ERROR("ssid is empty"); return false; - isSuccess = false; - - NMRemoteConnection* remoteConnection; - const GPtrArray* connections = nm_client_get_connections(client); + } - for (guint i = 0; i < connections->len; i++) + const GPtrArray *allconnections = nm_client_get_connections(client); + for (guint i = 0; i < allconnections->len; i++) { - remoteConnection = NM_REMOTE_CONNECTION(connections->pdata[i]); - NMConnection *connection = NM_CONNECTION(connections->pdata[i]); - if (NM_IS_SETTING_WIRELESS(nm_connection_get_setting_wireless(connection))) + NMConnection *connection = static_cast(g_ptr_array_index(allconnections, i)); + if (!NM_IS_SETTING_WIRELESS(nm_connection_get_setting_wireless(connection))) + continue; // if not wireless connection skipt + const char *connId = nm_connection_get_id(NM_CONNECTION(connection)); + if(connId == NULL) + continue; + NMLOG_DEBUG("wireless connection '%s'", connId); + if (strcmp(connId, ssid.c_str()) == 0) { - GBytes *ssidBytes = nm_setting_wireless_get_ssid(nm_connection_get_setting_wireless(connection)); - if (ssidBytes) + m_connection = g_object_ref(connection); + if (NM_IS_REMOTE_CONNECTION(m_connection)) { - gsize ssidSize; - const guint8 *ssidData = static_cast(g_bytes_get_data(ssidBytes, &ssidSize)); - std::string ssidstr(reinterpret_cast(ssidData), ssidSize); - if (ssid == ssidstr) - { - //nm_remote_connection_delete_async(remoteConnection, NULL, removeKnownSSIDCb, this); - // TODO add async - GError *error = NULL; - nm_remote_connection_delete(remoteConnection, NULL, &error); - if (error) - { - NMLOG_ERROR("RemoveKnownSSID failed %s", error->message); - g_error_free(error); - } - else - { - NMLOG_INFO("RemoveKnownSSID is success %s", ssid.c_str()); - isSuccess = true; - } - break; // if remove all connection with same ssid not to break - } + NMLOG_INFO("deleting '%s' connection...", ssid.c_str()); + nm_remote_connection_delete_async(NM_REMOTE_CONNECTION(m_connection), + NULL, + removeKnownSSIDCb, + this); } + wait(loop); + break; // multiple connection with same name not handiled } } - + + if(!m_connection) + NMLOG_INFO("'%s' no such connection profile", ssid.c_str()); + return isSuccess; } @@ -856,7 +881,7 @@ namespace WPEFramework g_main_loop_quit(_wifiManager->loop); } - bool wifiManager::wifiScanRequest(std::string frequency, std::string ssidReq) + bool wifiManager::wifiScanRequest(std::string ssidReq) { if(!createClientNewConnection()) return false; @@ -866,7 +891,7 @@ namespace WPEFramework return false; } isSuccess = false; - if(!ssidReq.empty()) + if(!ssidReq.empty() && ssidReq != "null") { NMLOG_INFO("staring wifi scanning .. %s", ssidReq.c_str()); GVariantBuilder builder, array_builder; @@ -877,7 +902,6 @@ namespace WPEFramework g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, (const guint8 *) ssidReq.c_str(), ssidReq.length(), 1) ); g_variant_builder_add(&builder, "{sv}", "ssids", g_variant_builder_end(&array_builder)); - g_variant_builder_add(&builder, "{sv}", "hidden", g_variant_new_boolean(TRUE)); options = g_variant_builder_end(&builder); nm_device_wifi_request_scan_options_async(wifiDevice, options, NULL, wifiScanCb, this); } diff --git a/NetworkManagerGnomeWIFI.h b/NetworkManagerGnomeWIFI.h index 9ad556b8..4a646225 100644 --- a/NetworkManagerGnomeWIFI.h +++ b/NetworkManagerGnomeWIFI.h @@ -46,8 +46,8 @@ namespace WPEFramework bool wifiDisconnect(); bool wifiConnectedSSIDInfo(Exchange::INetworkManager::WiFiSSIDInfo &ssidinfo); bool wifiConnect(Exchange::INetworkManager::WiFiConnectTo wifiData); - bool wifiScanRequest(std::string frequency, std::string ssidReq = ""); - bool isWifiScannedRecently(int timelimitInSec = 10); // default 10 sec as shotest scanning interval + bool wifiScanRequest(std::string ssidReq = ""); + bool isWifiScannedRecently(int timelimitInSec = 5); // default 10 sec as shotest scanning interval bool getKnownSSIDs(std::list& ssids); bool addToKnownSSIDs(const Exchange::INetworkManager::WiFiConnectTo ssidinfo); bool removeKnownSSID(const string& ssid); diff --git a/NetworkManagerJsonRpc.cpp b/NetworkManagerJsonRpc.cpp index 9b0a8ed3..8feedf50 100644 --- a/NetworkManagerJsonRpc.cpp +++ b/NetworkManagerJsonRpc.cpp @@ -723,7 +723,7 @@ namespace WPEFramework { uint32_t rc = Core::ERROR_GENERAL; Exchange::INetworkManager::WiFiConnectTo ssid{}; - NMLOG_INFO("Entry to %s\n", __FUNCTION__); + NMLOG_INFO("Entry to %s", __FUNCTION__); if (parameters.HasLabel("ssid") && parameters.HasLabel("passphrase")) { @@ -764,7 +764,7 @@ namespace WPEFramework { uint32_t rc = Core::ERROR_GENERAL; Exchange::INetworkManager::WiFiConnectTo ssid{}; - NMLOG_INFO("Entry to %s\n", __FUNCTION__); + NMLOG_INFO("Entry to %s", __FUNCTION__); if (parameters.HasLabel("ssid")) ssid.ssid = parameters["ssid"].String(); diff --git a/NetworkManagerRDKProxy.cpp b/NetworkManagerRDKProxy.cpp index 517e135f..8099a3cc 100644 --- a/NetworkManagerRDKProxy.cpp +++ b/NetworkManagerRDKProxy.cpp @@ -825,7 +825,7 @@ namespace WPEFramework strncpy(iarmData.interface, "ETHERNET", INTERFACE_SIZE); else if (!interface.empty()) { - NMLOG_ERROR("Given interface (%s) is NOT supported\n", interface.c_str()); + NMLOG_ERROR("Given interface (%s) is NOT supported", interface.c_str()); return Core::ERROR_NOT_SUPPORTED; } diff --git a/WiFiSignalStrengthMonitor.cpp b/WiFiSignalStrengthMonitor.cpp index 09b33cc2..27243b3b 100644 --- a/WiFiSignalStrengthMonitor.cpp +++ b/WiFiSignalStrengthMonitor.cpp @@ -28,7 +28,7 @@ namespace WPEFramework FILE *fp = popen(command, "r"); if (!fp) { - NMLOG_ERROR("Failed in getting output from command %s \n",command); + NMLOG_ERROR("Failed in getting output from command %s",command); return keystr; }