Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added tx_power in advertisement_data for Windows, Mac and Linux #987

Merged
merged 13 commits into from
Sep 11, 2022
Merged
4 changes: 4 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ and this project adheres to `Semantic Versioning <https://semver.org/spec/v2.0.0
`Unreleased`_
=============

Added
-----
* ``AdvertisementData`` class now has an attribute ``tx_power``. Merged #987.

Changed
-------
* ``BleakClient`` methods now raise ``BleakError`` if called when not connected in WinRT backend.
Expand Down
4 changes: 4 additions & 0 deletions bleak/backends/bluezdbus/scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,13 +231,17 @@ def _handle_advertising_data(self, path: str, props: Device1) -> None:
_service_data = {k: bytes(v) for k, v in props.get("ServiceData", {}).items()}
_service_uuids = props.get("UUIDs", [])

# Get tx power data
tx_power = props.get("TxPower")

# Pack the advertisement data
advertisement_data = AdvertisementData(
local_name=_local_name,
manufacturer_data=_manufacturer_data,
service_data=_service_data,
service_uuids=_service_uuids,
platform_data=props,
tx_power=tx_power,
)

device = BLEDevice(
Expand Down
4 changes: 4 additions & 0 deletions bleak/backends/corebluetooth/scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,16 @@ def callback(p: CBPeripheral, a: Dict[str, Any], r: int) -> None:
cb_uuid_to_str(u) for u in a.get("kCBAdvDataServiceUUIDs", [])
]

# set tx_power data if available
tx_power = a.get("kCBAdvDataTxPowerLevel")

advertisement_data = AdvertisementData(
local_name=p.name(),
manufacturer_data=manufacturer_data,
service_data=service_data,
service_uuids=service_uuids,
platform_data=(p, a, r),
tx_power=tx_power,
)

device = BLEDevice(
Expand Down
3 changes: 3 additions & 0 deletions bleak/backends/p4android/defs.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@
BluetoothGattCharacteristic = autoclass("android.bluetooth.BluetoothGattCharacteristic")
BluetoothGattDescriptor = autoclass("android.bluetooth.BluetoothGattDescriptor")
BluetoothProfile = autoclass("android.bluetooth.BluetoothProfile")

PythonActivity = autoclass("org.kivy.android.PythonActivity")
ParcelUuid = autoclass("android.os.ParcelUuid")
activity = cast("android.app.Activity", PythonActivity.mActivity)
context = cast("android.content.Context", activity.getApplicationContext())

ScanResult = autoclass("android.bluetooth.le.ScanResult")

BLEAK_JNI_NAMESPACE = "com.github.hbldh.bleak"
PythonScanCallback = autoclass(BLEAK_JNI_NAMESPACE + ".PythonScanCallback")
PythonBluetoothGattCallback = autoclass(
Expand Down
6 changes: 6 additions & 0 deletions bleak/backends/p4android/scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,13 +276,19 @@ def onScanResult(self, result):
entry.getKey().toString(): bytes(entry.getValue())
for entry in record.getServiceData().entrySet()
}
tx_power = result.getTxPower()

# change "not present" value to None to match other backends
if tx_power == defs.ScanResult.TX_POWER_NOT_PRESENT:
tx_power = None

advertisement = AdvertisementData(
local_name=record.getDeviceName(),
manufacturer_data=manufacturer_data,
service_data=service_data,
service_uuids=service_uuids,
platform_data=(result,),
tx_power=tx_power,
)
device = BLEDevice(
device.getAddress(),
Expand Down
6 changes: 6 additions & 0 deletions bleak/backends/scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ def __init__(self, **kwargs):
service_data (dict): Service data from the device
service_uuids (list): UUIDs associated with the device
platform_data (tuple): Tuple of platform specific advertisement data
tx_power (int): Transmit power level of the device
"""
# The local name of the device
self.local_name: Optional[str] = kwargs.get("local_name", None)
Expand All @@ -44,6 +45,9 @@ def __init__(self, **kwargs):
# Tuple of platform specific data
self.platform_data: Tuple = kwargs.get("platform_data", ())

# Tx Power data
self.tx_power: Optional[int] = kwargs.get("tx_power")

def __repr__(self) -> str:
kwargs = []
if self.local_name:
Expand All @@ -54,6 +58,8 @@ def __repr__(self) -> str:
kwargs.append(f"service_data={repr(self.service_data)}")
if self.service_uuids:
kwargs.append(f"service_uuids={repr(self.service_uuids)}")
if self.tx_power:
kwargs.append(f"tx_power={repr(self.tx_power)}")
return f"AdvertisementData({', '.join(kwargs)})"


Expand Down
4 changes: 4 additions & 0 deletions bleak/backends/winrt/scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,13 +163,17 @@ def _received_handler(
data = bytes(section.data)
service_data[str(UUID(bytes=bytes(data[15::-1])))] = data[16:]

# get transmit power level data
tx_power = raw_data.adv.transmit_power_level_in_d_bm

# Use the BLEDevice to populate all the fields for the advertisement data to return
advertisement_data = AdvertisementData(
local_name=device.name,
manufacturer_data=device.metadata["manufacturer_data"],
service_data=service_data,
service_uuids=device.metadata["uuids"],
platform_data=(sender, raw_data),
tx_power=tx_power,
)

self._callback(device, advertisement_data)
Expand Down