For my project, I need to downlink .zip files over Bluetooth. I am using python and obex for this. I have a working python opp client implemented (shout-out to ukBaz for the help), but I am still using os to start the server, so the rest of my server program has no idea when a file is received. The rest of the program is completed, but without output from the server, I can’t trigger the unzip function to run. I’ve read the bluez-obex API documentation and there doesn’t seem to be anything on starting a server. Is there another way of doing this? My code is below.
os.system("sudo obexpushd -B -o /home/pi/Desktop/ -n")
Advertisement
Answer
I am not familiar with obexpushd
and what it gives you over using the functionality that is there with obexd
.
My understanding is that you need to create an obex-agent to accept/reject a Bluetooth object push request with obexd
.
Monitoring the InterfacesAdded
DBus signal should give you the information that you need to know when a transfer has started. You can then monitor the PropertiesChanged
signal for when the status changes.
I was able to push a photo from my phone to a Raspberry Pi with the following running on the RPi (I had my phone and RPi already paired):
from gi.repository import GLib import pydbus BUS_NAME = 'org.bluez.obex' PATH = '/org/bluez/obex' AGENT_MANAGER_INTERFACE = 'org.bluez.obex.AgentManager1' AGENT_INTERFACE = 'org.bluez.obex.Agent1' SESSION_INTERFACE = 'org.bluez.obex.Session1' TRANSFER_INTERFACE = 'org.bluez.obex.Transfer1' ses_bus = pydbus.SessionBus() def transfer_status_handler(iface, props_changed, props_removed): if iface == TRANSFER_INTERFACE: status = props_changed.get('Status') if status == 'complete': print('Transfer complete') elif status == 'queued': print('Still queued') elif status == 'active': print('transferring') elif status == 'suspended': print('Suspended') elif status == 'error': print('error') def iface_added_handler(dbus_path, interfaces): if SESSION_INTERFACE in interfaces and 'server' in dbus_path: print('Server session added') elif TRANSFER_INTERFACE in interfaces and 'server' in dbus_path: print('Transfer started') transfer = ses_bus.get(BUS_NAME, dbus_path) transfer.onPropertiesChanged = transfer_status_handler class Agent: """ <node> <interface name='org.bluez.obex.Agent1'> <method name='Release'> </method> <method name='AuthorizePush'> <arg type='s' name='path' direction='out'/> <arg type='o' name='transfer' direction='in'/> </method> <method name='Cancel'> </method> </interface> </node> """ def AuthorizePush(self, path): print('Authorize Push', path) transfer = ses_bus.get(BUS_NAME, path) props = transfer.GetAll(TRANSFER_INTERFACE) print(props) return props.get('Name') def Cancel(self): print('Authorization Cancelled') def Release(self): pass if __name__ == '__main__': obex_mngr = ses_bus.get('org.bluez.obex', '/') obex_mngr.onInterfacesAdded = iface_added_handler mainloop = GLib.MainLoop() ses_bus.register_object('/test/agent', Agent(), None) print('Agent created') agnt_mngr = ses_bus.get(BUS_NAME, PATH) agnt_mngr.RegisterAgent('/test/agent') print('Agent registered') try: mainloop.run() except KeyboardInterrupt: mainloop.quit()
This code just accepts any request that is made of it. This is probably a bad thing to do and people might want to add some checking (or prompt the user) if the file should be accepted.