Skip to content

Commit

Permalink
getknowssid api implimentaion
Browse files Browse the repository at this point in the history
  • Loading branch information
cmuhammedrafi committed Sep 27, 2024
1 parent ed59d2c commit fe43ec5
Show file tree
Hide file tree
Showing 8 changed files with 447 additions and 0 deletions.
27 changes: 27 additions & 0 deletions Tests/dbus-api-test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
cmake_minimum_required(VERSION 3.5)
project(NmDbusClient)

set(CMAKE_CXX_STANDARD 11)

find_package(PkgConfig REQUIRED)
pkg_check_modules(GLIB REQUIRED glib-2.0)
pkg_check_modules(GIO REQUIRED gio-2.0)

include_directories(
${GLIB_INCLUDE_DIRS}
${GIO_INCLUDE_DIRS}
)

add_executable(
NmDbusClient
main.cpp
dbusConnectionManager.cpp
networkManagerClient.cpp
wpaSupplicantClient.cpp
)

target_link_libraries(
NmDbusClient
${GLIB_LIBRARIES}
${GIO_LIBRARIES}
)
35 changes: 35 additions & 0 deletions Tests/dbus-api-test/dbusConnectionManager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include "dbusConnectionManager.h"

DbusConnectionManager::DbusConnectionManager() : connection(nullptr) {
NMLOG_INFO("DbusConnectionManager created");
}

DbusConnectionManager::~DbusConnectionManager() {
DeinitializeDbusConnection();
}

bool DbusConnectionManager::InitializeBusConnection(const std::string& busName) {
GError* error = nullptr;
connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, &error);

if (!connection) {
NMLOG_ERROR("Failed to initialize D-Bus connection: %s ", error->message);
g_error_free(error);
return false;
}

NMLOG_INFO("D-Bus connection initialized successfully for bus: %s", busName.c_str());
return true;
}

void DbusConnectionManager::DeinitializeDbusConnection() {
if (connection) {
g_object_unref(connection);
connection = nullptr;
NMLOG_INFO("D-Bus connection deinitialized successfully");
}
}

GDBusConnection* DbusConnectionManager::getConnection() const {
return connection;
}
61 changes: 61 additions & 0 deletions Tests/dbus-api-test/dbusConnectionManager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#pragma once

#include <gio/gio.h>
#include <iostream>

#include <cstdio>


// 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();
~DbusConnectionManager();

bool InitializeBusConnection(const std::string& busName);
void DeinitializeDbusConnection();
GDBusConnection* getConnection() const;

private:
GDBusConnection* connection;
};
37 changes: 37 additions & 0 deletions Tests/dbus-api-test/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#include "networkManagerClient.h"
#include "wpaSupplicantClient.h"
#include "dbusConnectionManager.h"
#include <iostream>
#include <thread>
#include <chrono>


int main() {
// Create instances of the NetworkManager and wpa_supplicant clients
NetworkManagerClient nmClient;
// WpaSupplicantClient wpaClient;
int i=100;
while(i-- > 0)
{
std::list<std::string> ssids;
nmClient.getKnownSSIDs(ssids);
if (ssids.empty()) {
NMLOG_INFO("No SSID found");
} else {
NMLOG_INFO("SSID list available");
}
std::this_thread::sleep_for(std::chrono::milliseconds(1));
NMLOG_INFO("count %d", i);
}
// 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;
}
203 changes: 203 additions & 0 deletions Tests/dbus-api-test/networkManagerClient.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
#include "networkManagerClient.h"
#include "dbusConnectionManager.h"

NetworkManagerClient::NetworkManagerClient() {
NMLOG_INFO("NetworkManagerClient created");
if (!dbusConnection.InitializeBusConnection("org.freedesktop.NetworkManager")) {
NMLOG_ERROR("Failed to initialize D-Bus connection for NetworkManager");
}
}

NetworkManagerClient::~NetworkManagerClient() {
NMLOG_INFO("NetworkManagerClient destroyed");
}

static void fetssidandbssid(GVariant *setting80211, std::string &ssid, std::string &bssid)
{
GVariantIter iter;
const char *property_name;
GVariant *value;
char *printed_value;

g_variant_iter_init(&iter, setting80211);
while (g_variant_iter_next(&iter, "{&sv}", &property_name, &value)) {

printed_value = g_variant_print(value, FALSE);
if (strcmp(property_name, "seen-bssids") == 0) {
bssid.clear();
GVariantIter bssid_iter;
g_variant_iter_init(&bssid_iter, value);
gchar *bssid_elem;

if (g_variant_iter_next(&bssid_iter, "s", &bssid_elem)) {
bssid = bssid_elem;
NMLOG_TRACE("BSSID: %s", bssid.c_str());
}

//g_variant_iter_free(&bssid_iter);
}
else if (strcmp(property_name, "ssid") == 0) {
// Decode SSID from GVariant of type "ay"
gsize ssid_length = 0;
const guchar *ssid_data = static_cast<const guchar*>(g_variant_get_fixed_array(value, &ssid_length, sizeof(guchar)));
if (ssid_data && ssid_length > 0 && ssid_length <= 32) {
ssid.assign(reinterpret_cast<const char*>(ssid_data), ssid_length);
NMLOG_INFO("SSID: %s", ssid.c_str());
} else {
NMLOG_ERROR("Invalid SSID length: %zu (maximum is 32)", ssid_length);
ssid.clear();
}
}
}

g_free(printed_value);
g_variant_unref(value);
}

