我正在开发一个使用Connman DBus API连接到安全WiFi网络的应用程序。我读到我需要注册一个实现net.connman.Agent接口的对象,以便DBus可以调用我的方法。到目前为止,我已经能够做一些非常接近我需要的事情,但是当我运行程序时,如果我以前从未连接到该网络,“Connect”函数超时。2如果我在代理事件处理程序上设置断点,它将永远不会被调用。3我有以下代理注册代码:
WiFiAgent::WiFiAgent(GDBusConnection *inputConnection, Poco::JSON::Object::Ptr credentials)
: connection(inputConnection), parameters(std::move(credentials)) {
static const GDBusInterfaceVTable vtable = {
.method_call = handleMethodCall,
.get_property = nullptr,
.set_property = nullptr,
};
static GError* error = nullptr;
objectId = g_dbus_connection_register_object(
connection,
WiFiAgent::ourAgentPath,
WiFiAgent::introspectionWrapper->interfaces[0],
&vtable,
parameters.get(),
nullptr,
&error
);
if(objectId == 0 || error != nullptr)
throw GlibException("Register WiFi agent", error);
GVariant* agentPathVariant = g_variant_new("(o)", WiFiAgent::ourAgentPath);
if(agentPathVariant == nullptr)
throw std::runtime_error("Register WiFi agent: g_variant_new failed.");
GVariant* result = g_dbus_connection_call_sync(connection, "net.connman", "/", "net.connman.Manager",
"RegisterAgent", agentPathVariant, nullptr, G_DBUS_CALL_FLAGS_NONE, -1, nullptr, &error);
if(result == nullptr || error != nullptr)
throw GlibException("Register WiFi agent", error);
}
此事件处理程序代码:
void WiFiAgent::handleMethodCall(GDBusConnection *, const gchar *,
const gchar *, const gchar *, const gchar *method,
GVariant *methodParameters, GDBusMethodInvocation *invocation, gpointer userdata) {
std::cout << "Method got called." << std::endl;
}
这段代码是用来自省的
static inline class IntrospectionWrapper final {
GDBusNodeInfo* introspection = nullptr;
static constexpr auto introspectionXML =
"<node>"
" <interface name='net.connman.Agent'>"
" <method name='RequestInput'>"
" <arg type='o' name='service' direction='in'/>"
" <arg type='a{sv}' name='fields' direction='in'/>"
" <arg type='a{sv}' name='fields' direction='out'/>"
" </method>"
" <method name='ReportError'>"
" <arg type='o' name='service' direction='in'/>"
" <arg type='s' name='error' direction='in'/>"
" </method>"
" </interface>"
"</node>";
public:
IntrospectionWrapper() {
GError* error = nullptr;
introspection = g_dbus_node_info_new_for_xml(introspectionXML, &error);
if(introspection == nullptr || error != nullptr)
std::cerr << GlibException("Agent introspection construction", error) << std::endl;
}
GDBusNodeInfo* operator->() { return introspection; };
GDBusNodeInfo* get() { return introspection; }
} introspectionWrapper;
一切正常,未出现错误,但在指定服务接口上调用的“Connect”函数失败,并出现超时错误:
Glib错误代码为24 - g-io-error-quark -超时
我这样调用这个函数:
void DBusManipulator::connectToTheNetwork(GDBusProxy *network) {
GError* error = nullptr;
g_dbus_proxy_call_sync(network, "Connect", nullptr, G_DBUS_CALL_FLAGS_NONE, -1, nullptr, &error);
if(error != nullptr)
throw GlibException("Connect to the network", error);
const auto state = variantGetValue(getNetworkProperty(network, "State"));
if(state != "online" && state != "ready")
throw std::runtime_error("Connect to the WiFi network: connection failed");
std::cout << "Connected to the network successfully." << std::endl;
}
网络接收的方式是:
GDBusProxy* network = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, nullptr, "net.connman", servicePath, "net.connman.Service", nullptr, &error);
if(network == nullptr || error != nullptr)
throw GlibException("Get network by name", error);
1条答案
按热度按时间ej83mcc01#
通过将
Connect
方法调用更改为异步并运行主循环,设法解决了问题:分页装订器功能:
现在,代理方法在
Connect
方法之后立即调用。