I’m writing code to connect a particular Wi-Fi device using Connection Manager and sdbus-c++. When calling the Connect function, the system asks for a password via RequestInput. The password is provided to the system by replying to RequestInput using the callback function installed by addMatch. However, while running the code, the callback function is called after the connection times out. Ideally, the callback function should be called immediately when the Connect function is called.
When I monitor this method call from the terminal using the command:
dbus-monitor --system "interface='net.connman.Agent',member='RequestInput'"
I receive it at the right time.
Here is my code:
#include <iostream>
#include <sdbus-c++/sdbus-c++.h>
#include <map>
#include <vector>
#include <memory>
#include <functional>
#include <string>
void handle_message(sdbus::Message message) {
std::cout << "Received RequestInput method call" << std::endl;
}
int monitor_pass_req(std::unique_ptr<sdbus::IConnection>& connection) {
try {
// Define handler
sdbus::message_handler handler = [](sdbus::Message message) {
handle_message(std::move(message));
};
auto match_rule = "type='method_call',interface='net.connman.Agent',member='RequestInput'";
connection->addMatch(match_rule, handler);
} catch (sdbus::Error& e) {
std::cerr << "D-Bus error:" << e.what() << std::endl;
return -1;
}
return 0;
}
int set_wifi_power(std::unique_ptr<sdbus::IConnection>& connection, bool power_state) {
try {
sdbus::ServiceName service("net.connman");
sdbus::ObjectPath objectpath("/net/connman/technology/wifi");
std::unique_ptr<sdbus::IProxy> proxy = sdbus::createProxy(*connection, std::move(service), std::move(objectpath));
proxy->callMethod("SetProperty").onInterface("net.connman.Technology").withArguments("Powered", sdbus::Variant(power_state));
} catch (sdbus::Error& e) {
std::cerr << "D-Bus error:" << e.what() << std::endl;
return -1;
}
return 0;
}
int register_agent(std::unique_ptr<sdbus::IConnection>& connection, sdbus::ObjectPath& path) {
try {
sdbus::ServiceName service("net.connman");
sdbus::ObjectPath objectpath("/");
std::unique_ptr<sdbus::IProxy> proxy = sdbus::createProxy(*connection, std::move(service), std::move(objectpath));
proxy->callMethod("RegisterAgent").onInterface("net.connman.Manager").withArguments(path);
} catch (sdbus::Error& e) {
std::cerr << "D-Bus error:" << e.what() << std::endl;
return -1;
}
return 0;
}
int connect_wifi_dev(std::unique_ptr<sdbus::IConnection>& connection, sdbus::ObjectPath& path) {
try {
sdbus::ServiceName service("net.connman");
sdbus::ObjectPath objectpath(path);
std::unique_ptr<sdbus::IProxy> proxy = sdbus::createProxy(*connection, std::move(service), std::move(objectpath));
proxy->callMethod("Connect").onInterface("net.connman.Service");
} catch (sdbus::Error& e) {
std::cerr << "D-Bus error:" << e.what() << std::endl;
return -1;
}
return 0;
}
int scan_wifi(std::unique_ptr<sdbus::IConnection>& connection) {
try {
sdbus::ServiceName service("net.connman");
sdbus::ObjectPath objectpath("/net/connman/technology/wifi");
std::unique_ptr<sdbus::IProxy> proxy = sdbus::createProxy(*connection, std::move(service), std::move(objectpath));
proxy->callMethod("Scan").onInterface("net.connman.Technology");
} catch (const sdbus::Error& e) {
std::cerr << "D-Bus error:" << e.what() << std::endl;
return -1;
}
return 0;
}
int main() {
std::unique_ptr<sdbus::IConnection> connection = sdbus::createSystemBusConnection();
bool power_state = true;
int ret = set_wifi_power(connection, power_state);
if (0 == ret) std::cout << "Wi-Fi powered successfullyn";
sdbus::ObjectPath mypath("/test/wifi");
ret = register_agent(connection, mypath);
if (0 == ret) std::cout << "Agent Registeredn";
ret = monitor_pass_req(connection);
if (0 == ret) std::cout << "Add match addedn";
connection->enterEventLoopAsync();
ret = scan_wifi(connection);
if (0 == ret) std::cout << "Scan completedn";
sdbus::ObjectPath devpath("/net/connman/service/wifi_340a33303465_6d616873686f6f6b_managed_psk");
ret = connect_wifi_dev(connection, devpath);
if (0 == ret) std::cout << "Connection completedn";
while (true) {}
return 0;
}
Expected Behavior:
The RequestInput callback function should be called immediately when the Connect function is invoked, prompting the user for the Wi-Fi password.
Actual Behavior:
The RequestInput callback function is called after the connection times out.
Output:
Wi-Fi powered successfully
Agent Registered
Add match added
Scan completed
D-Bus error:[org.freedesktop.DBus.Error.Timeout] Connection timed out
Received RequestInput method call
Any insights or suggestions on how to ensure the callback function is triggered at the correct time would be greatly appreciated. Thank you