From a69c19becf5e371ae8c0a5e15875d61d0954e0dd Mon Sep 17 00:00:00 2001 From: cmuhammedrafi Date: Tue, 1 Oct 2024 17:30:30 +0530 Subject: [PATCH] getavailablessid --- Tests/dbus-api-test/CMakeLists.txt | 10 +- ...ient.cpp => NetworkManagerGnomeClient.cpp} | 117 ++++++++++++-- ...erClient.h => NetworkManagerGnomeClient.h} | 9 +- .../NetworkManagerGnomeUtils.cpp | 153 ++++++++++++++++++ .../dbus-api-test/NetworkManagerGnomeUtils.h | 50 ++++++ Tests/dbus-api-test/dbusConnectionManager.h | 42 ----- Tests/dbus-api-test/main.cpp | 18 +-- Tests/dbus-api-test/utils.h | 52 ++++++ 8 files changed, 375 insertions(+), 76 deletions(-) rename Tests/dbus-api-test/{networkManagerClient.cpp => NetworkManagerGnomeClient.cpp} (63%) rename Tests/dbus-api-test/{networkManagerClient.h => NetworkManagerGnomeClient.h} (69%) create mode 100644 Tests/dbus-api-test/NetworkManagerGnomeUtils.cpp create mode 100644 Tests/dbus-api-test/NetworkManagerGnomeUtils.h create mode 100644 Tests/dbus-api-test/utils.h diff --git a/Tests/dbus-api-test/CMakeLists.txt b/Tests/dbus-api-test/CMakeLists.txt index 1684ef61..e603f71f 100644 --- a/Tests/dbus-api-test/CMakeLists.txt +++ b/Tests/dbus-api-test/CMakeLists.txt @@ -10,14 +10,18 @@ pkg_check_modules(GIO REQUIRED gio-2.0) include_directories( ${GLIB_INCLUDE_DIRS} ${GIO_INCLUDE_DIRS} + /usr/include/NetworkManager/libnm ) +# Force the compiler to include utils.h automatically +add_compile_options(-include ${CMAKE_SOURCE_DIR}/utils.h) + add_executable( NmDbusClient - main.cpp + main.cpp dbusConnectionManager.cpp - networkManagerClient.cpp - wpaSupplicantClient.cpp + NetworkManagerGnomeClient.cpp + NetworkManagerGnomeUtils.cpp ) target_link_libraries( diff --git a/Tests/dbus-api-test/networkManagerClient.cpp b/Tests/dbus-api-test/NetworkManagerGnomeClient.cpp similarity index 63% rename from Tests/dbus-api-test/networkManagerClient.cpp rename to Tests/dbus-api-test/NetworkManagerGnomeClient.cpp index d80a5479..f78fe4f9 100644 --- a/Tests/dbus-api-test/networkManagerClient.cpp +++ b/Tests/dbus-api-test/NetworkManagerGnomeClient.cpp @@ -1,4 +1,4 @@ -#include "networkManagerClient.h" +#include "NetworkManagerGnomeClient.h" #include "dbusConnectionManager.h" NetworkManagerClient::NetworkManagerClient() { @@ -12,6 +12,24 @@ NetworkManagerClient::~NetworkManagerClient() { NMLOG_INFO("NetworkManagerClient destroyed"); } +static void printKeyVariant(const char *setting_name, GVariant *setting) +{ + GVariantIter iter; + const char *property_name; + GVariant *value; + char *printed_value; + + NMLOG_VERBOSE(" %s:", setting_name); + g_variant_iter_init(&iter, setting); + while (g_variant_iter_next(&iter, "{&sv}", &property_name, &value)) { + printed_value = g_variant_print(value, FALSE); + if (strcmp(printed_value, "[]") != 0) + NMLOG_VERBOSE(" %s: %s", property_name, printed_value); + g_free(printed_value); + g_variant_unref(value); + } +} + static void fetssidandbssid(GVariant *setting80211, std::string &ssid, std::string &bssid) { GVariantIter iter; @@ -31,7 +49,7 @@ static void fetssidandbssid(GVariant *setting80211, std::string &ssid, std::stri if (g_variant_iter_next(&bssid_iter, "s", &bssid_elem)) { bssid = bssid_elem; - NMLOG_TRACE("BSSID: %s", bssid.c_str()); + NMLOG_VERBOSE("BSSID: %s", bssid.c_str()); } //g_variant_iter_free(&bssid_iter); @@ -58,7 +76,7 @@ static bool fetchSSIDFromConnection(const char *path, std::list& ss { GError *error = NULL; GDBusProxy *ConnProxy = NULL; - GVariant *settingsProxy= NULL, *connection= NULL, *s_con= NULL; + GVariant *settingsProxy= NULL, *connection= NULL, *sCon= NULL; bool isFound; const char *connId= NULL, *connTyp= NULL, *iface= NULL; ConnProxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, @@ -89,14 +107,11 @@ static bool fetchSSIDFromConnection(const char *path, std::list& ss } g_variant_get(settingsProxy, "(@a{sa{sv}})", &connection); - s_con = g_variant_lookup_value(connection, "connection", NULL); - g_assert(s_con != NULL); - isFound = g_variant_lookup(s_con, "type", "&s", &connTyp); - g_assert(isFound); - isFound = g_variant_lookup(s_con, "interface-name", "&s", &iface); - g_assert(isFound); - - // NMLOG_TRACE("type= %s, iface= %s", connTyp, iface); + sCon = g_variant_lookup_value(connection, "connection", NULL); + g_assert(sCon != NULL); // TODO change error return + G_VARIANT_LOOKUP(sCon, "type", "&s", &connTyp); + G_VARIANT_LOOKUP(sCon, "interface-name", "&s", &iface); + NMLOG_VERBOSE("type= %s, iface= %s", connTyp, iface); if(strcmp(connTyp,"802-11-wireless") == 0 && strcmp(iface,"wlan0") == 0) { GVariant *setting = g_variant_lookup_value(connection, "802-11-wireless", NULL); @@ -109,8 +124,8 @@ static bool fetchSSIDFromConnection(const char *path, std::list& ss } } - if (s_con) - g_variant_unref(s_con); + if (sCon) + g_variant_unref(sCon); if (connection) g_variant_unref(connection); if (settingsProxy) @@ -153,7 +168,7 @@ static bool fetchConnectionPaths(GDBusProxy *proxy, std::list& path } for (int i = 0; paths[i]; i++) { - //NMLOG_INFO("Connection path: %s", paths[i]); + NMLOG_VERBOSE("Connection path: %s", paths[i]); pathsList.push_back(paths[i]); } @@ -190,7 +205,7 @@ bool NetworkManagerClient::getKnownSSIDs(std::list& ssids) if(fetchConnectionPaths(sProxy, paths)) { for (const std::string& path : paths) { - NMLOG_TRACE("connection path %s", path.c_str()); + NMLOG_VERBOSE("connection path %s", path.c_str()); fetchSSIDFromConnection(path.c_str(), ssids); } } @@ -201,3 +216,75 @@ bool NetworkManagerClient::getKnownSSIDs(std::list& ssids) return false; return true; } + +bool NetworkManagerClient::getConnectedSSID() +{ + std::string wifiDevicePath; + if(!GnomeUtils::getDeviceByIpIface(dbusConnection.getConnection(),"wlan0", wifiDevicePath)) + { + NMLOG_ERROR("no wifi device found"); + return false; + } + NMLOG_TRACE("wifi device path %s", wifiDevicePath.c_str()); + //TODO check active connection path and return properties + return true; +} + +bool NetworkManagerClient::getavilableSSID(std::list& ssids) +{ + // TODO Wifi device state fix it + GError* error = nullptr; + GDBusProxy* wProxy = nullptr; + std::string wifiDevicePath; + + if(!GnomeUtils::getDeviceByIpIface(dbusConnection.getConnection(),"wlan0", wifiDevicePath)) + { + NMLOG_ERROR("no wifi device found"); + return false; + } + NMLOG_TRACE("wifi device path %s", wifiDevicePath.c_str()); + + wProxy = g_dbus_proxy_new_sync(dbusConnection.getConnection(), + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "org.freedesktop.NetworkManager", + wifiDevicePath.c_str(), + "org.freedesktop.NetworkManager.Device.Wireless", + NULL, // GCancellable + &error); + + if (error) { + NMLOG_ERROR("Error creating proxy: %s", error->message); + g_error_free(error); + return false; + } + + GVariant* result = g_dbus_proxy_call_sync(wProxy, "GetAccessPoints", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); + // TODO change to GetAllAccessPoints to include hidden ssid + if (error) { + NMLOG_ERROR("Error creating proxy: %s", error->message); + g_error_free(error); + g_object_unref(wProxy); + return false; + } + + GVariantIter* iter; + const gchar* apPath; + g_variant_get(result, "(ao)", &iter); + + while (g_variant_iter_loop(iter, "o", &apPath)) { + apProperties apDetails; + NMLOG_VERBOSE("Access Point Path: %s", apPath); + if(!GnomeUtils::getApDetails(dbusConnection.getConnection(), apPath, apDetails)) + { + NMLOG_WARNING("getApDetails failed"); + } + } + + g_variant_iter_free(iter); + g_variant_unref(result); + g_object_unref(wProxy); + + return true; +} + diff --git a/Tests/dbus-api-test/networkManagerClient.h b/Tests/dbus-api-test/NetworkManagerGnomeClient.h similarity index 69% rename from Tests/dbus-api-test/networkManagerClient.h rename to Tests/dbus-api-test/NetworkManagerGnomeClient.h index 6f3527bf..8ce2c1ac 100644 --- a/Tests/dbus-api-test/networkManagerClient.h +++ b/Tests/dbus-api-test/NetworkManagerGnomeClient.h @@ -1,16 +1,19 @@ #pragma once - -#include "dbusConnectionManager.h" #include #include +#include "dbusConnectionManager.h" +#include "NetworkManagerGnomeUtils.h" + + class NetworkManagerClient { public: NetworkManagerClient(); ~NetworkManagerClient(); bool getKnownSSIDs(std::list& ssids); - + bool getavilableSSID(std::list& ssids); + bool getConnectedSSID(); private: DbusConnectionManager dbusConnection; }; diff --git a/Tests/dbus-api-test/NetworkManagerGnomeUtils.cpp b/Tests/dbus-api-test/NetworkManagerGnomeUtils.cpp new file mode 100644 index 00000000..68f894e9 --- /dev/null +++ b/Tests/dbus-api-test/NetworkManagerGnomeUtils.cpp @@ -0,0 +1,153 @@ + +#include +#include +#include +#include + +#include "NetworkManagerGnomeUtils.h" + +// Function to get device path by network interface name +bool GnomeUtils::getDeviceByIpIface(GDBusConnection *connection, const gchar *iface_name, std::string& path) +{ + GError *error = NULL; + GVariant *result; + gchar *device_path = NULL; + bool ret = false; + + // // Connect to the system bus + // connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + // if (error != NULL) { + // g_printerr("Error connecting to system bus: %s\n", error->message); + // g_error_free(error); + // return NULL; + // } + + result = g_dbus_connection_call_sync( + connection, + "org.freedesktop.NetworkManager", // D-Bus name + "/org/freedesktop/NetworkManager", // Object path + "org.freedesktop.NetworkManager", // Interface + "GetDeviceByIpIface", // Method name + g_variant_new("(s)", iface_name), // Input parameter (the interface name) + G_VARIANT_TYPE("(o)"), // Expected return type (object path) + G_DBUS_CALL_FLAGS_NONE, + -1, // Default timeout + NULL, + &error + ); + + if (error != NULL) { + NMLOG_ERROR("calling GetDeviceByIpIface: %s", error->message); + g_error_free(error); + return ret; + } + + g_variant_get(result, "(o)", &device_path); + if(g_strdup(device_path) != NULL) + { + path = std::string(g_strdup(device_path)); + ret = true; + } + + g_variant_unref(result); + return ret; +} + +static bool get_cached_property_u(GDBusProxy* proxy, const char* propertiy, uint32_t value) +{ + GVariant* result = NULL; + result = g_dbus_proxy_get_cached_property(proxy, propertiy); + if (!result) { + NMLOG_ERROR("Failed to get AP properties"); + g_object_unref(proxy); + return false; + } + g_variant_get(result, "u", &value); + NMLOG_TRACE("%s: %d", propertiy, value); + g_variant_unref(result); + return true; +} + +/* +Flags readable u +WpaFlags readable u +RsnFlags readable u +Ssid readable ay +Frequency readable u +HwAddress readable s +Mode readable u +MaxBitrate readable u +Bandwidth readable u +Strength readable y +LastSeen readable i +*/ +bool GnomeUtils::getApDetails(GDBusConnection *connection, const char* apPath, apProperties& apDetails) +{ + char *bssid = NULL; + uint8_t strength = 0; + GError* error = NULL; + GVariant* result = NULL; + + GDBusProxy* proxy = g_dbus_proxy_new_sync(connection, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "org.freedesktop.NetworkManager", + apPath, + "org.freedesktop.NetworkManager.AccessPoint", + NULL, + &error); + + if (error) { + NMLOG_ERROR("creating proxy: %s", error->message); + g_error_free(error); + return false; + } + + gsize ssid_length = 0; + result = g_dbus_proxy_get_cached_property(proxy,"Ssid"); + if (!result) { + std::cerr << "Failed to get AP properties." << std::endl; + g_object_unref(proxy); + return false; + } + const guchar *ssid_data = static_cast(g_variant_get_fixed_array(result, &ssid_length, sizeof(guchar))); + if (ssid_data && ssid_length > 0 && ssid_length <= 32) { + apDetails.ssid.assign(reinterpret_cast(ssid_data), ssid_length); + NMLOG_TRACE("SSID: %s", apDetails.ssid.c_str()); + } else { + NMLOG_ERROR("Invalid SSID length: %zu (maximum is 32)", ssid_length); + apDetails.ssid="---"; + } + g_variant_unref(result); + + result = g_dbus_proxy_get_cached_property(proxy,"HwAddress"); + if (!result) { + std::cerr << "Failed to get AP properties." << std::endl; + g_object_unref(proxy); + return false; + } + g_variant_get(result, "s", &bssid); + apDetails.bssid.assign(bssid); + NMLOG_TRACE("bssid %s", apDetails.bssid.c_str()); + g_variant_unref(result); + + result = g_dbus_proxy_get_cached_property(proxy,"Strength"); + if (!result) { + std::cerr << "Failed to get AP properties." << std::endl; + g_object_unref(proxy); + return false; + } + g_variant_get(result, "y", &strength); + NMLOG_TRACE("strength %d", strength); + g_variant_unref(result); + + get_cached_property_u(proxy, "Flags", apDetails.flags); + get_cached_property_u(proxy, "WpaFlags", apDetails.wpaFlags); + get_cached_property_u(proxy, "RsnFlags", apDetails.rsnFlags); + get_cached_property_u(proxy, "Mode", apDetails.mode); + get_cached_property_u(proxy, "Frequency", apDetails.frequency); + + g_object_unref(proxy); + + return true; +} diff --git a/Tests/dbus-api-test/NetworkManagerGnomeUtils.h b/Tests/dbus-api-test/NetworkManagerGnomeUtils.h new file mode 100644 index 00000000..b40bf6ef --- /dev/null +++ b/Tests/dbus-api-test/NetworkManagerGnomeUtils.h @@ -0,0 +1,50 @@ + /* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2020 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once +#include +#include + +#include + +struct apProperties +{ + uint32_t flags; + uint32_t wpaFlags; + uint32_t rsnFlags; + uint32_t frequency; + uint32_t mode; + std::string ssid; + std::string bssid; + uint8_t strength; +}; + +class GnomeUtils +{ + public: + static bool getDeviceByIpIface(GDBusConnection *connection, const gchar *iface_name, std::string& path); + static bool getApDetails(GDBusConnection *connection, const char* apPath, apProperties& apDetails); +}; + + +#define G_VARIANT_LOOKUP(dict, key, format, ...) \ + if (!g_variant_lookup(dict, key, format, __VA_ARGS__)) {\ + NMLOG_ERROR("g_variant Key '%s' not found", key); \ + return FALSE; \ + } diff --git a/Tests/dbus-api-test/dbusConnectionManager.h b/Tests/dbus-api-test/dbusConnectionManager.h index 44baaa9d..ec9f3d45 100644 --- a/Tests/dbus-api-test/dbusConnectionManager.h +++ b/Tests/dbus-api-test/dbusConnectionManager.h @@ -5,48 +5,6 @@ #include - -// Define log levels -enum LogLevel { - LOG_LEVEL_ERROR = 0, - LOG_LEVEL_WARN = 1, - LOG_LEVEL_INFO = 2, - LOG_LEVEL_TRACE = 3, - LOG_LEVEL_VERBOSE = 4 -}; - -// Set the current log level (modify as needed) -static const int currentLogLevel = LOG_LEVEL_INFO; - -#define NMLOG_ERROR(fmt, ...) \ - do { \ - if (currentLogLevel >= LOG_LEVEL_ERROR) { \ - fprintf(stderr, "[ERROR] [%s:%d] " fmt "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); \ - } \ - } while(0) - -#define NMLOG_WARNING(fmt, ...) \ - do { \ - if (currentLogLevel >= LOG_LEVEL_WARN) { \ - printf("[WARN] [%s:%d] " fmt "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); \ - } \ - } while(0) - -#define NMLOG_INFO(fmt, ...) \ - do { \ - if (currentLogLevel >= LOG_LEVEL_INFO) { \ - printf("[INFO] " fmt "\n", ##__VA_ARGS__); \ - } \ - } while(0) - -#define NMLOG_TRACE(fmt, ...) \ - do { \ - if (currentLogLevel >= LOG_LEVEL_TRACE) { \ - printf("[TRACE] [%s:%d] " fmt "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); \ - } \ - } while (0) - - class DbusConnectionManager { public: DbusConnectionManager(); diff --git a/Tests/dbus-api-test/main.cpp b/Tests/dbus-api-test/main.cpp index 832b002f..745bf543 100644 --- a/Tests/dbus-api-test/main.cpp +++ b/Tests/dbus-api-test/main.cpp @@ -1,5 +1,4 @@ -#include "networkManagerClient.h" -#include "wpaSupplicantClient.h" +#include "NetworkManagerGnomeClient.h" #include "dbusConnectionManager.h" #include #include @@ -10,7 +9,7 @@ int main() { // Create instances of the NetworkManager and wpa_supplicant clients NetworkManagerClient nmClient; // WpaSupplicantClient wpaClient; - int i=100; + int i=1; while(i-- > 0) { std::list ssids; @@ -21,17 +20,10 @@ int main() { NMLOG_INFO("SSID list available"); } std::this_thread::sleep_for(std::chrono::milliseconds(1)); - NMLOG_INFO("count %d", i); + + nmClient.getConnectedSSID(); + nmClient.getavilableSSID(ssids); } - // std::string wifiStatus = wpaClient.getWifiStatus(); - // if (!wifiStatus.empty()) { - // NMLOG_INFO("Wi-Fi status: %s", wifiStatus.c_str()); - // } else { - // NMLOG_WARNING("Failed to retrieve Wi-Fi status"); - // } - - // Sleep for a short period to simulate real-world conditions - NMLOG_INFO("Program completed successfully"); return 0; } diff --git a/Tests/dbus-api-test/utils.h b/Tests/dbus-api-test/utils.h new file mode 100644 index 00000000..3a108063 --- /dev/null +++ b/Tests/dbus-api-test/utils.h @@ -0,0 +1,52 @@ +#pragma once + +#include + +// Define log levels +enum LogLevel { + LOG_LEVEL_ERROR = 0, + LOG_LEVEL_WARN = 1, + LOG_LEVEL_INFO = 2, + LOG_LEVEL_TRACE = 3, + LOG_LEVEL_VERBOSE = 4 +}; + +// Set the current log level (modify as needed) +static const int currentLogLevel = LOG_LEVEL_TRACE; + +#define NMLOG_ERROR(fmt, ...) \ + do { \ + if (currentLogLevel >= LOG_LEVEL_ERROR) { \ + fprintf(stderr, "[ERROR] [%s:%d] " fmt "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + } \ + } while(0) + +#define NMLOG_WARNING(fmt, ...) \ + do { \ + if (currentLogLevel >= LOG_LEVEL_WARN) { \ + printf("[WARN] [%s:%d] " fmt "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + } \ + } while(0) + +#define NMLOG_INFO(fmt, ...) \ + do { \ + if (currentLogLevel >= LOG_LEVEL_INFO) { \ + printf("[INFO] " fmt "\n", ##__VA_ARGS__); \ + } \ + } while(0) + +#define NMLOG_TRACE(fmt, ...) \ + do { \ + if (currentLogLevel >= LOG_LEVEL_TRACE) { \ + printf("[TRACE] [%s:%d] " fmt "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + } \ + } while (0) + + +#define NMLOG_VERBOSE(fmt, ...) \ + do { \ + if (currentLogLevel >= LOG_LEVEL_VERBOSE) { \ + printf("[VERBOSE] [%s:%d] " fmt "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + } \ + } while (0) +