diff --git a/LegacyPlugin_WiFiManagerAPIs.cpp b/LegacyPlugin_WiFiManagerAPIs.cpp index a86631c..3369132 100644 --- a/LegacyPlugin_WiFiManagerAPIs.cpp +++ b/LegacyPlugin_WiFiManagerAPIs.cpp @@ -544,13 +544,31 @@ namespace WPEFramework returnJson(rc); } - uint32_t WiFiManager::startScan(const JsonObject& parameters, JsonObject& response) + uint32_t WiFiManager::startScan(const JsonObject& parameters, JsonObject& response) { LOG_INPARAM(); uint32_t rc = Core::ERROR_GENERAL; - string frequency = parameters["frequency"].String(); + string frequency{}; Exchange::INetworkManager::IStringIterator* ssids = NULL; + + if (parameters.HasLabel("frequency")) + frequency = parameters["frequency"].String(); + + if (parameters.HasLabel("ssid")) + { + string inputSSID = parameters["ssid"].String(); + string ssid{}; + vector inputSSIDlist; + stringstream ssidStream(inputSSID); + while (getline(ssidStream, ssid, '|')) + { + inputSSIDlist.push_back(ssid); + } + + ssids = (Core::Service::Create(inputSSIDlist)); + } + auto _nwmgr = m_service->QueryInterfaceByCallsign(NETWORK_MANAGER_CALLSIGN); if (_nwmgr) { @@ -560,6 +578,9 @@ namespace WPEFramework else rc = Core::ERROR_UNAVAILABLE; + if (ssids) + ssids->Release(); + returnJson(rc); } diff --git a/NetworkManagerGnomeEvents.cpp b/NetworkManagerGnomeEvents.cpp index c5c5c72..3b745b7 100644 --- a/NetworkManagerGnomeEvents.cpp +++ b/NetworkManagerGnomeEvents.cpp @@ -617,7 +617,6 @@ namespace WPEFramework return; } JsonArray ssidList = JsonArray(); - string ssidListJson; NMAccessPoint *ap = nullptr; const GPtrArray *accessPoints = nm_device_wifi_get_access_points(wifiDevice); for (guint i = 0; i < accessPoints->len; i++) @@ -628,13 +627,11 @@ namespace WPEFramework ssidList.Add(ssidObj); } - ssidList.ToString(ssidListJson); NMLOG_INFO("No of AP Available = %d", static_cast(accessPoints->len)); - //NMLOG_DEBUG("Scanned APIs are = %s",ssidListJson.c_str()); if(_nmEventInstance->doScanNotify) { _nmEventInstance->doScanNotify = false; - _instance->ReportAvailableSSIDs(ssidListJson); + _instance->ReportAvailableSSIDs(ssidList); } } diff --git a/NetworkManagerGnomeProxy.cpp b/NetworkManagerGnomeProxy.cpp index 9a00cc8..fe1fadd 100644 --- a/NetworkManagerGnomeProxy.cpp +++ b/NetworkManagerGnomeProxy.cpp @@ -528,10 +528,29 @@ namespace WPEFramework uint32_t NetworkManagerImplementation::StartWiFiScan(const string& frequency /* @in */, IStringIterator* const ssids/* @in */) { uint32_t rc = Core::ERROR_RPC_CALL_FAILED; - (void) ssids; + + //Cleared the Existing Store filterred SSID list + m_filterSsidslist.clear(); + m_filterfrequency.clear(); + + if(ssids) + { + string tmpssidlist{}; + while (ssids->Next(tmpssidlist) == true) + { + m_filterSsidslist.push_back(tmpssidlist.c_str()); + NMLOG_DEBUG("%s added to SSID filtering", tmpssidlist.c_str()); + } + } + + if (!frequency.empty()) + { + m_filterfrequency = frequency; + NMLOG_DEBUG("Scan SSIDs of frequency %s", m_filterfrequency.c_str()); + } nmEvent->setwifiScanOptions(true); - if(wifi->wifiScanRequest(frequency)) + if(wifi->wifiScanRequest(m_filterfrequency)) rc = Core::ERROR_NONE; return rc; } @@ -669,6 +688,11 @@ namespace WPEFramework uint32_t NetworkManagerImplementation::StartWPS(const WiFiWPS& method /* @in */, const string& wps_pin /* @in */) { uint32_t rc = Core::ERROR_NONE; + if(method == WIFI_WPS_SERIALIZED_PIN || method == WIFI_WPS_PIN) + { + NMLOG_ERROR("WPS PIN method is not supported as of now"); + return Core::ERROR_RPC_CALL_FAILED; + } if(wifi->initiateWPS()) NMLOG_INFO ("startWPS success"); else diff --git a/NetworkManagerGnomeWIFI.cpp b/NetworkManagerGnomeWIFI.cpp index 22d8a1f..64be901 100644 --- a/NetworkManagerGnomeWIFI.cpp +++ b/NetworkManagerGnomeWIFI.cpp @@ -948,7 +948,6 @@ namespace WPEFramework void wifiManager::wpsAction() { FILE *fp = nullptr; - std::ifstream configFile(WPA_SUPPLICANT_CONF); std::string line = ""; std::string securityPattern = "key_mgmt="; std::string ssidPattern = "ssid="; @@ -960,8 +959,15 @@ namespace WPEFramework gboolean wpsConnect = false; struct timespec startTime = {}, endTime = {}; long timeDiff = 0; + int count = 0; + bool scanResult = false; + bool ssidFound = false; + const char* bssid = nullptr; + gboolean pbcFound = false; + const GPtrArray *aps; - if (!g_main_context_acquire(wpsContext)) + + if (!wpsContext || !g_main_context_acquire(wpsContext)) { NMLOG_ERROR("Failed to acquire wpsContext"); return; @@ -969,7 +975,37 @@ namespace WPEFramework g_main_context_push_thread_default(wpsContext); - std::string wpaCliCommand = "wpa_cli -i " + std::string(nmUtils::wlanIface()) + " wps_pbc"; + do{ + sleep(10); + loop = g_main_loop_new(wpsContext, FALSE); + scanResult = wifiScanRequest(""); + loop = g_main_loop_new(nmContext, FALSE); + if(scanResult) + { + aps = nm_device_wifi_get_access_points(NM_DEVICE_WIFI(getWifiDevice())); + for (guint i = 0; i < aps->len; i++) { + NMAccessPoint *ap = static_cast(g_ptr_array_index(aps, i)); + guint32 flags = nm_access_point_get_flags(ap); + + if (flags & NM_802_11_AP_FLAGS_WPS_PBC) + { + bssid = nm_access_point_get_bssid(ap); + pbcFound = true; + break; + } + } + } + count++; + }while(count < 10 && !pbcFound && !wpsStop.load()); + + if(!pbcFound || wpsStop.load()) + { + g_main_context_pop_thread_default(wpsContext); + g_main_context_release(wpsContext); + return; + } + + std::string wpaCliCommand = "wpa_cli disconnect && wpa_cli -i " + std::string(nmUtils::wlanIface()) + " abort_scan && wpa_cli -i " + std::string(nmUtils::wlanIface()) + " bss_flush 0 && wpa_cli -i " + std::string(nmUtils::wlanIface()) + " wps_pbc " + std::string(bssid); fp = popen(wpaCliCommand.c_str(), "r"); if (fp == nullptr) { @@ -993,13 +1029,16 @@ namespace WPEFramework { wpaCliResult += buffer.data(); } + pclose(fp); wpsConnect = (wpaCliResult.find("wpa_state=COMPLETED") != std::string::npos); clock_gettime(CLOCK_MONOTONIC, &endTime); timeDiff = (endTime.tv_sec - startTime.tv_sec); NMLOG_DEBUG("Time elapsed before getting wifi connected = %ld", timeDiff); - if(wpsConnect || timeDiff > 120) + if(wpsConnect || timeDiff > 20) + { + NMLOG_WARNING("WPS Connect status = %d; took %ld seconds", wpsConnect, (100 + timeDiff)); break; - pclose(fp); + } sleep(5); } @@ -1010,7 +1049,10 @@ namespace WPEFramework return; } + count = 0; + while(count < 2 && !ssidFound) { + std::ifstream configFile(WPA_SUPPLICANT_CONF); if (!configFile.is_open()) { NMLOG_ERROR("WPS connected with an SSID but not able to fetch IP address"); @@ -1021,22 +1063,9 @@ namespace WPEFramework while (std::getline(configFile, line)) { + NMLOG_DEBUG("Attempting to read the configuration to populate SSID specific information"); size_t pos; - // Fetch security value - pos = line.find(securityPattern); - if (pos != std::string::npos) - { - pos += securityPattern.length(); - size_t end = line.find(' ', pos); - if (end == std::string::npos) - { - end = line.length(); - } - security = line.substr(pos, end - pos); - continue; - } - // Fetch ssid value pos = line.find(ssidPattern); if (pos != std::string::npos) @@ -1048,37 +1077,64 @@ namespace WPEFramework end = line.length(); } ssid = line.substr(pos + 1, end - pos - 1); + ssidFound = true; + NMLOG_DEBUG("SSID found"); continue; } - // Fetch passphare value - pos = line.find(passphrasePattern); - if (pos != std::string::npos) - { - pos += passphrasePattern.length(); - size_t end = line.find('"', pos + 1); - if (end == std::string::npos) + if (ssidFound) { + // Fetch security value + pos = line.find(securityPattern); + if (pos != std::string::npos) { - end = line.length(); + pos += securityPattern.length(); + size_t end = line.find(' ', pos); + if (end == std::string::npos) + { + end = line.length(); + } + security = line.substr(pos, end - pos); + continue; } - passphrase = line.substr(pos + 1, end - pos - 1); - continue; + + // Fetch passphare value + pos = line.find(passphrasePattern); + if (pos != std::string::npos) + { + pos += passphrasePattern.length(); + size_t end = line.find('"', pos + 1); + if (end == std::string::npos) + { + end = line.length(); + } + passphrase = line.substr(pos + 1, end - pos - 1); + } + NMLOG_DEBUG("Fetched SSID = %s, security = %s", ssid.c_str(), security.c_str()); } } - configFile.close(); - wifiData.ssid = ssid; - wifiData.passphrase = passphrase; - if(security == "WPA-PSK") - wifiData.security = Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WPA_PSK_AES; - else if(security == "WPA2-PSK") - wifiData.security = Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WPA2_PSK_AES; - } - if(this->wifiConnect(wifiData)) - NMLOG_INFO("WPS connected successfully"); - else - NMLOG_ERROR("WPS connect failed");/* TODO: Need to disconnect the wpa_cli connection, as the libnm is not aware of the connection created by wpa_cli */ - + if(ssid.empty()) + { + count++; + NMLOG_INFO("connected successfully; attempting to retrive SSID info to persist"); + sleep(5); + } + else + { + wifiData.ssid = ssid; + wifiData.passphrase = passphrase; + if(security == "WPA-PSK") + wifiData.security = Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WPA_PSK_AES; + else if(security == "WPA2-PSK") + wifiData.security = Exchange::INetworkManager::WIFISecurityMode::WIFI_SECURITY_WPA2_PSK_AES; + loop = g_main_loop_new(wpsContext, FALSE); + if(this->wifiConnect(wifiData)) + NMLOG_INFO("NetworkManager updated with WPS status - connected successfully"); + else + NMLOG_ERROR("NetworkManager is not able to sync up with underneath wpa_supplicant/hal regarding the WPS connect"); /* TODO: Need to disconnect the wpa_cli connection, as the libnm is not aware of the connection created by wpa_cli */ + loop = g_main_loop_new(nmContext, FALSE); + } + } g_main_context_pop_thread_default(wpsContext); g_main_context_release(wpsContext); if (wpsContext) { @@ -1090,14 +1146,15 @@ namespace WPEFramework bool wifiManager::initiateWPS() { - if (!createClientNewConnection()) - return false; - if(!wpsContext){ if (wpsThread.joinable()) { wpsThread.join(); } wpsContext = g_main_context_new(); + if (!wpsContext) { + NMLOG_ERROR("Failed to create new main context for WPS"); + return false; + } wpsThread = std::thread(&wifiManager::wpsAction, this); } else diff --git a/NetworkManagerImplementation.cpp b/NetworkManagerImplementation.cpp index 66b0d0f..f08fe09 100644 --- a/NetworkManagerImplementation.cpp +++ b/NetworkManagerImplementation.cpp @@ -490,6 +490,56 @@ namespace WPEFramework return; } + + void NetworkManagerImplementation::filterScanResults(JsonArray &ssids) + { + JsonArray result; + double filterFreq = 0.0; + std::unordered_set scanForSsidsSet(m_filterSsidslist.begin(), m_filterSsidslist.end()); + + // If neither SSID list nor frequency is provided, exit + if (m_filterSsidslist.empty() && m_filterfrequency.empty()) + { + NMLOG_DEBUG("Neither SSID nor Frequency is provided. Exiting function."); + return; + } + + if (!m_filterfrequency.empty()) + { + filterFreq = std::stod(m_filterfrequency); + NMLOG_DEBUG("Frequency provided: %lf\n", filterFreq); + } + + for (int i = 0; i < ssids.Length(); i++) + { + JsonObject object = ssids[i].Object(); + string ssid = object["ssid"].String(); + string frequency = object["frequency"].String(); + + NMLOG_DEBUG("Processing SSID: %s, Frequency: %s\n", ssid.c_str(), frequency.c_str()); + + double frequencyValue = std::stod(frequency); + + //Debug to print log + NMLOG_DEBUG("Processing Frequency after double conversion: %lf\n", frequencyValue); + + bool ssidMatches = scanForSsidsSet.empty() || scanForSsidsSet.find(ssid) != scanForSsidsSet.end(); + bool freqMatches = m_filterfrequency.empty() || (filterFreq == frequencyValue); + + if (ssidMatches && freqMatches) + { + result.Add(object); + NMLOG_DEBUG("Match found: SSID = %s, Frequency = %lf\n", ssid.c_str(), frequencyValue); + } + else + { + NMLOG_DEBUG("No match: SSID = %s, Frequency = %lf\n", ssid.c_str(), frequencyValue); + } + } + ssids = result; + NMLOG_DEBUG("After filtering, found %d SSIDs.", ssids.Length()); + } + // WiFi Specific Methods /* @brief Initiate a WIFI Scan; This is Async method and returns the scan results as Event */ uint32_t NetworkManagerImplementation::GetSupportedSecurityModes(ISecurityModeIterator*& securityModes /* @out */) const @@ -581,12 +631,22 @@ namespace WPEFramework _notificationLock.Unlock(); } - void NetworkManagerImplementation::ReportAvailableSSIDs(const string jsonOfWiFiScanResults) + void NetworkManagerImplementation::ReportAvailableSSIDs(JsonArray &arrayofWiFiScanResults) { _notificationLock.Lock(); - NMLOG_INFO("Posting onAvailableSSIDs result is, %s", jsonOfWiFiScanResults.c_str()); + string jsonOfWiFiScanResults; + string jsonOfFilterScanResults; + + arrayofWiFiScanResults.ToString(jsonOfWiFiScanResults); + NMLOG_DEBUG("Posting onAvailableSSIDs result before Filtering is, %s", jsonOfWiFiScanResults.c_str()); + + filterScanResults(arrayofWiFiScanResults); + + arrayofWiFiScanResults.ToString(jsonOfFilterScanResults); + + NMLOG_INFO("Posting onAvailableSSIDs result is, %s", jsonOfFilterScanResults.c_str()); for (const auto callback : _notificationCallbacks) { - callback->onAvailableSSIDs(jsonOfWiFiScanResults); + callback->onAvailableSSIDs(jsonOfFilterScanResults); } _notificationLock.Unlock(); } diff --git a/NetworkManagerImplementation.h b/NetworkManagerImplementation.h index a9cdcaf..64767f9 100644 --- a/NetworkManagerImplementation.h +++ b/NetworkManagerImplementation.h @@ -219,7 +219,7 @@ namespace WPEFramework void ReportActiveInterfaceChange(const string prevActiveInterface, const string currentActiveinterface); void ReportIPAddressChange(const string interface, const string ipversion, const string ipaddress, const Exchange::INetworkManager::IPStatus status); void ReportInternetStatusChange(const Exchange::INetworkManager::InternetStatus prevState, const Exchange::INetworkManager::InternetStatus currState); - void ReportAvailableSSIDs(const string jsonOfScanResults); + void ReportAvailableSSIDs(JsonArray &arrayofWiFiScanResults); void ReportWiFiStateChange(const Exchange::INetworkManager::WiFiState state); void ReportWiFiSignalStrengthChange(const string ssid, const string strength, const Exchange::INetworkManager::WiFiSignalQuality quality); @@ -233,6 +233,7 @@ namespace WPEFramework void getInitialConnectionState(); void threadEventRegistration(); void executeExternally(NetworkEvents event, const string commandToExecute, string& response); + void filterScanResults(JsonArray &ssids); private: std::list _notificationCallbacks; @@ -245,7 +246,10 @@ namespace WPEFramework uint16_t m_stunBindTimeout; uint16_t m_stunCacheTimeout; std::thread m_registrationThread; - public: + string m_filterfrequency; + std::vector m_filterSsidslist; + + public: WiFiSignalStrengthMonitor m_wifiSignalMonitor; mutable ConnectivityMonitor connectivityMonitor; }; diff --git a/NetworkManagerJsonRpc.cpp b/NetworkManagerJsonRpc.cpp index bb143f0..1079443 100644 --- a/NetworkManagerJsonRpc.cpp +++ b/NetworkManagerJsonRpc.cpp @@ -667,14 +667,42 @@ namespace WPEFramework { LOG_INPARAM(); uint32_t rc = Core::ERROR_GENERAL; - string frequency = parameters["frequency"].String(); - Exchange::INetworkManager::IStringIterator* ssids = NULL; + string frequency{}; + Exchange::INetworkManager::IStringIterator* ssids = NULL; + + if (parameters.HasLabel("frequency")) + frequency = parameters["frequency"].String(); + + if (parameters.HasLabel("ssids")) + { + JsonArray array = parameters["ssids"].Array(); + std::vector ssidslist; + JsonArray::Iterator index(array.Elements()); + + while (index.Next() == true) + { + if (Core::JSON::Variant::type::STRING == index.Current().Content()) + { + ssidslist.push_back(index.Current().String().c_str()); + } + else + { + NMLOG_ERROR("Unexpected variant type in SSID array."); + returnJson(rc); + } + } + ssids = (Core::Service::Create(ssidslist)); + } if (_networkManager) rc = _networkManager->StartWiFiScan(frequency, ssids); else rc = Core::ERROR_UNAVAILABLE; + if (ssids) + ssids->Release(); + + returnJson(rc); } diff --git a/NetworkManagerRDKProxy.cpp b/NetworkManagerRDKProxy.cpp index a6b7d15..4578571 100644 --- a/NetworkManagerRDKProxy.cpp +++ b/NetworkManagerRDKProxy.cpp @@ -505,10 +505,8 @@ namespace WPEFramework } JsonArray ssids = eventDocument["getAvailableSSIDs"].Array(); - string json; - ssids.ToString(json); - ::_instance->ReportAvailableSSIDs(json); + ::_instance->ReportAvailableSSIDs(ssids); break; } case IARM_BUS_WIFI_MGR_EVENT_onWIFIStateChanged: @@ -1085,8 +1083,25 @@ const string CIDR_PREFIXES[CIDR_NETMASK_IP_LEN+1] = { IARM_Bus_WiFiSrvMgr_SsidList_Param_t param{}; IARM_Result_t retVal = IARM_RESULT_SUCCESS; - (void)ssids; - (void) frequency; + //Cleared the Existing Store filterred SSID list + m_filterSsidslist.clear(); + m_filterfrequency.clear(); + + if(ssids) + { + string ssidlist{}; + while (ssids->Next(ssidlist) == true) + { + m_filterSsidslist.push_back(ssidlist.c_str()); + NMLOG_DEBUG("%s added to SSID filtering", ssidlist.c_str()); + } + } + + if (!frequency.empty()) + { + m_filterfrequency = frequency; + NMLOG_DEBUG("Scan SSIDs of frequency %s", m_filterfrequency.c_str()); + } memset(¶m, 0, sizeof(param));