ble-wifi-example-tests: Add fixes and cleanups to ble and wifi tests

(cherry picked from commit 2d22374460)
This commit is contained in:
Shivani Tipnis
2021-06-01 12:42:28 +05:30
parent 71cf821659
commit be960bc3dc
10 changed files with 1088 additions and 1110 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -18,6 +18,7 @@
# Register Advertisement
from __future__ import print_function
import sys
try:
@@ -27,11 +28,10 @@ except ImportError as e:
if 'linux' not in sys.platform:
raise e
print(e)
print("Install packages `libgirepository1.0-dev gir1.2-gtk-3.0 libcairo2-dev libdbus-1-dev libdbus-glib-1-dev` for resolving the issue")
print("Run `pip install -r $IDF_PATH/tools/ble/requirements.txt` for resolving the issue")
print('Install packages `libgirepository1.0-dev gir1.2-gtk-3.0 libcairo2-dev libdbus-1-dev libdbus-glib-1-dev` for resolving the issue')
print('Run `pip install -r $IDF_PATH/tools/ble/requirements.txt` for resolving the issue')
raise
ADV_OBJ = False
DBUS_PROP_IFACE = 'org.freedesktop.DBus.Properties'
LE_ADVERTISEMENT_IFACE = 'org.bluez.LEAdvertisement1'
@@ -74,10 +74,8 @@ class Advertisement(dbus.service.Object):
in_signature='s',
out_signature='a{sv}')
def GetAll(self, interface):
global ADV_OBJ
if interface != LE_ADVERTISEMENT_IFACE:
raise InvalidArgsException()
ADV_OBJ = True
return self.get_properties()[LE_ADVERTISEMENT_IFACE]
@dbus.service.method(LE_ADVERTISEMENT_IFACE,

View File

@@ -18,6 +18,7 @@
# Creating GATT Application which then becomes available to remote devices.
from __future__ import print_function
import sys
try:
@@ -27,17 +28,10 @@ except ImportError as e:
if 'linux' not in sys.platform:
raise e
print(e)
print("Install packages `libgirepository1.0-dev gir1.2-gtk-3.0 libcairo2-dev libdbus-1-dev libdbus-glib-1-dev` for resolving the issue")
print("Run `pip install -r $IDF_PATH/tools/ble/requirements.txt` for resolving the issue")
print('Install packages `libgirepository1.0-dev gir1.2-gtk-3.0 libcairo2-dev libdbus-1-dev libdbus-glib-1-dev` for resolving the issue')
print('Run `pip install -r $IDF_PATH/tools/ble/requirements.txt` for resolving the issue')
raise
alert_status_char_obj = None
GATT_APP_OBJ = False
CHAR_READ = False
CHAR_WRITE = False
CHAR_SUBSCRIBE = False
DBUS_OM_IFACE = 'org.freedesktop.DBus.ObjectManager'
DBUS_PROP_IFACE = 'org.freedesktop.DBus.Properties'
GATT_MANAGER_IFACE = 'org.bluez.GattManager1'
@@ -46,6 +40,21 @@ GATT_CHRC_IFACE = 'org.bluez.GattCharacteristic1'
GATT_DESC_IFACE = 'org.bluez.GattDescriptor1'
SERVICE_UUIDS = {
'ALERT_NOTIF_SVC_UUID': '00001811-0000-1000-8000-00805f9b34fb'
}
CHAR_UUIDS = {
'SUPPORT_NEW_ALERT_UUID': '00002A47-0000-1000-8000-00805f9b34fb',
'ALERT_NOTIF_UUID': '00002A44-0000-1000-8000-00805f9b34fb',
'UNREAD_ALERT_STATUS_UUID': '00002A45-0000-1000-8000-00805f9b34fb'
}
DESCR_UUIDS = {
'CCCD_UUID': '00002902-0000-1000-8000-00805f9b34fb'
}
class InvalidArgsException(dbus.exceptions.DBusException):
_dbus_error_name = 'org.freedesktop.DBus.Error.InvalidArgs'
@@ -62,22 +71,16 @@ class Application(dbus.service.Object):
def __init__(self, bus, path):
self.path = path
self.services = []
srv_obj = AlertNotificationService(bus, '0001')
self.add_service(srv_obj)
dbus.service.Object.__init__(self, bus, self.path)
def __del__(self):
pass
def get_path(self):
return dbus.ObjectPath(self.path)
def add_service(self, service):
self.services.append(service)
@dbus.service.method(DBUS_OM_IFACE, out_signature='a{oa{sa{sv}}}')
def GetManagedObjects(self):
global GATT_APP_OBJ
response = {}
for service in self.services:
@@ -89,13 +92,25 @@ class Application(dbus.service.Object):
for desc in descs:
response[desc.get_path()] = desc.get_properties()
GATT_APP_OBJ = True
return response
def get_path(self):
return dbus.ObjectPath(self.path)
def Release(self):
pass
class AlertNotificationApp(Application):
'''
Alert Notification Application
'''
def __init__(self, bus, path):
Application.__init__(self, bus, path)
self.service = AlertNotificationService(bus, '0001')
self.add_service(self.service)
class Service(dbus.service.Object):
"""
org.bluez.GattService1 interface implementation
@@ -190,7 +205,6 @@ class Characteristic(dbus.service.Object):
def GetAll(self, interface):
if interface != GATT_CHRC_IFACE:
raise InvalidArgsException()
return self.get_properties()[GATT_CHRC_IFACE]
@dbus.service.method(GATT_CHRC_IFACE, in_signature='a{sv}', out_signature='ay')
@@ -216,7 +230,8 @@ class Characteristic(dbus.service.Object):
@dbus.service.signal(DBUS_PROP_IFACE,
signature='sa{sv}as')
def PropertiesChanged(self, interface, changed, invalidated):
print("\nProperties Changed")
pass
# print('\nProperties Changed')
class Descriptor(dbus.service.Object):
@@ -249,7 +264,6 @@ class Descriptor(dbus.service.Object):
def GetAll(self, interface):
if interface != GATT_DESC_IFACE:
raise InvalidArgsException()
return self.get_properties()[GATT_DESC_IFACE]
@dbus.service.method(GATT_DESC_IFACE, in_signature='a{sv}', out_signature='ay')
@@ -262,151 +276,155 @@ class Descriptor(dbus.service.Object):
print('Default WriteValue called, returning error')
raise NotSupportedException()
@dbus.service.signal(DBUS_PROP_IFACE,
signature='sa{sv}as')
def PropertiesChanged(self, interface, changed, invalidated):
pass
# print('\nProperties Changed')
class AlertNotificationService(Service):
TEST_SVC_UUID = '00001811-0000-1000-8000-00805f9b34fb'
def __init__(self, bus, index):
global alert_status_char_obj
Service.__init__(self, bus, index, self.TEST_SVC_UUID, primary=True)
Service.__init__(self, bus, index, SERVICE_UUIDS['ALERT_NOTIF_SVC_UUID'], primary=True)
self.add_characteristic(SupportedNewAlertCategoryCharacteristic(bus, '0001', self))
self.add_characteristic(AlertNotificationControlPointCharacteristic(bus, '0002', self))
alert_status_char_obj = UnreadAlertStatusCharacteristic(bus, '0003', self)
self.add_characteristic(alert_status_char_obj)
self.add_characteristic(UnreadAlertStatusCharacteristic(bus, '0003', self))
def get_char_status(self, uuid, status):
for char in self.characteristics:
if char.uuid == uuid:
if status in char.status:
return True
return False
class SupportedNewAlertCategoryCharacteristic(Characteristic):
SUPPORT_NEW_ALERT_UUID = '00002A47-0000-1000-8000-00805f9b34fb'
def __init__(self, bus, index, service):
Characteristic.__init__(
self, bus, index,
self.SUPPORT_NEW_ALERT_UUID,
CHAR_UUIDS['SUPPORT_NEW_ALERT_UUID'],
['read'],
service)
self.value = [dbus.Byte(2)]
self.status = []
def ReadValue(self, options):
global CHAR_READ
CHAR_READ = True
val_list = []
for val in self.value:
val_list.append(dbus.Byte(val))
print("Read Request received\n", "\tSupportedNewAlertCategoryCharacteristic")
print("\tValue:", "\t", val_list)
print('Read Request received\n', '\tSupportedNewAlertCategoryCharacteristic')
print('\tValue:', '\t', val_list)
self.status.append('read')
return val_list
class AlertNotificationControlPointCharacteristic(Characteristic):
ALERT_NOTIF_UUID = '00002A44-0000-1000-8000-00805f9b34fb'
def __init__(self, bus, index, service):
Characteristic.__init__(
self, bus, index,
self.ALERT_NOTIF_UUID,
['read','write'],
CHAR_UUIDS['ALERT_NOTIF_UUID'],
['read', 'write'],
service)
self.value = [dbus.Byte(0)]
self.status = []
def ReadValue(self, options):
val_list = []
for val in self.value:
val_list.append(dbus.Byte(val))
print("Read Request received\n", "\tAlertNotificationControlPointCharacteristic")
print("\tValue:", "\t", val_list)
print('Read Request received\n', '\tAlertNotificationControlPointCharacteristic')
print('\tValue:', '\t', val_list)
self.status.append('read')
return val_list
def WriteValue(self, value, options):
global CHAR_WRITE
CHAR_WRITE = True
print("Write Request received\n", "\tAlertNotificationControlPointCharacteristic")
print("\tCurrent value:", "\t", self.value)
print('Write Request received\n', '\tAlertNotificationControlPointCharacteristic')
print('\tCurrent value:', '\t', self.value)
val_list = []
for val in value:
val_list.append(val)
self.value = val_list
self.PropertiesChanged(GATT_CHRC_IFACE, {'Value': self.value}, [])
# Check if new value is written
print("\tNew value:", "\t", self.value)
print('\tNew value:', '\t', self.value)
if not self.value == value:
print("Failed: Write Request\n\tNew value not written\tCurrent value:", self.value)
print('Failed: Write Request\n\tNew value not written\tCurrent value:', self.value)
self.status.append('write')
class UnreadAlertStatusCharacteristic(Characteristic):
UNREAD_ALERT_STATUS_UUID = '00002A45-0000-1000-8000-00805f9b34fb'
def __init__(self, bus, index, service):
Characteristic.__init__(
self, bus, index,
self.UNREAD_ALERT_STATUS_UUID,
CHAR_UUIDS['UNREAD_ALERT_STATUS_UUID'],
['read', 'write', 'notify'],
service)
self.value = [dbus.Byte(0)]
self.cccd_obj = ClientCharacteristicConfigurationDescriptor(bus, '0001', self)
self.add_descriptor(self.cccd_obj)
self.notifying = False
self.status = []
def StartNotify(self):
global CHAR_SUBSCRIBE
CHAR_SUBSCRIBE = True
try:
if self.notifying:
print('\nAlready notifying, nothing to do')
return
print('Notify Started')
self.notifying = True
self.ReadValue()
self.WriteValue([dbus.Byte(1), dbus.Byte(0)])
self.status.append('notify')
if self.notifying:
print('\nAlready notifying, nothing to do')
return
self.notifying = True
print("\nNotify Started")
self.cccd_obj.WriteValue([dbus.Byte(1), dbus.Byte(0)])
self.cccd_obj.ReadValue()
except Exception as e:
print(e)
def StopNotify(self):
if not self.notifying:
print('\nNot notifying, nothing to do')
return
self.notifying = False
print("\nNotify Stopped")
print('\nNotify Stopped')
def ReadValue(self, options):
print("Read Request received\n", "\tUnreadAlertStatusCharacteristic")
def ReadValue(self, options=None):
val_list = []
for val in self.value:
val_list.append(dbus.Byte(val))
print("\tValue:", "\t", val_list)
self.status.append('read')
print('\tValue:', '\t', val_list)
return val_list
def WriteValue(self, value, options):
print("Write Request received\n", "\tUnreadAlertStatusCharacteristic")
def WriteValue(self, value, options=None):
val_list = []
for val in value:
val_list.append(val)
self.value = val_list
self.PropertiesChanged(GATT_CHRC_IFACE, {'Value': self.value}, [])
# Check if new value is written
print("\tNew value:", "\t", self.value)
if not self.value == value:
print("Failed: Write Request\n\tNew value not written\tCurrent value:", self.value)
print('Failed: Write Request\n\tNew value not written\tCurrent value:', self.value)
print('New value:', '\t', self.value)
self.status.append('write')
class ClientCharacteristicConfigurationDescriptor(Descriptor):
CCCD_UUID = '00002902-0000-1000-8000-00805f9b34fb'
def __init__(self, bus, index, characteristic):
self.value = [dbus.Byte(0)]
self.value = [dbus.Byte(1)]
Descriptor.__init__(
self, bus, index,
self.CCCD_UUID,
DESCR_UUIDS['CCCD_UUID'],
['read', 'write'],
characteristic)
def ReadValue(self):
print("\tValue on read:", "\t", self.value)
def ReadValue(self, options=None):
return self.value
def WriteValue(self, value):
def WriteValue(self, value, options=None):
val_list = []
for val in value:
val_list.append(val)
self.value = val_list
self.PropertiesChanged(GATT_DESC_IFACE, {'Value': self.value}, [])
# Check if new value is written
print("New value on write:", "\t", self.value)
if not self.value == value:
print("Failed: Write Request\n\tNew value not written\tCurrent value:", self.value)
print('Failed: Write Request\n\tNew value not written\tCurrent value:', self.value)

View File

@@ -13,10 +13,11 @@
# limitations under the License.
#
import time
import dbus
import dbus.mainloop.glib
import netifaces
import time
def get_wiface_name():
@@ -43,25 +44,30 @@ class wpa_cli:
self.new_network = None
self.connected = False
self.reset_on_exit = reset_on_exit
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
bus = dbus.SystemBus()
service = dbus.Interface(bus.get_object("fi.w1.wpa_supplicant1", "/fi/w1/wpa_supplicant1"),
"fi.w1.wpa_supplicant1")
iface_path = service.GetInterface(self.iface_name)
self.iface_obj = bus.get_object("fi.w1.wpa_supplicant1", iface_path)
self.iface_ifc = dbus.Interface(self.iface_obj, "fi.w1.wpa_supplicant1.Interface")
self.iface_props = dbus.Interface(self.iface_obj, 'org.freedesktop.DBus.Properties')
if self.iface_ifc is None:
raise RuntimeError('supplicant : Failed to fetch interface')
try:
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
bus = dbus.SystemBus()
self.old_network = self._get_iface_property("CurrentNetwork")
print("Old network is %s" % self.old_network)
service = dbus.Interface(bus.get_object('fi.w1.wpa_supplicant1', '/fi/w1/wpa_supplicant1'),
'fi.w1.wpa_supplicant1')
iface_path = service.GetInterface(self.iface_name)
self.iface_obj = bus.get_object('fi.w1.wpa_supplicant1', iface_path)
self.iface_ifc = dbus.Interface(self.iface_obj, 'fi.w1.wpa_supplicant1.Interface')
self.iface_props = dbus.Interface(self.iface_obj, 'org.freedesktop.DBus.Properties')
if self.iface_ifc is None:
raise RuntimeError('supplicant : Failed to fetch interface')
if self.old_network == '/':
self.old_network = None
else:
self.connected = True
self.old_network = self._get_iface_property('CurrentNetwork')
print('Old network is %s' % self.old_network)
if self.old_network == '/':
self.old_network = None
else:
self.connected = True
except Exception as err:
raise Exception('Failure in wpa_cli init: {}'.format(err))
def _get_iface_property(self, name):
""" Read the property with 'name' from the wi-fi interface object
@@ -69,40 +75,44 @@ class wpa_cli:
Note: The result is a dbus wrapped type, so should usually convert it to the corresponding native
Python type
"""
return self.iface_props.Get("fi.w1.wpa_supplicant1.Interface", name)
return self.iface_props.Get('fi.w1.wpa_supplicant1.Interface', name)
def connect(self, ssid, password):
if self.connected is True:
self.iface_ifc.Disconnect()
self.connected = False
try:
if self.connected is True:
self.iface_ifc.Disconnect()
self.connected = False
if self.new_network is not None:
self.iface_ifc.RemoveNetwork(self.new_network)
if self.new_network is not None:
self.iface_ifc.RemoveNetwork(self.new_network)
print("Pre-connect state is %s, IP is %s" % (self._get_iface_property("State"), get_wiface_IPv4(self.iface_name)))
print('Pre-connect state is %s, IP is %s' % (self._get_iface_property('State'), get_wiface_IPv4(self.iface_name)))
self.new_network = self.iface_ifc.AddNetwork({"ssid": ssid, "psk": password})
self.iface_ifc.SelectNetwork(self.new_network)
self.new_network = self.iface_ifc.AddNetwork({'ssid': ssid, 'psk': password})
self.iface_ifc.SelectNetwork(self.new_network)
time.sleep(10)
ip = None
retry = 10
while retry > 0:
time.sleep(5)
ip = None
retry = 10
while retry > 0:
time.sleep(5)
state = str(self._get_iface_property('State'))
print('wpa iface state %s (scanning %s)' % (state, bool(self._get_iface_property('Scanning'))))
if state in ['disconnected', 'inactive']:
self.iface_ifc.Reconnect()
ip = get_wiface_IPv4(self.iface_name)
print('wpa iface %s IP %s' % (self.iface_name, ip))
if ip is not None:
self.connected = True
return ip
retry -= 1
time.sleep(3)
state = str(self._get_iface_property("State"))
print("wpa iface state %s (scanning %s)" % (state, bool(self._get_iface_property("Scanning"))))
if state in ["disconnected", "inactive"]:
self.iface_ifc.Reconnect()
self.reset()
print('wpa_cli : Connection failed')
ip = get_wiface_IPv4(self.iface_name)
print("wpa iface %s IP %s" % (self.iface_name, ip))
if ip is not None:
self.connected = True
return ip
retry -= 1
self.reset()
raise RuntimeError('wpa_cli : Connection failed')
except Exception as err:
raise Exception('Failure in wpa_cli init: {}'.format(err))
def reset(self):
if self.iface_ifc is not None:

View File

@@ -14,12 +14,12 @@
#
from __future__ import print_function
from builtins import input
from future.utils import iteritems
import platform
from builtins import input
import utils
from future.utils import iteritems
fallback = True
@@ -28,9 +28,10 @@ fallback = True
# else fallback to console mode
if platform.system() == 'Linux':
try:
import time
import dbus
import dbus.mainloop.glib
import time
fallback = False
except ImportError:
pass
@@ -41,13 +42,15 @@ if platform.system() == 'Linux':
# BLE client (Linux Only) using Bluez and DBus
class BLE_Bluez_Client:
def __init__(self):
self.adapter_props = None
def connect(self, devname, iface, chrc_names, fallback_srv_uuid):
self.devname = devname
self.srv_uuid_fallback = fallback_srv_uuid
self.chrc_names = [name.lower() for name in chrc_names]
self.device = None
self.adapter = None
self.adapter_props = None
self.services = None
self.nu_lookup = None
self.characteristics = dict()
@@ -55,33 +58,69 @@ class BLE_Bluez_Client:
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
bus = dbus.SystemBus()
manager = dbus.Interface(bus.get_object("org.bluez", "/"), "org.freedesktop.DBus.ObjectManager")
manager = dbus.Interface(bus.get_object('org.bluez', '/'), 'org.freedesktop.DBus.ObjectManager')
objects = manager.GetManagedObjects()
adapter_path = None
for path, interfaces in iteritems(objects):
adapter = interfaces.get("org.bluez.Adapter1")
adapter = interfaces.get('org.bluez.Adapter1')
if adapter is not None:
if path.endswith(iface):
self.adapter = dbus.Interface(bus.get_object("org.bluez", path), "org.bluez.Adapter1")
self.adapter_props = dbus.Interface(bus.get_object("org.bluez", path), "org.freedesktop.DBus.Properties")
self.adapter = dbus.Interface(bus.get_object('org.bluez', path), 'org.bluez.Adapter1')
self.adapter_props = dbus.Interface(bus.get_object('org.bluez', path), 'org.freedesktop.DBus.Properties')
adapter_path = path
break
if self.adapter is None:
raise RuntimeError("Bluetooth adapter not found")
raise RuntimeError('Bluetooth adapter not found')
self.adapter_props.Set("org.bluez.Adapter1", "Powered", dbus.Boolean(1))
self.adapter.StartDiscovery()
# Power on bluetooth adapter
self.adapter_props.Set('org.bluez.Adapter1', 'Powered', dbus.Boolean(1))
print('checking if adapter is powered on')
for cnt in range(10, 0, -1):
time.sleep(5)
powered_on = self.adapter_props.Get('org.bluez.Adapter1', 'Powered')
if powered_on == 1:
# Set adapter props again with powered on value
self.adapter_props = dbus.Interface(bus.get_object('org.bluez', adapter_path), 'org.freedesktop.DBus.Properties')
print('bluetooth adapter powered on')
break
print('number of retries left({})'.format(cnt - 1))
if powered_on == 0:
raise RuntimeError('Failed to starte bluetooth adapter')
# Start discovery if not already discovering
started_discovery = 0
discovery_val = self.adapter_props.Get('org.bluez.Adapter1', 'Discovering')
if discovery_val == 0:
print('starting discovery')
self.adapter.StartDiscovery()
# Set as start discovery is called
started_discovery = 1
for cnt in range(10, 0, -1):
time.sleep(5)
discovery_val = self.adapter_props.Get('org.bluez.Adapter1', 'Discovering')
if discovery_val == 1:
print('start discovery successful')
break
print('number of retries left ({})'.format(cnt - 1))
if discovery_val == 0:
print('start discovery failed')
raise RuntimeError('Failed to start discovery')
retry = 10
while (retry > 0):
try:
if self.device is None:
print("Connecting...")
print('Connecting...')
# Wait for device to be discovered
time.sleep(5)
self._connect_()
print("Connected")
print("Getting Services...")
connected = self._connect_()
if connected:
print('Connected')
else:
return False
print('Getting Services...')
# Wait for services to be discovered
time.sleep(5)
self._get_services_()
@@ -89,28 +128,42 @@ class BLE_Bluez_Client:
except Exception as e:
print(e)
retry -= 1
print("Retries left", retry)
print('Retries left', retry)
continue
self.adapter.StopDiscovery()
# Call StopDiscovery() for corresponding StartDiscovery() session
if started_discovery == 1:
print('stopping discovery')
self.adapter.StopDiscovery()
for cnt in range(10, 0, -1):
time.sleep(5)
discovery_val = self.adapter_props.Get('org.bluez.Adapter1', 'Discovering')
if discovery_val == 0:
print('stop discovery successful')
break
print('number of retries left ({})'.format(cnt - 1))
if discovery_val == 1:
print('stop discovery failed')
return False
def _connect_(self):
bus = dbus.SystemBus()
manager = dbus.Interface(bus.get_object("org.bluez", "/"), "org.freedesktop.DBus.ObjectManager")
manager = dbus.Interface(bus.get_object('org.bluez', '/'), 'org.freedesktop.DBus.ObjectManager')
objects = manager.GetManagedObjects()
dev_path = None
for path, interfaces in iteritems(objects):
if "org.bluez.Device1" not in interfaces:
if 'org.bluez.Device1' not in interfaces:
continue
if interfaces["org.bluez.Device1"].get("Name") == self.devname:
if interfaces['org.bluez.Device1'].get('Name') == self.devname:
dev_path = path
break
if dev_path is None:
raise RuntimeError("BLE device not found")
raise RuntimeError('BLE device not found')
try:
self.device = bus.get_object("org.bluez", dev_path)
self.device = bus.get_object('org.bluez', dev_path)
try:
uuids = self.device.Get('org.bluez.Device1', 'UUIDs',
dbus_interface='org.freedesktop.DBus.Properties')
@@ -122,25 +175,42 @@ class BLE_Bluez_Client:
if len(uuids) == 1:
self.srv_uuid_adv = uuids[0]
except dbus.exceptions.DBusException as e:
print(e)
raise RuntimeError(e)
self.device.Connect(dbus_interface='org.bluez.Device1')
# Check device is connected successfully
for cnt in range(10, 0, -1):
time.sleep(5)
device_conn = self.device.Get(
'org.bluez.Device1',
'Connected',
dbus_interface='org.freedesktop.DBus.Properties')
if device_conn == 1:
print('device is connected')
break
print('number of retries left ({})'.format(cnt - 1))
if device_conn == 0:
print('failed to connect device')
return False
return True
except Exception as e:
print(e)
self.device = None
raise RuntimeError("BLE device could not connect")
raise RuntimeError('BLE device could not connect')
def _get_services_(self):
bus = dbus.SystemBus()
manager = dbus.Interface(bus.get_object("org.bluez", "/"), "org.freedesktop.DBus.ObjectManager")
manager = dbus.Interface(bus.get_object('org.bluez', '/'), 'org.freedesktop.DBus.ObjectManager')
objects = manager.GetManagedObjects()
service_found = False
for srv_path, srv_interfaces in iteritems(objects):
if "org.bluez.GattService1" not in srv_interfaces:
if 'org.bluez.GattService1' not in srv_interfaces:
continue
if not srv_path.startswith(self.device.object_path):
continue
service = bus.get_object("org.bluez", srv_path)
service = bus.get_object('org.bluez', srv_path)
srv_uuid = service.Get('org.bluez.GattService1', 'UUID',
dbus_interface='org.freedesktop.DBus.Properties')
@@ -152,28 +222,28 @@ class BLE_Bluez_Client:
nu_lookup = dict()
characteristics = dict()
for chrc_path, chrc_interfaces in iteritems(objects):
if "org.bluez.GattCharacteristic1" not in chrc_interfaces:
if 'org.bluez.GattCharacteristic1' not in chrc_interfaces:
continue
if not chrc_path.startswith(service.object_path):
continue
chrc = bus.get_object("org.bluez", chrc_path)
chrc = bus.get_object('org.bluez', chrc_path)
uuid = chrc.Get('org.bluez.GattCharacteristic1', 'UUID',
dbus_interface='org.freedesktop.DBus.Properties')
characteristics[uuid] = chrc
for desc_path, desc_interfaces in iteritems(objects):
if "org.bluez.GattDescriptor1" not in desc_interfaces:
if 'org.bluez.GattDescriptor1' not in desc_interfaces:
continue
if not desc_path.startswith(chrc.object_path):
continue
desc = bus.get_object("org.bluez", desc_path)
desc = bus.get_object('org.bluez', desc_path)
desc_uuid = desc.Get('org.bluez.GattDescriptor1', 'UUID',
dbus_interface='org.freedesktop.DBus.Properties')
if desc_uuid[4:8] != '2901':
continue
try:
readval = desc.ReadValue({}, dbus_interface='org.bluez.GattDescriptor1')
except dbus.exceptions.DBusException:
break
except dbus.exceptions.DBusException as err:
raise RuntimeError('Failed to read value for descriptor while getting services - {}'.format(err))
found_name = ''.join(chr(b) for b in readval).lower()
nu_lookup[found_name] = uuid
break
@@ -200,12 +270,14 @@ class BLE_Bluez_Client:
if not service_found:
self.device.Disconnect(dbus_interface='org.bluez.Device1')
# Check if device is disconnected successfully
self._check_device_disconnected()
if self.adapter:
self.adapter.RemoveDevice(self.device)
self.device = None
self.nu_lookup = None
self.characteristics = dict()
raise RuntimeError("Provisioning service not found")
raise RuntimeError('Provisioning service not found')
def get_nu_lookup(self):
return self.nu_lookup
@@ -218,31 +290,47 @@ class BLE_Bluez_Client:
def disconnect(self):
if self.device:
self.device.Disconnect(dbus_interface='org.bluez.Device1')
# Check if device is disconnected successfully
self._check_device_disconnected()
if self.adapter:
self.adapter.RemoveDevice(self.device)
self.device = None
self.nu_lookup = None
self.characteristics = dict()
if self.adapter_props:
self.adapter_props.Set("org.bluez.Adapter1", "Powered", dbus.Boolean(0))
self.adapter_props.Set('org.bluez.Adapter1', 'Powered', dbus.Boolean(0))
def _check_device_disconnected(self):
for cnt in range(10, 0, -1):
time.sleep(5)
device_conn = self.device.Get(
'org.bluez.Device1',
'Connected',
dbus_interface='org.freedesktop.DBus.Properties')
if device_conn == 0:
print('device disconnected')
break
print('number of retries left ({})'.format(cnt - 1))
if device_conn == 1:
print('failed to disconnect device')
def send_data(self, characteristic_uuid, data):
try:
path = self.characteristics[characteristic_uuid]
except KeyError:
raise RuntimeError("Invalid characteristic : " + characteristic_uuid)
raise RuntimeError('Invalid characteristic : ' + characteristic_uuid)
try:
path.WriteValue([ord(c) for c in data], {}, dbus_interface='org.bluez.GattCharacteristic1')
except TypeError: # python3 compatible
path.WriteValue([c for c in data], {}, dbus_interface='org.bluez.GattCharacteristic1')
except dbus.exceptions.DBusException as e:
raise RuntimeError("Failed to write value to characteristic " + characteristic_uuid + ": " + str(e))
raise RuntimeError('Failed to write value to characteristic ' + characteristic_uuid + ': ' + str(e))
try:
readval = path.ReadValue({}, dbus_interface='org.bluez.GattCharacteristic1')
except dbus.exceptions.DBusException as e:
raise RuntimeError("Failed to read value from characteristic " + characteristic_uuid + ": " + str(e))
raise RuntimeError('Failed to read value from characteristic ' + characteristic_uuid + ': ' + str(e))
return ''.join(chr(b) for b in readval)
@@ -252,14 +340,14 @@ class BLE_Bluez_Client:
# Console based BLE client for Cross Platform support
class BLE_Console_Client:
def connect(self, devname, iface, chrc_names, fallback_srv_uuid):
print("BLE client is running in console mode")
print("\tThis could be due to your platform not being supported or dependencies not being met")
print("\tPlease ensure all pre-requisites are met to run the full fledged client")
print("BLECLI >> Please connect to BLE device `" + devname + "` manually using your tool of choice")
resp = input("BLECLI >> Was the device connected successfully? [y/n] ")
print('BLE client is running in console mode')
print('\tThis could be due to your platform not being supported or dependencies not being met')
print('\tPlease ensure all pre-requisites are met to run the full fledged client')
print('BLECLI >> Please connect to BLE device `' + devname + '` manually using your tool of choice')
resp = input('BLECLI >> Was the device connected successfully? [y/n] ')
if resp != 'Y' and resp != 'y':
return False
print("BLECLI >> List available attributes of the connected device")
print('BLECLI >> List available attributes of the connected device')
resp = input("BLECLI >> Is the service UUID '" + fallback_srv_uuid + "' listed among available attributes? [y/n] ")
if resp != 'Y' and resp != 'y':
return False
@@ -279,9 +367,9 @@ class BLE_Console_Client:
def send_data(self, characteristic_uuid, data):
print("BLECLI >> Write following data to characteristic with UUID '" + characteristic_uuid + "' :")
print("\t>> " + utils.str_to_hexstr(data))
print("BLECLI >> Enter data read from characteristic (in hex) :")
resp = input("\t<< ")
print('\t>> ' + utils.str_to_hexstr(data))
print('BLECLI >> Enter data read from characteristic (in hex) :')
resp = input('\t<< ')
return utils.hexstr_to_str(resp)

View File

@@ -14,9 +14,11 @@
#
from __future__ import print_function
from future.utils import tobytes
import socket
from future.utils import tobytes
try:
from http.client import HTTPConnection, HTTPSConnection
except ImportError:
@@ -31,28 +33,28 @@ class Transport_HTTP(Transport):
try:
socket.gethostbyname(hostname.split(':')[0])
except socket.gaierror:
raise RuntimeError("Unable to resolve hostname :" + hostname)
raise RuntimeError('Unable to resolve hostname :' + hostname)
if ssl_context is None:
self.conn = HTTPConnection(hostname, timeout=45)
self.conn = HTTPConnection(hostname, timeout=60)
else:
self.conn = HTTPSConnection(hostname, context=ssl_context, timeout=45)
self.conn = HTTPSConnection(hostname, context=ssl_context, timeout=60)
try:
print("Connecting to " + hostname)
print('Connecting to ' + hostname)
self.conn.connect()
except Exception as err:
raise RuntimeError("Connection Failure : " + str(err))
self.headers = {"Content-type": "application/x-www-form-urlencoded","Accept": "text/plain"}
raise RuntimeError('Connection Failure : ' + str(err))
self.headers = {'Content-type': 'application/x-www-form-urlencoded','Accept': 'text/plain'}
def _send_post_request(self, path, data):
try:
self.conn.request("POST", path, tobytes(data), self.headers)
self.conn.request('POST', path, tobytes(data), self.headers)
response = self.conn.getresponse()
if response.status == 200:
return response.read().decode('latin-1')
except Exception as err:
raise RuntimeError("Connection Failure : " + str(err))
raise RuntimeError("Server responded with error code " + str(response.status))
raise RuntimeError('Connection Failure : ' + str(err))
raise RuntimeError('Server responded with error code ' + str(response.status))
def send_data(self, ep_name, data):
return self._send_post_request('/' + ep_name, data)