[英]Bluez DBUS api NewConnection method gives wrong file descriptor
I am trying to implement RFCOMM profile using the DBUS bluez api.我正在尝试使用 DBUS bluez api 实现 RFCOMM 配置文件。 I have implemented the
org.bluez.Profile1
interface and the NewConnection
method gets called, but file descriptor parameter is wrong.我已经实现了
org.bluez.Profile1
接口并调用了NewConnection
方法,但文件描述符参数错误。 Every time the method gets called the file descriptor is 0. And when i try to write to it i get errno set to Bad file descriptor
.每次调用该方法时,文件描述符都是 0。当我尝试写入它时,我将 errno 设置为
Bad file descriptor
。
This is code for the method_call callback:这是 method_call 回调的代码:
val methodCall = staticCFunction<
CPointer<GDBusConnection>?,
CPointer<gcharVar>?,
CPointer<gcharVar>?,
CPointer<gcharVar>?,
CPointer<gcharVar>?,
CPointer<GVariant>?,
CPointer<GDBusMethodInvocation>?,
gpointer?,
Unit >
{dbus, sender, objectPath, interfaceName, methodName, parameters, invocation, userData ->
memScoped {
val caller = allocPointerTo<gcharVar>()
val fd = alloc<gint32Var>()
val properties = allocPointerTo<GVariantIter>()
fd.value = -1
g_variant_get(parameters, "(oha{sv})", caller.ptr, fd, properties.ptr)
"""
Method call sender: ${sender?.toKString()}
objectPath: ${objectPath?.toKString()}
interfaceName: ${interfaceName?.toKString()}
methodName: ${methodName?.toKString()}
caller: ${caller.value?.toKString()}
fd: ${fd.value}
""".debug()
val text = "text".cstr
"Written: ${write(fd.value, text, text.size.convert())} bytes".debug()
strerror(errno)?.toKString()?.error()
}
}
Which produces this output:这产生了这个 output:
11:43:43 [DEBUG]
Method call sender: :1.3
objectPath: /org/bluez/myprofile
interfaceName: org.bluez.Profile1
methodName: NewConnection
caller: /org/bluez/hci0/dev_......
fd: 0
11:43:43 [DEBUG] Written: -1 bytes
11:43:43 [ERROR] Bad file descriptor
I am registering the object implementing the interface with this code:我正在使用以下代码注册实现接口的 object:
fun registerBluetoothProfileObject() {
val interfaceDesc =
"""
<node>
<interface name='org.bluez.Profile1'>
<method name='Release' />
<method name='NewConnection'>
<arg type='o' name='device' direction='in' />
<arg type='h' name='fd' direction='in' />
<arg type='a{sv}' name='fd_properties' direction='in' />
</method>
<method name='RequestDisconnection'>
<arg type='o' name='device' direction='in' />
</method>
</interface>
</node>
"""
val vTable = cValue<GDBusInterfaceVTable> {
method_call = Bluetooth.methodCall //This points to the method_call callback
set_property = Bluetooth.setProperty
get_property = Bluetooth.getProperty
}
memScoped {
val error = allocPointerTo<GError>()
val nodeInfo = g_dbus_node_info_new_for_xml(interfaceDesc, error.ptr)
error.value?.let {
"Error creating node from xml ${it.pointed.message?.toKString()}".error()
}
val interfaceInfo = g_dbus_node_info_lookup_interface(nodeInfo, "org.bluez.Profile1")
g_dbus_connection_register_object(
dbus,
Bluetooth.PROFILE_OBJECT_PATH,
interfaceInfo,
vTable.ptr,
null,
null,
error.ptr
)
error.value?.let {
"Error registering sdp profile object: ${it.pointed.message?.toKString()}".error()
}
}
}
So i found out where the problem is.所以我发现问题出在哪里。 The parameter called
fd
in the interface is actually not file descriptor.接口中名为
fd
的参数实际上并不是文件描述符。 It is index to a field of file descriptors.它是文件描述符字段的索引。 So the
0
value i am getting is index of the file descriptor in array of file descriptors which can be obtained using something like this所以我得到的
0
值是文件描述符数组中文件描述符的索引,可以使用类似这样的方法获得
val fdList = g_dbus_message_get_unix_fd_list(g_dbus_method_invocation_get_message(invocation))
the invocation
parameter passed to the g_dbus_method_invocation_get_message
method is from the callMethod
callback parameter.传递给
g_dbus_method_invocation_get_message
方法的invocation
参数来自callMethod
回调参数。 This returns the list, then the actual file descriptor can be obtained using这将返回列表,然后可以使用获取实际的文件描述符
val fd = g_unix_fd_list_get(fdList, fdIndex.value, null)
So the callback function was the only thing that needed change.所以回调 function 是唯一需要改变的东西。 Now it looks like this
现在看起来像这样
val methodCall = staticCFunction<
CPointer<GDBusConnection>?,
CPointer<gcharVar>?,
CPointer<gcharVar>?,
CPointer<gcharVar>?,
CPointer<gcharVar>?,
CPointer<GVariant>?,
CPointer<GDBusMethodInvocation>?,
gpointer?,
Unit >
{dbus, sender, objectPath, interfaceName, methodName, parameters, invocation, userData ->
memScoped {
val caller = allocPointerTo<gcharVar>()
val fdIndex = alloc<gint32Var>()
val properties = allocPointerTo<GVariantIter>()
g_variant_get(parameters, "(oha{sv})", caller.ptr, fdIndex, properties.ptr)
"""
Method call sender: ${sender?.toKString()}
objectPath: ${objectPath?.toKString()}
interfaceName: ${interfaceName?.toKString()}
methodName: ${methodName?.toKString()}
caller: ${caller.value?.toKString()}
fd: ${fdIndex.value}
""".debug()
val fdList = g_dbus_message_get_unix_fd_list(g_dbus_method_invocation_get_message(invocation))
val fd = g_unix_fd_list_get(fdList, fdIndex.value, null)
val text = "text".cstr
"Written: ${write(fd, text, text.size.convert())} bytes".debug()
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.