# DO NOT EDIT THIS FILE!
#
# This file is generated from the CDP specification. If you need to make
# changes, edit the generator and regenerate all of the modules.
#
# CDP domain: BluetoothEmulation (experimental)
from __future__ import annotations
import enum
import typing
from dataclasses import dataclass
from .util import event_class, T_JSON_DICT
[docs]
class CentralState(enum.Enum):
'''
Indicates the various states of Central.
'''
ABSENT = "absent"
POWERED_OFF = "powered-off"
POWERED_ON = "powered-on"
def to_json(self) -> str:
return self.value
@classmethod
def from_json(cls, json: str) -> CentralState:
return cls(json)
[docs]
class GATTOperationType(enum.Enum):
'''
Indicates the various types of GATT event.
'''
CONNECTION = "connection"
DISCOVERY = "discovery"
def to_json(self) -> str:
return self.value
@classmethod
def from_json(cls, json: str) -> GATTOperationType:
return cls(json)
[docs]
class CharacteristicWriteType(enum.Enum):
'''
Indicates the various types of characteristic write.
'''
WRITE_DEFAULT_DEPRECATED = "write-default-deprecated"
WRITE_WITH_RESPONSE = "write-with-response"
WRITE_WITHOUT_RESPONSE = "write-without-response"
def to_json(self) -> str:
return self.value
@classmethod
def from_json(cls, json: str) -> CharacteristicWriteType:
return cls(json)
[docs]
class CharacteristicOperationType(enum.Enum):
'''
Indicates the various types of characteristic operation.
'''
READ = "read"
WRITE = "write"
SUBSCRIBE_TO_NOTIFICATIONS = "subscribe-to-notifications"
UNSUBSCRIBE_FROM_NOTIFICATIONS = "unsubscribe-from-notifications"
def to_json(self) -> str:
return self.value
@classmethod
def from_json(cls, json: str) -> CharacteristicOperationType:
return cls(json)
[docs]
class DescriptorOperationType(enum.Enum):
'''
Indicates the various types of descriptor operation.
'''
READ = "read"
WRITE = "write"
def to_json(self) -> str:
return self.value
@classmethod
def from_json(cls, json: str) -> DescriptorOperationType:
return cls(json)
[docs]
@dataclass
class ManufacturerData:
'''
Stores the manufacturer data
'''
#: Company identifier
#: https://bitbucket.org/bluetooth-SIG/public/src/main/assigned_numbers/company_identifiers/company_identifiers.yaml
#: https://usb.org/developers
key: int
#: Manufacturer-specific data (Encoded as a base64 string when passed over JSON)
data: str
def to_json(self) -> T_JSON_DICT:
json: T_JSON_DICT = dict()
json['key'] = self.key
json['data'] = self.data
return json
@classmethod
def from_json(cls, json: T_JSON_DICT) -> ManufacturerData:
return cls(
key=int(json['key']),
data=str(json['data']),
)
[docs]
@dataclass
class ScanRecord:
'''
Stores the byte data of the advertisement packet sent by a Bluetooth device.
'''
name: typing.Optional[str] = None
uuids: typing.Optional[typing.List[str]] = None
#: Stores the external appearance description of the device.
appearance: typing.Optional[int] = None
#: Stores the transmission power of a broadcasting device.
tx_power: typing.Optional[int] = None
#: Key is the company identifier and the value is an array of bytes of
#: manufacturer specific data.
manufacturer_data: typing.Optional[typing.List[ManufacturerData]] = None
def to_json(self) -> T_JSON_DICT:
json: T_JSON_DICT = dict()
if self.name is not None:
json['name'] = self.name
if self.uuids is not None:
json['uuids'] = [i for i in self.uuids]
if self.appearance is not None:
json['appearance'] = self.appearance
if self.tx_power is not None:
json['txPower'] = self.tx_power
if self.manufacturer_data is not None:
json['manufacturerData'] = [i.to_json() for i in self.manufacturer_data]
return json
@classmethod
def from_json(cls, json: T_JSON_DICT) -> ScanRecord:
return cls(
name=str(json['name']) if json.get('name', None) is not None else None,
uuids=[str(i) for i in json['uuids']] if json.get('uuids', None) is not None else None,
appearance=int(json['appearance']) if json.get('appearance', None) is not None else None,
tx_power=int(json['txPower']) if json.get('txPower', None) is not None else None,
manufacturer_data=[ManufacturerData.from_json(i) for i in json['manufacturerData']] if json.get('manufacturerData', None) is not None else None,
)
[docs]
@dataclass
class ScanEntry:
'''
Stores the advertisement packet information that is sent by a Bluetooth device.
'''
device_address: str
rssi: int
scan_record: ScanRecord
def to_json(self) -> T_JSON_DICT:
json: T_JSON_DICT = dict()
json['deviceAddress'] = self.device_address
json['rssi'] = self.rssi
json['scanRecord'] = self.scan_record.to_json()
return json
@classmethod
def from_json(cls, json: T_JSON_DICT) -> ScanEntry:
return cls(
device_address=str(json['deviceAddress']),
rssi=int(json['rssi']),
scan_record=ScanRecord.from_json(json['scanRecord']),
)
[docs]
@dataclass
class CharacteristicProperties:
'''
Describes the properties of a characteristic. This follows Bluetooth Core
Specification BT 4.2 Vol 3 Part G 3.3.1. Characteristic Properties.
'''
broadcast: typing.Optional[bool] = None
read: typing.Optional[bool] = None
write_without_response: typing.Optional[bool] = None
write: typing.Optional[bool] = None
notify: typing.Optional[bool] = None
indicate: typing.Optional[bool] = None
authenticated_signed_writes: typing.Optional[bool] = None
extended_properties: typing.Optional[bool] = None
def to_json(self) -> T_JSON_DICT:
json: T_JSON_DICT = dict()
if self.broadcast is not None:
json['broadcast'] = self.broadcast
if self.read is not None:
json['read'] = self.read
if self.write_without_response is not None:
json['writeWithoutResponse'] = self.write_without_response
if self.write is not None:
json['write'] = self.write
if self.notify is not None:
json['notify'] = self.notify
if self.indicate is not None:
json['indicate'] = self.indicate
if self.authenticated_signed_writes is not None:
json['authenticatedSignedWrites'] = self.authenticated_signed_writes
if self.extended_properties is not None:
json['extendedProperties'] = self.extended_properties
return json
@classmethod
def from_json(cls, json: T_JSON_DICT) -> CharacteristicProperties:
return cls(
broadcast=bool(json['broadcast']) if json.get('broadcast', None) is not None else None,
read=bool(json['read']) if json.get('read', None) is not None else None,
write_without_response=bool(json['writeWithoutResponse']) if json.get('writeWithoutResponse', None) is not None else None,
write=bool(json['write']) if json.get('write', None) is not None else None,
notify=bool(json['notify']) if json.get('notify', None) is not None else None,
indicate=bool(json['indicate']) if json.get('indicate', None) is not None else None,
authenticated_signed_writes=bool(json['authenticatedSignedWrites']) if json.get('authenticatedSignedWrites', None) is not None else None,
extended_properties=bool(json['extendedProperties']) if json.get('extendedProperties', None) is not None else None,
)
[docs]
def enable(
state: CentralState,
le_supported: bool
) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
'''
Enable the BluetoothEmulation domain.
:param state: State of the simulated central.
:param le_supported: If the simulated central supports low-energy.
'''
params: T_JSON_DICT = dict()
params['state'] = state.to_json()
params['leSupported'] = le_supported
cmd_dict: T_JSON_DICT = {
'method': 'BluetoothEmulation.enable',
'params': params,
}
json = yield cmd_dict
[docs]
def set_simulated_central_state(
state: CentralState
) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
'''
Set the state of the simulated central.
:param state: State of the simulated central.
'''
params: T_JSON_DICT = dict()
params['state'] = state.to_json()
cmd_dict: T_JSON_DICT = {
'method': 'BluetoothEmulation.setSimulatedCentralState',
'params': params,
}
json = yield cmd_dict
[docs]
def disable() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
'''
Disable the BluetoothEmulation domain.
'''
cmd_dict: T_JSON_DICT = {
'method': 'BluetoothEmulation.disable',
}
json = yield cmd_dict
[docs]
def simulate_preconnected_peripheral(
address: str,
name: str,
manufacturer_data: typing.List[ManufacturerData],
known_service_uuids: typing.List[str]
) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
'''
Simulates a peripheral with ``address``, ``name`` and ``knownServiceUuids``
that has already been connected to the system.
:param address:
:param name:
:param manufacturer_data:
:param known_service_uuids:
'''
params: T_JSON_DICT = dict()
params['address'] = address
params['name'] = name
params['manufacturerData'] = [i.to_json() for i in manufacturer_data]
params['knownServiceUuids'] = [i for i in known_service_uuids]
cmd_dict: T_JSON_DICT = {
'method': 'BluetoothEmulation.simulatePreconnectedPeripheral',
'params': params,
}
json = yield cmd_dict
[docs]
def simulate_advertisement(
entry: ScanEntry
) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
'''
Simulates an advertisement packet described in ``entry`` being received by
the central.
:param entry:
'''
params: T_JSON_DICT = dict()
params['entry'] = entry.to_json()
cmd_dict: T_JSON_DICT = {
'method': 'BluetoothEmulation.simulateAdvertisement',
'params': params,
}
json = yield cmd_dict
[docs]
def simulate_gatt_operation_response(
address: str,
type_: GATTOperationType,
code: int
) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
'''
Simulates the response code from the peripheral with ``address`` for a
GATT operation of ``type``. The ``code`` value follows the HCI Error Codes from
Bluetooth Core Specification Vol 2 Part D 1.3 List Of Error Codes.
:param address:
:param type_:
:param code:
'''
params: T_JSON_DICT = dict()
params['address'] = address
params['type'] = type_.to_json()
params['code'] = code
cmd_dict: T_JSON_DICT = {
'method': 'BluetoothEmulation.simulateGATTOperationResponse',
'params': params,
}
json = yield cmd_dict
[docs]
def simulate_characteristic_operation_response(
characteristic_id: str,
type_: CharacteristicOperationType,
code: int,
data: typing.Optional[str] = None
) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
'''
Simulates the response from the characteristic with ``characteristicId`` for a
characteristic operation of ``type``. The ``code`` value follows the Error
Codes from Bluetooth Core Specification Vol 3 Part F 3.4.1.1 Error Response.
The ``data`` is expected to exist when simulating a successful read operation
response.
:param characteristic_id:
:param type_:
:param code:
:param data: *(Optional)*
'''
params: T_JSON_DICT = dict()
params['characteristicId'] = characteristic_id
params['type'] = type_.to_json()
params['code'] = code
if data is not None:
params['data'] = data
cmd_dict: T_JSON_DICT = {
'method': 'BluetoothEmulation.simulateCharacteristicOperationResponse',
'params': params,
}
json = yield cmd_dict
[docs]
def simulate_descriptor_operation_response(
descriptor_id: str,
type_: DescriptorOperationType,
code: int,
data: typing.Optional[str] = None
) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
'''
Simulates the response from the descriptor with ``descriptorId`` for a
descriptor operation of ``type``. The ``code`` value follows the Error
Codes from Bluetooth Core Specification Vol 3 Part F 3.4.1.1 Error Response.
The ``data`` is expected to exist when simulating a successful read operation
response.
:param descriptor_id:
:param type_:
:param code:
:param data: *(Optional)*
'''
params: T_JSON_DICT = dict()
params['descriptorId'] = descriptor_id
params['type'] = type_.to_json()
params['code'] = code
if data is not None:
params['data'] = data
cmd_dict: T_JSON_DICT = {
'method': 'BluetoothEmulation.simulateDescriptorOperationResponse',
'params': params,
}
json = yield cmd_dict
[docs]
def add_service(
address: str,
service_uuid: str
) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,str]:
'''
Adds a service with ``serviceUuid`` to the peripheral with ``address``.
:param address:
:param service_uuid:
:returns: An identifier that uniquely represents this service.
'''
params: T_JSON_DICT = dict()
params['address'] = address
params['serviceUuid'] = service_uuid
cmd_dict: T_JSON_DICT = {
'method': 'BluetoothEmulation.addService',
'params': params,
}
json = yield cmd_dict
return str(json['serviceId'])
[docs]
def remove_service(
service_id: str
) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
'''
Removes the service respresented by ``serviceId`` from the simulated central.
:param service_id:
'''
params: T_JSON_DICT = dict()
params['serviceId'] = service_id
cmd_dict: T_JSON_DICT = {
'method': 'BluetoothEmulation.removeService',
'params': params,
}
json = yield cmd_dict
[docs]
def add_characteristic(
service_id: str,
characteristic_uuid: str,
properties: CharacteristicProperties
) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,str]:
'''
Adds a characteristic with ``characteristicUuid`` and ``properties`` to the
service represented by ``serviceId``.
:param service_id:
:param characteristic_uuid:
:param properties:
:returns: An identifier that uniquely represents this characteristic.
'''
params: T_JSON_DICT = dict()
params['serviceId'] = service_id
params['characteristicUuid'] = characteristic_uuid
params['properties'] = properties.to_json()
cmd_dict: T_JSON_DICT = {
'method': 'BluetoothEmulation.addCharacteristic',
'params': params,
}
json = yield cmd_dict
return str(json['characteristicId'])
[docs]
def remove_characteristic(
characteristic_id: str
) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
'''
Removes the characteristic respresented by ``characteristicId`` from the
simulated central.
:param characteristic_id:
'''
params: T_JSON_DICT = dict()
params['characteristicId'] = characteristic_id
cmd_dict: T_JSON_DICT = {
'method': 'BluetoothEmulation.removeCharacteristic',
'params': params,
}
json = yield cmd_dict
[docs]
def add_descriptor(
characteristic_id: str,
descriptor_uuid: str
) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,str]:
'''
Adds a descriptor with ``descriptorUuid`` to the characteristic respresented
by ``characteristicId``.
:param characteristic_id:
:param descriptor_uuid:
:returns: An identifier that uniquely represents this descriptor.
'''
params: T_JSON_DICT = dict()
params['characteristicId'] = characteristic_id
params['descriptorUuid'] = descriptor_uuid
cmd_dict: T_JSON_DICT = {
'method': 'BluetoothEmulation.addDescriptor',
'params': params,
}
json = yield cmd_dict
return str(json['descriptorId'])
[docs]
def remove_descriptor(
descriptor_id: str
) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
'''
Removes the descriptor with ``descriptorId`` from the simulated central.
:param descriptor_id:
'''
params: T_JSON_DICT = dict()
params['descriptorId'] = descriptor_id
cmd_dict: T_JSON_DICT = {
'method': 'BluetoothEmulation.removeDescriptor',
'params': params,
}
json = yield cmd_dict
[docs]
def simulate_gatt_disconnection(
address: str
) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
'''
Simulates a GATT disconnection from the peripheral with ``address``.
:param address:
'''
params: T_JSON_DICT = dict()
params['address'] = address
cmd_dict: T_JSON_DICT = {
'method': 'BluetoothEmulation.simulateGATTDisconnection',
'params': params,
}
json = yield cmd_dict
[docs]
@event_class('BluetoothEmulation.gattOperationReceived')
@dataclass
class GattOperationReceived:
'''
Event for when a GATT operation of ``type`` to the peripheral with ``address``
happened.
'''
address: str
type_: GATTOperationType
@classmethod
def from_json(cls, json: T_JSON_DICT) -> GattOperationReceived:
return cls(
address=str(json['address']),
type_=GATTOperationType.from_json(json['type'])
)
[docs]
@event_class('BluetoothEmulation.characteristicOperationReceived')
@dataclass
class CharacteristicOperationReceived:
'''
Event for when a characteristic operation of ``type`` to the characteristic
respresented by ``characteristicId`` happened. ``data`` and ``writeType`` is
expected to exist when ``type`` is write.
'''
characteristic_id: str
type_: CharacteristicOperationType
data: typing.Optional[str]
write_type: typing.Optional[CharacteristicWriteType]
@classmethod
def from_json(cls, json: T_JSON_DICT) -> CharacteristicOperationReceived:
return cls(
characteristic_id=str(json['characteristicId']),
type_=CharacteristicOperationType.from_json(json['type']),
data=str(json['data']) if json.get('data', None) is not None else None,
write_type=CharacteristicWriteType.from_json(json['writeType']) if json.get('writeType', None) is not None else None
)
[docs]
@event_class('BluetoothEmulation.descriptorOperationReceived')
@dataclass
class DescriptorOperationReceived:
'''
Event for when a descriptor operation of ``type`` to the descriptor
respresented by ``descriptorId`` happened. ``data`` is expected to exist when
``type`` is write.
'''
descriptor_id: str
type_: DescriptorOperationType
data: typing.Optional[str]
@classmethod
def from_json(cls, json: T_JSON_DICT) -> DescriptorOperationReceived:
return cls(
descriptor_id=str(json['descriptorId']),
type_=DescriptorOperationType.from_json(json['type']),
data=str(json['data']) if json.get('data', None) is not None else None
)