Open ukBaz opened 7 years ago
Just stumbled upon this bug as well, is there any workaround?
Implemented support here: https://github.com/LEW21/pydbus/compare/master...molobrakos:unixfd Both passing and receiving unix file descriptors should work, but I have mainly tested receiving, and verified that receiving file descriptors for org.bluez.Profile1:NewConnection works, which is my main use case right now. @ukBaz, maybe you are interested in testing this out as well? @LEW21, feel free to steal/modify the code, or please let me know it you want it as a PR as-is (thank you for your beautiful and very useful library btw)?
Thanks @molobrakos for taking a look at this. I've had time to do some testing tonight.
It is still not coming out as <type 'dbus.UnixFd'>
in my tests . When I run with your unixfd
branch I still see <type 'int'>
I've been using org.bluez.Profile1:NewConnection
to create a Serial Port Profile. Do you have some example code?
@ukBaz, thanks for testing! The file descriptor will be received as int
(not dbus.UnixFd
), have you tried reading from it using os.read
?
I could add a proper test case to the tests
-directory (but it wasn't obvious anyone, including the maintainer, cared). Anyway, here is how I use it:
UUID_SPP = "00001101-0000-1000-8000-00805f9b34fb"
class Profile:
def __init__(self, read_callback):
_LOGGER.debug("Init profile")
self.read_callback = read_callback
self.fd = None
def Release(self):
_LOGGER.debug("Release")
def NewConnection(self, path, fd, properties):
_LOGGER.error("New connection %s %s %s",
path, fd, properties)
if self.fd != None:
_LOGGER.error("Should not happen")
self.fd = os.dup(fd)
_LOGGER.debug("Got fd %s, dup as %d", fd, self.fd)
def fd_read_callback(fd, conditions):
_LOGGER.debug("io cb on fd %d (self.fd: %d)", fd, self.fd)
assert(self.fd == fd)
data = os.read(fd, 1024)
_LOGGER.debug("Read %d bytes: %s: %s", len(data),
binascii.hexlify(data), data.decode("ascii"))
self.read_callback(path, data.decode("ascii"))
# We are done
# os.close(self.fd)
# gobject.source_remove(io_id)
# self.fd = None
return True
io_id = GObject.io_add_watch(self.fd,
GObject.PRIORITY_DEFAULT,
GObject.IO_IN | GObject.IO_PRI,
fd_read_callback)
def RequestDisconnection(self, path):
_LOGGER.debug("RequestDisconnection: %s", path)
if self.fd:
os.close(self.fd)
# gobject.source_remove(io_id)
self.fd = None
def register_spp_profile():
profile_path = "/foo/bar/profile"
opts = dict(
AutoConnect=pydbus.Variant("b", True),
Role=pydbus.Variant("s", "server"),
Channel=pydbus.Variant("q", 1),
RequireAuthorization=pydbus.Variant("b", False),
RequireAuthentication=pydbus.Variant("b", False),
Name=pydbus.Variant("s", "Foobar")
)
_LOGGER.info("Creating Serial Port Profile")
def read_cb(path, value):
_LOGGER.debug("Read value %s", value)
pydbus.SystemBus().register_object(
profile_path,
Profile(read_cb),
pathlib.Path(__file__).with_name("btspp.xml").read_text())
blus.profile_manager().RegisterProfile(
profile_path,
UUID_SPP, opts)
_LOGGER.info("Registered profile on %s", profile_path)
(Btw, I don't think I have seen Release
or RequestDisconnection
being called, but I guess that is a Bluez-issue)
Actually there seems to be a problem returning fd:s with the current code (as in Fixed in latest commit. Also added a test case.direction="out"
). Sending and receiving should work.
Any chance this has been merged in yet? I am looking to use something like this for accepting incoming RFCOMM connections passed in from BlueZ.
This looks similar to #42 but the suggested modifications by @LEW21 do not seem to be having an effect. However I am right at the edge of my knowledge so apologies if this is a duplicate.
I am looking to implement the BlueZ Profile DBus APi https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/profile-api.txt#n104
I have implemented, published and registered the
NewConnection
methodWhen a new connection is made the the Bluetooth daemon calls the
NewConnection
method but the value of fd is wrong:I say wrong because it gives the tty of the terminal I'm running in and If I monitor the bus then I can see the bluetoothd sending the command with UNIX_FD = 4
To confirm what the sender is
Versions I am running
As I say, I am right on the edge of my knowledge so I am not sure how to fix this. If someone can give me some guidance then I am willing to do more on this.