mirror of
https://git.kernel.org/pub/scm/bluetooth/bluez.git
synced 2024-11-15 00:04:29 +08:00
d31f04aa92
Currently we have a mix of /usr/bin/python, /usr/bin/python3 and /usr/bin/env python3. Use the latter since is the more common way of handling this, plus it allows people to override the system python (for what ever reason). Inspired by a Debian patch, doing a mass /usr/bin/python{,3} conversion. Cc: Nobuhiro Iwamatsu <iwamatsu@debian.org>
177 lines
4.2 KiB
Python
Executable File
177 lines
4.2 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
|
|
|
from __future__ import absolute_import, print_function, unicode_literals
|
|
|
|
import os
|
|
import sys
|
|
import dbus
|
|
import dbus.service
|
|
import dbus.mainloop.glib
|
|
try:
|
|
from gi.repository import GObject
|
|
except ImportError:
|
|
import gobject as GObject
|
|
|
|
BUS_NAME='org.bluez.obex'
|
|
PATH = '/org/bluez/obex'
|
|
CLIENT_INTERFACE = 'org.bluez.obex.Client1'
|
|
SESSION_INTERFACE = 'org.bluez.obex.Session1'
|
|
PHONEBOOK_ACCESS_INTERFACE = 'org.bluez.obex.PhonebookAccess1'
|
|
TRANSFER_INTERFACE = 'org.bluez.obex.Transfer1'
|
|
|
|
class Transfer:
|
|
def __init__(self, callback_func):
|
|
self.callback_func = callback_func
|
|
self.path = None
|
|
self.filename = None
|
|
|
|
class PbapClient:
|
|
def __init__(self, session_path):
|
|
self.transfers = 0
|
|
self.props = dict()
|
|
self.flush_func = None
|
|
bus = dbus.SessionBus()
|
|
obj = bus.get_object(BUS_NAME, session_path)
|
|
self.session = dbus.Interface(obj, SESSION_INTERFACE)
|
|
self.pbap = dbus.Interface(obj, PHONEBOOK_ACCESS_INTERFACE)
|
|
bus.add_signal_receiver(self.properties_changed,
|
|
dbus_interface="org.freedesktop.DBus.Properties",
|
|
signal_name="PropertiesChanged",
|
|
path_keyword="path")
|
|
|
|
def register(self, path, properties, transfer):
|
|
transfer.path = path
|
|
transfer.filename = properties["Filename"]
|
|
self.props[path] = transfer
|
|
print("Transfer created: %s (file %s)" % (path,
|
|
transfer.filename))
|
|
|
|
def error(self, err):
|
|
print(err)
|
|
mainloop.quit()
|
|
|
|
def transfer_complete(self, path):
|
|
req = self.props.get(path)
|
|
if req == None:
|
|
return
|
|
self.transfers -= 1
|
|
print("Transfer %s complete" % path)
|
|
try:
|
|
f = open(req.filename, "r")
|
|
os.remove(req.filename)
|
|
lines = f.readlines()
|
|
del self.props[path]
|
|
req.callback_func(lines)
|
|
except:
|
|
pass
|
|
|
|
if (len(self.props) == 0) and (self.transfers == 0):
|
|
if self.flush_func != None:
|
|
f = self.flush_func
|
|
self.flush_func = None
|
|
f()
|
|
|
|
def transfer_error(self, path):
|
|
print("Transfer %s error" % path)
|
|
mainloop.quit()
|
|
|
|
def properties_changed(self, interface, properties, invalidated, path):
|
|
req = self.props.get(path)
|
|
if req == None:
|
|
return
|
|
|
|
if properties['Status'] == 'complete':
|
|
self.transfer_complete(path)
|
|
return
|
|
|
|
if properties['Status'] == 'error':
|
|
self.transfer_error(path)
|
|
return
|
|
|
|
def pull(self, vcard, params, func):
|
|
req = Transfer(func)
|
|
self.pbap.Pull(vcard, "", params,
|
|
reply_handler=lambda o, p: self.register(o, p, req),
|
|
error_handler=self.error)
|
|
self.transfers += 1
|
|
|
|
def pull_all(self, params, func):
|
|
req = Transfer(func)
|
|
self.pbap.PullAll("", params,
|
|
reply_handler=lambda o, p: self.register(o, p, req),
|
|
error_handler=self.error)
|
|
self.transfers += 1
|
|
|
|
def flush_transfers(self, func):
|
|
if (len(self.props) == 0) and (self.transfers == 0):
|
|
return
|
|
self.flush_func = func
|
|
|
|
def interface(self):
|
|
return self.pbap
|
|
|
|
if __name__ == '__main__':
|
|
|
|
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
|
|
|
|
bus = dbus.SessionBus()
|
|
mainloop = GObject.MainLoop()
|
|
|
|
client = dbus.Interface(bus.get_object(BUS_NAME, PATH),
|
|
CLIENT_INTERFACE)
|
|
|
|
if (len(sys.argv) < 2):
|
|
print("Usage: %s <device>" % (sys.argv[0]))
|
|
sys.exit(1)
|
|
|
|
print("Creating Session")
|
|
session_path = client.CreateSession(sys.argv[1], { "Target": "PBAP" })
|
|
|
|
pbap_client = PbapClient(session_path)
|
|
|
|
def process_result(lines, header):
|
|
if header != None:
|
|
print(header)
|
|
for line in lines:
|
|
print(line),
|
|
print
|
|
|
|
def test_paths(paths):
|
|
if len(paths) == 0:
|
|
print
|
|
print("FINISHED")
|
|
mainloop.quit()
|
|
return
|
|
|
|
path = paths[0]
|
|
|
|
print("\n--- Select Phonebook %s ---\n" % (path))
|
|
pbap_client.interface().Select("int", path)
|
|
|
|
print("\n--- GetSize ---\n")
|
|
ret = pbap_client.interface().GetSize()
|
|
print("Size = %d\n" % (ret))
|
|
|
|
print("\n--- List vCard ---\n")
|
|
try:
|
|
ret = pbap_client.interface().List(dbus.Dictionary())
|
|
except:
|
|
ret = []
|
|
|
|
params = dbus.Dictionary({ "Format" : "vcard30",
|
|
"Fields" : ["PHOTO"] })
|
|
for item in ret:
|
|
print("%s : %s" % (item[0], item[1]))
|
|
pbap_client.pull(item[0], params,
|
|
lambda x: process_result(x, None))
|
|
|
|
pbap_client.pull_all(params, lambda x: process_result(x,
|
|
"\n--- PullAll ---\n"))
|
|
|
|
pbap_client.flush_transfers(lambda: test_paths(paths[1:]))
|
|
|
|
test_paths(["PB", "ICH", "OCH", "MCH", "CCH", "SPD", "FAV"])
|
|
|
|
mainloop.run()
|