static bool fetchSSIDFromConnection(const char *path, std::list<std::string>& ssids)
{
GError *error = NULL;
GDBusProxy *ConnProxy = NULL;
GVariant *settingsProxy= NULL, *connection= NULL, *s_con= NULL;
bool isFound;
const char *connId= NULL, *connTyp= NULL, *iface= NULL;
ConnProxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
G_DBUS_PROXY_FLAGS_NONE,
NULL,
"org.freedesktop.NetworkManager",
path,
"org.freedesktop.NetworkManager.Settings.Connection",
NULL,
&error);
if (error != NULL) {
NMLOG_ERROR("Failed to create proxy: %s", error->message);
g_error_free(error);
return false;
}

settingsProxy = g_dbus_proxy_call_sync(ConnProxy,
"GetSettings",
NULL,
G_DBUS_CALL_FLAGS_NONE,
-1,
NULL,
&error);
if (!settingsProxy) {
g_dbus_error_strip_remote_error(error);
NMLOG_WARNING("Failed to get connection settings: %s", error->message);
g_error_free(error);
}

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);
if(strcmp(connTyp,"802-11-wireless") == 0 && strcmp(iface,"wlan0") == 0)
{
GVariant *setting = g_variant_lookup_value(connection, "802-11-wireless", NULL);
if (setting) {
std::string ssid, bssid;
fetssidandbssid(setting, ssid, bssid);
if(!ssid.empty())
ssids.push_back(ssid);
g_variant_unref(setting);
}
}

if (s_con)
g_variant_unref(s_con);
if (connection)
g_variant_unref(connection);
if (settingsProxy)
g_variant_unref(settingsProxy);
g_object_unref(ConnProxy);

return true;
}

static bool fetchConnectionPaths(GDBusProxy *proxy, std::list<std::string>& pathsList)
{
GVariant *listProxy = NULL;
GError *error = NULL;
char **paths = NULL;
listProxy = g_dbus_proxy_call_sync(proxy,
"ListConnections",
NULL,
G_DBUS_CALL_FLAGS_NONE,
-1,
NULL,
&error);
if(listProxy == NULL)
{
if (!error) {
NMLOG_ERROR("ListConnections failed: %s", error->message);
g_error_free(error);
return false;
}
else
NMLOG_ERROR("ListConnections proxy failed no error message");
}

g_variant_get(listProxy, "(^ao)", &paths);
g_variant_unref(listProxy);

if(paths == NULL)
{
NMLOG_WARNING("no connection path available");
return false;
}

for (int i = 0; paths[i]; i++) {
//NMLOG_INFO("Connection path: %s", paths[i]);
pathsList.push_back(paths[i]);
}

if(pathsList.empty())
return false;

return true;
}

bool NetworkManagerClient::getKnownSSIDs(std::list<std::string>& ssids)
{
GDBusProxy *sProxy= NULL;
GError *error= NULL;
std::list<std::string> paths;

sProxy = g_dbus_proxy_new_sync(dbusConnection.getConnection(),
G_DBUS_PROXY_FLAGS_NONE,
NULL,
"org.freedesktop.NetworkManager",
"/org/freedesktop/NetworkManager/Settings",
"org.freedesktop.NetworkManager.Settings",
NULL, // GCancellable
&error);

if(sProxy == NULL)
{
if (error != NULL) {
NMLOG_ERROR("Failed to create proxy: %s", error->message);
g_error_free(error);
}
return false;
}

if(fetchConnectionPaths(sProxy, paths))
{
for (const std::string& path : paths) {
NMLOG_TRACE("connection path %s", path.c_str());
fetchSSIDFromConnection(path.c_str(), ssids);
}
}

g_object_unref(sProxy);

if(ssids.empty())
return false;
return true;
}
16 changes: 16 additions & 0 deletions Tests/dbus-api-test/networkManagerClient.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#pragma once

#include "dbusConnectionManager.h"
#include <string>
#include <list>

class NetworkManagerClient {
public:
NetworkManagerClient();
~NetworkManagerClient();

bool getKnownSSIDs(std::list<std::string>& ssids);

private:
DbusConnectionManager dbusConnection;
};
Loading

0 comments on commit fe43ec5

Please sign in to comment.