bumble 0.0.222__py3-none-any.whl → 0.0.224__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bumble/_version.py +2 -2
- bumble/apps/controller_info.py +90 -114
- bumble/apps/controller_loopback.py +11 -9
- bumble/apps/gg_bridge.py +1 -1
- bumble/apps/hci_bridge.py +3 -1
- bumble/apps/l2cap_bridge.py +1 -1
- bumble/apps/rfcomm_bridge.py +1 -1
- bumble/apps/scan.py +10 -4
- bumble/apps/speaker/speaker.py +1 -1
- bumble/apps/usb_probe.py +15 -2
- bumble/att.py +97 -32
- bumble/avctp.py +1 -1
- bumble/avdtp.py +3 -3
- bumble/avrcp.py +366 -190
- bumble/bridge.py +10 -2
- bumble/controller.py +14 -1
- bumble/core.py +1 -1
- bumble/device.py +999 -577
- bumble/drivers/intel.py +45 -39
- bumble/drivers/rtk.py +102 -43
- bumble/gatt.py +2 -2
- bumble/gatt_client.py +5 -4
- bumble/gatt_server.py +100 -1
- bumble/hci.py +1367 -844
- bumble/hid.py +2 -2
- bumble/host.py +339 -157
- bumble/l2cap.py +13 -6
- bumble/pandora/l2cap.py +1 -1
- bumble/profiles/battery_service.py +25 -34
- bumble/profiles/heart_rate_service.py +130 -121
- bumble/rfcomm.py +1 -1
- bumble/sdp.py +2 -2
- bumble/smp.py +8 -3
- bumble/snoop.py +111 -1
- bumble/transport/android_netsim.py +1 -1
- bumble/vendor/android/hci.py +108 -86
- bumble/vendor/zephyr/hci.py +24 -18
- {bumble-0.0.222.dist-info → bumble-0.0.224.dist-info}/METADATA +4 -3
- {bumble-0.0.222.dist-info → bumble-0.0.224.dist-info}/RECORD +43 -43
- {bumble-0.0.222.dist-info → bumble-0.0.224.dist-info}/WHEEL +1 -1
- {bumble-0.0.222.dist-info → bumble-0.0.224.dist-info}/entry_points.txt +0 -0
- {bumble-0.0.222.dist-info → bumble-0.0.224.dist-info}/licenses/LICENSE +0 -0
- {bumble-0.0.222.dist-info → bumble-0.0.224.dist-info}/top_level.txt +0 -0
bumble/snoop.py
CHANGED
|
@@ -110,6 +110,53 @@ class BtSnooper(Snooper):
|
|
|
110
110
|
)
|
|
111
111
|
|
|
112
112
|
|
|
113
|
+
# -----------------------------------------------------------------------------
|
|
114
|
+
class PcapSnooper(Snooper):
|
|
115
|
+
"""
|
|
116
|
+
Snooper that saves or streames HCI packets using the PCAP format.
|
|
117
|
+
"""
|
|
118
|
+
|
|
119
|
+
PCAP_MAGIC = 0xA1B2C3D4
|
|
120
|
+
DLT_BLUETOOTH_HCI_H4_WITH_PHDR = 201
|
|
121
|
+
|
|
122
|
+
def __init__(self, output: BinaryIO):
|
|
123
|
+
self.output = output
|
|
124
|
+
|
|
125
|
+
# Write the header
|
|
126
|
+
self.output.write(
|
|
127
|
+
struct.pack(
|
|
128
|
+
"<IHHIIII",
|
|
129
|
+
self.PCAP_MAGIC,
|
|
130
|
+
2, # Major PCAP Version
|
|
131
|
+
4, # Minor PCAP Version
|
|
132
|
+
0, # Reserved 1
|
|
133
|
+
0, # Reserved 2
|
|
134
|
+
65535, # SnapLen
|
|
135
|
+
# FCS and f are set to 0 implicitly by the next line
|
|
136
|
+
self.DLT_BLUETOOTH_HCI_H4_WITH_PHDR, # The DLT in this PCAP
|
|
137
|
+
)
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
def snoop(self, hci_packet: bytes, direction: Snooper.Direction):
|
|
141
|
+
now = datetime.datetime.now(datetime.timezone.utc)
|
|
142
|
+
sec = int(now.timestamp())
|
|
143
|
+
usec = now.microsecond
|
|
144
|
+
|
|
145
|
+
# Emit the record
|
|
146
|
+
self.output.write(
|
|
147
|
+
struct.pack(
|
|
148
|
+
"<IIII",
|
|
149
|
+
sec, # Timestamp (Seconds)
|
|
150
|
+
usec, # Timestamp (Microseconds)
|
|
151
|
+
len(hci_packet) + 4,
|
|
152
|
+
len(hci_packet) + 4, # +4 because of the addtional direction info...
|
|
153
|
+
)
|
|
154
|
+
+ struct.pack(">I", int(direction)) # ...thats being added here
|
|
155
|
+
+ hci_packet
|
|
156
|
+
)
|
|
157
|
+
self.output.flush() # flush after every packet for live logging
|
|
158
|
+
|
|
159
|
+
|
|
113
160
|
# -----------------------------------------------------------------------------
|
|
114
161
|
_SNOOPER_INSTANCE_COUNT = 0
|
|
115
162
|
|
|
@@ -140,9 +187,38 @@ def create_snooper(spec: str) -> Generator[Snooper, None, None]:
|
|
|
140
187
|
pid: the current process ID.
|
|
141
188
|
instance: the instance ID in the current process.
|
|
142
189
|
|
|
190
|
+
pcapsnoop
|
|
191
|
+
The syntax for the type-specific arguments for this type is:
|
|
192
|
+
<io-type>:<io-type-specific-arguments>
|
|
193
|
+
|
|
194
|
+
Supported I/O types are:
|
|
195
|
+
|
|
196
|
+
file
|
|
197
|
+
The type-specific arguments for this I/O type is a string that is converted
|
|
198
|
+
to a file path using the python `str.format()` string formatting. The log
|
|
199
|
+
records will be written to that file if it can be opened/created.
|
|
200
|
+
The keyword args that may be referenced by the string pattern are:
|
|
201
|
+
now: the value of `datetime.now()`
|
|
202
|
+
utcnow: the value of `datetime.now(tz=datetime.timezone.utc)`
|
|
203
|
+
pid: the current process ID.
|
|
204
|
+
instance: the instance ID in the current process.
|
|
205
|
+
|
|
206
|
+
pipe
|
|
207
|
+
The type-specific arguments for this I/O type is a string that is converted
|
|
208
|
+
to a path using the python `str.format()` string formatting. The log
|
|
209
|
+
records will be written to the named pipe referenced by this path
|
|
210
|
+
if it can be opened. The keyword args that may be referenced by the
|
|
211
|
+
string pattern are:
|
|
212
|
+
now: the value of `datetime.now()`
|
|
213
|
+
utcnow: the value of `datetime.now(tz=datetime.timezone.utc)`
|
|
214
|
+
pid: the current process ID.
|
|
215
|
+
instance: the instance ID in the current process.
|
|
216
|
+
|
|
143
217
|
Examples:
|
|
144
218
|
btsnoop:file:my_btsnoop.log
|
|
145
219
|
btsnoop:file:/tmp/bumble_{now:%Y-%m-%d-%H:%M:%S}_{pid}.log
|
|
220
|
+
pcapsnoop:pipe:/tmp/bumble-extcap
|
|
221
|
+
|
|
146
222
|
|
|
147
223
|
"""
|
|
148
224
|
if ':' not in spec:
|
|
@@ -150,6 +226,8 @@ def create_snooper(spec: str) -> Generator[Snooper, None, None]:
|
|
|
150
226
|
|
|
151
227
|
snooper_type, snooper_args = spec.split(':', maxsplit=1)
|
|
152
228
|
|
|
229
|
+
global _SNOOPER_INSTANCE_COUNT
|
|
230
|
+
|
|
153
231
|
if snooper_type == 'btsnoop':
|
|
154
232
|
if ':' not in snooper_args:
|
|
155
233
|
raise core.InvalidArgumentError('I/O type for btsnoop snooper type missing')
|
|
@@ -157,7 +235,6 @@ def create_snooper(spec: str) -> Generator[Snooper, None, None]:
|
|
|
157
235
|
io_type, io_name = snooper_args.split(':', maxsplit=1)
|
|
158
236
|
if io_type == 'file':
|
|
159
237
|
# Process the file name string pattern.
|
|
160
|
-
global _SNOOPER_INSTANCE_COUNT
|
|
161
238
|
file_path = io_name.format(
|
|
162
239
|
now=datetime.datetime.now(),
|
|
163
240
|
utcnow=datetime.datetime.now(tz=datetime.timezone.utc),
|
|
@@ -173,6 +250,39 @@ def create_snooper(spec: str) -> Generator[Snooper, None, None]:
|
|
|
173
250
|
_SNOOPER_INSTANCE_COUNT -= 1
|
|
174
251
|
return
|
|
175
252
|
|
|
253
|
+
elif snooper_type == 'pcapsnoop':
|
|
254
|
+
if ':' not in snooper_args:
|
|
255
|
+
raise core.InvalidArgumentError(
|
|
256
|
+
'I/O type for pcapsnoop snooper type missing'
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
io_type, io_name = snooper_args.split(':', maxsplit=1)
|
|
260
|
+
if io_type in {'pipe', 'file'}:
|
|
261
|
+
# Process the file name string pattern.
|
|
262
|
+
file_path = io_name.format(
|
|
263
|
+
now=datetime.datetime.now(),
|
|
264
|
+
utcnow=datetime.datetime.now(tz=datetime.timezone.utc),
|
|
265
|
+
pid=os.getpid(),
|
|
266
|
+
instance=_SNOOPER_INSTANCE_COUNT,
|
|
267
|
+
)
|
|
268
|
+
|
|
269
|
+
# Open a file or pipe
|
|
270
|
+
logger.debug(f'PCAP file: {file_path}')
|
|
271
|
+
|
|
272
|
+
# Pipes we have to open with unbuffered binary I/O
|
|
273
|
+
# so we pass ``buffering`` for pipes but not for files
|
|
274
|
+
pcap_file: BinaryIO
|
|
275
|
+
if io_type == 'pipe':
|
|
276
|
+
pcap_file = open(file_path, 'wb', buffering=0)
|
|
277
|
+
else:
|
|
278
|
+
pcap_file = open(file_path, 'wb')
|
|
279
|
+
|
|
280
|
+
with pcap_file:
|
|
281
|
+
_SNOOPER_INSTANCE_COUNT += 1
|
|
282
|
+
yield PcapSnooper(pcap_file)
|
|
283
|
+
_SNOOPER_INSTANCE_COUNT -= 1
|
|
284
|
+
return
|
|
285
|
+
|
|
176
286
|
raise core.InvalidArgumentError(f'I/O type {io_type} not supported')
|
|
177
287
|
|
|
178
288
|
raise core.InvalidArgumentError(f'snooper type {snooper_type} not found')
|
|
@@ -194,7 +194,7 @@ async def open_android_netsim_controller_transport(
|
|
|
194
194
|
|
|
195
195
|
# We only accept BLUETOOTH
|
|
196
196
|
if request.initial_info.chip.kind != ChipKind.BLUETOOTH:
|
|
197
|
-
logger.
|
|
197
|
+
logger.debug('Request for unsupported chip type')
|
|
198
198
|
error = PacketResponse(error='Unsupported chip type')
|
|
199
199
|
await self.context.write(error)
|
|
200
200
|
# return
|
bumble/vendor/android/hci.py
CHANGED
|
@@ -43,44 +43,53 @@ hci.HCI_Command.register_commands(globals())
|
|
|
43
43
|
|
|
44
44
|
|
|
45
45
|
# -----------------------------------------------------------------------------
|
|
46
|
-
@hci.HCI_Command.command
|
|
47
46
|
@dataclasses.dataclass
|
|
48
|
-
class
|
|
47
|
+
class HCI_LE_Get_Vendor_Capabilities_ReturnParameters(hci.HCI_StatusReturnParameters):
|
|
48
|
+
max_advt_instances: int = field(metadata=hci.metadata(1), default=0)
|
|
49
|
+
offloaded_resolution_of_private_address: int = field(
|
|
50
|
+
metadata=hci.metadata(1), default=0
|
|
51
|
+
)
|
|
52
|
+
total_scan_results_storage: int = field(metadata=hci.metadata(2), default=0)
|
|
53
|
+
max_irk_list_sz: int = field(metadata=hci.metadata(1), default=0)
|
|
54
|
+
filtering_support: int = field(metadata=hci.metadata(1), default=0)
|
|
55
|
+
max_filter: int = field(metadata=hci.metadata(1), default=0)
|
|
56
|
+
activity_energy_info_support: int = field(metadata=hci.metadata(1), default=0)
|
|
57
|
+
version_supported: int = field(metadata=hci.metadata(2), default=0)
|
|
58
|
+
total_num_of_advt_tracked: int = field(metadata=hci.metadata(2), default=0)
|
|
59
|
+
extended_scan_support: int = field(metadata=hci.metadata(1), default=0)
|
|
60
|
+
debug_logging_supported: int = field(metadata=hci.metadata(1), default=0)
|
|
61
|
+
le_address_generation_offloading_support: int = field(
|
|
62
|
+
metadata=hci.metadata(1), default=0
|
|
63
|
+
)
|
|
64
|
+
a2dp_source_offload_capability_mask: int = field(
|
|
65
|
+
metadata=hci.metadata(4), default=0
|
|
66
|
+
)
|
|
67
|
+
bluetooth_quality_report_support: int = field(metadata=hci.metadata(1), default=0)
|
|
68
|
+
dynamic_audio_buffer_support: int = field(metadata=hci.metadata(4), default=0)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
@hci.HCI_SyncCommand.sync_command(HCI_LE_Get_Vendor_Capabilities_ReturnParameters)
|
|
72
|
+
@dataclasses.dataclass
|
|
73
|
+
class HCI_LE_Get_Vendor_Capabilities_Command(
|
|
74
|
+
hci.HCI_SyncCommand[HCI_LE_Get_Vendor_Capabilities_ReturnParameters]
|
|
75
|
+
):
|
|
49
76
|
# pylint: disable=line-too-long
|
|
50
77
|
'''
|
|
51
78
|
See https://source.android.com/docs/core/connect/bluetooth/hci_requirements#vendor-specific-capabilities
|
|
52
79
|
'''
|
|
53
80
|
|
|
54
|
-
return_parameters_fields = [
|
|
55
|
-
('status', hci.STATUS_SPEC),
|
|
56
|
-
('max_advt_instances', 1),
|
|
57
|
-
('offloaded_resolution_of_private_address', 1),
|
|
58
|
-
('total_scan_results_storage', 2),
|
|
59
|
-
('max_irk_list_sz', 1),
|
|
60
|
-
('filtering_support', 1),
|
|
61
|
-
('max_filter', 1),
|
|
62
|
-
('activity_energy_info_support', 1),
|
|
63
|
-
('version_supported', 2),
|
|
64
|
-
('total_num_of_advt_tracked', 2),
|
|
65
|
-
('extended_scan_support', 1),
|
|
66
|
-
('debug_logging_supported', 1),
|
|
67
|
-
('le_address_generation_offloading_support', 1),
|
|
68
|
-
('a2dp_source_offload_capability_mask', 4),
|
|
69
|
-
('bluetooth_quality_report_support', 1),
|
|
70
|
-
('dynamic_audio_buffer_support', 4),
|
|
71
|
-
]
|
|
72
|
-
|
|
73
81
|
@classmethod
|
|
74
82
|
def parse_return_parameters(cls, parameters):
|
|
75
83
|
# There are many versions of this data structure, so we need to parse until
|
|
76
|
-
# there are no more bytes to parse, and leave un-
|
|
77
|
-
#
|
|
78
|
-
|
|
79
|
-
|
|
84
|
+
# there are no more bytes to parse, and leave un-signaled parameters set to
|
|
85
|
+
# 0
|
|
86
|
+
return_parameters = HCI_LE_Get_Vendor_Capabilities_ReturnParameters(
|
|
87
|
+
hci.HCI_ErrorCode.SUCCESS
|
|
88
|
+
)
|
|
80
89
|
|
|
81
90
|
try:
|
|
82
91
|
offset = 0
|
|
83
|
-
for field in cls.
|
|
92
|
+
for field in cls.return_parameters_class.fields:
|
|
84
93
|
field_name, field_type = field
|
|
85
94
|
field_value, field_size = hci.HCI_Object.parse_field(
|
|
86
95
|
parameters, offset, field_type
|
|
@@ -94,9 +103,30 @@ class HCI_LE_Get_Vendor_Capabilities_Command(hci.HCI_Command):
|
|
|
94
103
|
|
|
95
104
|
|
|
96
105
|
# -----------------------------------------------------------------------------
|
|
97
|
-
|
|
106
|
+
# APCF Subcommands
|
|
107
|
+
class LeApcfOpcode(hci.SpecableEnum):
|
|
108
|
+
ENABLE = 0x00
|
|
109
|
+
SET_FILTERING_PARAMETERS = 0x01
|
|
110
|
+
BROADCASTER_ADDRESS = 0x02
|
|
111
|
+
SERVICE_UUID = 0x03
|
|
112
|
+
SERVICE_SOLICITATION_UUID = 0x04
|
|
113
|
+
LOCAL_NAME = 0x05
|
|
114
|
+
MANUFACTURER_DATA = 0x06
|
|
115
|
+
SERVICE_DATA = 0x07
|
|
116
|
+
TRANSPORT_DISCOVERY_SERVICE = 0x08
|
|
117
|
+
AD_TYPE_FILTER = 0x09
|
|
118
|
+
READ_EXTENDED_FEATURES = 0xFF
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
@dataclasses.dataclass
|
|
122
|
+
class HCI_LE_APCF_ReturnParameters(hci.HCI_StatusReturnParameters):
|
|
123
|
+
opcode: int = field(metadata=LeApcfOpcode.type_metadata(1))
|
|
124
|
+
payload: bytes = field(metadata=hci.metadata('*'))
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
@hci.HCI_SyncCommand.sync_command(HCI_LE_APCF_ReturnParameters)
|
|
98
128
|
@dataclasses.dataclass
|
|
99
|
-
class HCI_LE_APCF_Command(hci.
|
|
129
|
+
class HCI_LE_APCF_Command(hci.HCI_SyncCommand[HCI_LE_APCF_ReturnParameters]):
|
|
100
130
|
# pylint: disable=line-too-long
|
|
101
131
|
'''
|
|
102
132
|
See https://source.android.com/docs/core/connect/bluetooth/hci_requirements#le_apcf_command
|
|
@@ -105,52 +135,52 @@ class HCI_LE_APCF_Command(hci.HCI_Command):
|
|
|
105
135
|
implementation. A future enhancement may define subcommand-specific data structures.
|
|
106
136
|
'''
|
|
107
137
|
|
|
108
|
-
|
|
109
|
-
class Opcode(hci.SpecableEnum):
|
|
110
|
-
ENABLE = 0x00
|
|
111
|
-
SET_FILTERING_PARAMETERS = 0x01
|
|
112
|
-
BROADCASTER_ADDRESS = 0x02
|
|
113
|
-
SERVICE_UUID = 0x03
|
|
114
|
-
SERVICE_SOLICITATION_UUID = 0x04
|
|
115
|
-
LOCAL_NAME = 0x05
|
|
116
|
-
MANUFACTURER_DATA = 0x06
|
|
117
|
-
SERVICE_DATA = 0x07
|
|
118
|
-
TRANSPORT_DISCOVERY_SERVICE = 0x08
|
|
119
|
-
AD_TYPE_FILTER = 0x09
|
|
120
|
-
READ_EXTENDED_FEATURES = 0xFF
|
|
121
|
-
|
|
122
|
-
opcode: int = dataclasses.field(metadata=Opcode.type_metadata(1))
|
|
138
|
+
opcode: int = dataclasses.field(metadata=LeApcfOpcode.type_metadata(1))
|
|
123
139
|
payload: bytes = dataclasses.field(metadata=hci.metadata("*"))
|
|
124
140
|
|
|
125
|
-
return_parameters_fields = [
|
|
126
|
-
('status', hci.STATUS_SPEC),
|
|
127
|
-
('opcode', Opcode.type_spec(1)),
|
|
128
|
-
('payload', '*'),
|
|
129
|
-
]
|
|
130
|
-
|
|
131
141
|
|
|
132
142
|
# -----------------------------------------------------------------------------
|
|
133
|
-
@hci.HCI_Command.command
|
|
134
143
|
@dataclasses.dataclass
|
|
135
|
-
class
|
|
144
|
+
class HCI_Get_Controller_Activity_Energy_Info_ReturnParameters(
|
|
145
|
+
hci.HCI_StatusReturnParameters
|
|
146
|
+
):
|
|
147
|
+
total_tx_time_ms: int = field(metadata=hci.metadata(4))
|
|
148
|
+
total_rx_time_ms: int = field(metadata=hci.metadata(4))
|
|
149
|
+
total_idle_time_ms: int = field(metadata=hci.metadata(4))
|
|
150
|
+
total_energy_used: int = field(metadata=hci.metadata(4))
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
@hci.HCI_SyncCommand.sync_command(
|
|
154
|
+
HCI_Get_Controller_Activity_Energy_Info_ReturnParameters
|
|
155
|
+
)
|
|
156
|
+
@dataclasses.dataclass
|
|
157
|
+
class HCI_Get_Controller_Activity_Energy_Info_Command(
|
|
158
|
+
hci.HCI_SyncCommand[HCI_Get_Controller_Activity_Energy_Info_ReturnParameters]
|
|
159
|
+
):
|
|
136
160
|
# pylint: disable=line-too-long
|
|
137
161
|
'''
|
|
138
162
|
See https://source.android.com/docs/core/connect/bluetooth/hci_requirements#le_get_controller_activity_energy_info
|
|
139
163
|
'''
|
|
140
164
|
|
|
141
|
-
return_parameters_fields = [
|
|
142
|
-
('status', hci.STATUS_SPEC),
|
|
143
|
-
('total_tx_time_ms', 4),
|
|
144
|
-
('total_rx_time_ms', 4),
|
|
145
|
-
('total_idle_time_ms', 4),
|
|
146
|
-
('total_energy_used', 4),
|
|
147
|
-
]
|
|
148
|
-
|
|
149
165
|
|
|
150
166
|
# -----------------------------------------------------------------------------
|
|
151
|
-
|
|
167
|
+
# A2DP Hardware Offload Subcommands
|
|
168
|
+
class A2dpHardwareOffloadOpcode(hci.SpecableEnum):
|
|
169
|
+
START_A2DP_OFFLOAD = 0x01
|
|
170
|
+
STOP_A2DP_OFFLOAD = 0x02
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
@dataclasses.dataclass
|
|
174
|
+
class HCI_A2DP_Hardware_Offload_ReturnParameters(hci.HCI_StatusReturnParameters):
|
|
175
|
+
opcode: int = dataclasses.field(metadata=A2dpHardwareOffloadOpcode.type_metadata(1))
|
|
176
|
+
payload: bytes = dataclasses.field(metadata=hci.metadata("*"))
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
@hci.HCI_SyncCommand.sync_command(HCI_A2DP_Hardware_Offload_ReturnParameters)
|
|
152
180
|
@dataclasses.dataclass
|
|
153
|
-
class HCI_A2DP_Hardware_Offload_Command(
|
|
181
|
+
class HCI_A2DP_Hardware_Offload_Command(
|
|
182
|
+
hci.HCI_SyncCommand[HCI_A2DP_Hardware_Offload_ReturnParameters]
|
|
183
|
+
):
|
|
154
184
|
# pylint: disable=line-too-long
|
|
155
185
|
'''
|
|
156
186
|
See https://source.android.com/docs/core/connect/bluetooth/hci_requirements#a2dp-hardware-offload-support
|
|
@@ -159,25 +189,27 @@ class HCI_A2DP_Hardware_Offload_Command(hci.HCI_Command):
|
|
|
159
189
|
implementation. A future enhancement may define subcommand-specific data structures.
|
|
160
190
|
'''
|
|
161
191
|
|
|
162
|
-
|
|
163
|
-
class Opcode(hci.SpecableEnum):
|
|
164
|
-
START_A2DP_OFFLOAD = 0x01
|
|
165
|
-
STOP_A2DP_OFFLOAD = 0x02
|
|
166
|
-
|
|
167
|
-
opcode: int = dataclasses.field(metadata=Opcode.type_metadata(1))
|
|
192
|
+
opcode: int = dataclasses.field(metadata=A2dpHardwareOffloadOpcode.type_metadata(1))
|
|
168
193
|
payload: bytes = dataclasses.field(metadata=hci.metadata("*"))
|
|
169
194
|
|
|
170
|
-
return_parameters_fields = [
|
|
171
|
-
('status', hci.STATUS_SPEC),
|
|
172
|
-
('opcode', Opcode.type_spec(1)),
|
|
173
|
-
('payload', '*'),
|
|
174
|
-
]
|
|
175
|
-
|
|
176
195
|
|
|
177
196
|
# -----------------------------------------------------------------------------
|
|
178
|
-
|
|
197
|
+
# Dynamic Audio Buffer Subcommands
|
|
198
|
+
class DynamicAudioBufferOpcode(hci.SpecableEnum):
|
|
199
|
+
GET_AUDIO_BUFFER_TIME_CAPABILITY = 0x01
|
|
200
|
+
|
|
201
|
+
|
|
179
202
|
@dataclasses.dataclass
|
|
180
|
-
class
|
|
203
|
+
class HCI_Dynamic_Audio_Buffer_ReturnParameters(hci.HCI_StatusReturnParameters):
|
|
204
|
+
opcode: int = dataclasses.field(metadata=DynamicAudioBufferOpcode.type_metadata(1))
|
|
205
|
+
payload: bytes = dataclasses.field(metadata=hci.metadata("*"))
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
@hci.HCI_SyncCommand.sync_command(HCI_Dynamic_Audio_Buffer_ReturnParameters)
|
|
209
|
+
@dataclasses.dataclass
|
|
210
|
+
class HCI_Dynamic_Audio_Buffer_Command(
|
|
211
|
+
hci.HCI_SyncCommand[HCI_Dynamic_Audio_Buffer_ReturnParameters]
|
|
212
|
+
):
|
|
181
213
|
# pylint: disable=line-too-long
|
|
182
214
|
'''
|
|
183
215
|
See https://source.android.com/docs/core/connect/bluetooth/hci_requirements#dynamic-audio-buffer-command
|
|
@@ -186,19 +218,9 @@ class HCI_Dynamic_Audio_Buffer_Command(hci.HCI_Command):
|
|
|
186
218
|
implementation. A future enhancement may define subcommand-specific data structures.
|
|
187
219
|
'''
|
|
188
220
|
|
|
189
|
-
|
|
190
|
-
class Opcode(hci.SpecableEnum):
|
|
191
|
-
GET_AUDIO_BUFFER_TIME_CAPABILITY = 0x01
|
|
192
|
-
|
|
193
|
-
opcode: int = dataclasses.field(metadata=Opcode.type_metadata(1))
|
|
221
|
+
opcode: int = dataclasses.field(metadata=DynamicAudioBufferOpcode.type_metadata(1))
|
|
194
222
|
payload: bytes = dataclasses.field(metadata=hci.metadata("*"))
|
|
195
223
|
|
|
196
|
-
return_parameters_fields = [
|
|
197
|
-
('status', hci.STATUS_SPEC),
|
|
198
|
-
('opcode', Opcode.type_spec(1)),
|
|
199
|
-
('payload', '*'),
|
|
200
|
-
]
|
|
201
|
-
|
|
202
224
|
|
|
203
225
|
# -----------------------------------------------------------------------------
|
|
204
226
|
class HCI_Android_Vendor_Event(hci.HCI_Extended_Event):
|
bumble/vendor/zephyr/hci.py
CHANGED
|
@@ -46,9 +46,19 @@ class TX_Power_Level_Command:
|
|
|
46
46
|
|
|
47
47
|
|
|
48
48
|
# -----------------------------------------------------------------------------
|
|
49
|
-
@hci.HCI_Command.command
|
|
50
49
|
@dataclasses.dataclass
|
|
51
|
-
class
|
|
50
|
+
class HCI_Write_Tx_Power_Level_ReturnParameters(hci.HCI_StatusReturnParameters):
|
|
51
|
+
handle_type: int = hci.field(metadata=hci.metadata(1))
|
|
52
|
+
connection_handle: int = hci.field(metadata=hci.metadata(2))
|
|
53
|
+
selected_tx_power_level: int = hci.field(metadata=hci.metadata(-1))
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@hci.HCI_SyncCommand.sync_command(HCI_Write_Tx_Power_Level_ReturnParameters)
|
|
57
|
+
@dataclasses.dataclass
|
|
58
|
+
class HCI_Write_Tx_Power_Level_Command(
|
|
59
|
+
hci.HCI_SyncCommand[HCI_Write_Tx_Power_Level_ReturnParameters],
|
|
60
|
+
TX_Power_Level_Command,
|
|
61
|
+
):
|
|
52
62
|
'''
|
|
53
63
|
Write TX power level. See BT_HCI_OP_VS_WRITE_TX_POWER_LEVEL in
|
|
54
64
|
https://github.com/zephyrproject-rtos/zephyr/blob/main/include/zephyr/bluetooth/hci_vs.h
|
|
@@ -61,18 +71,21 @@ class HCI_Write_Tx_Power_Level_Command(hci.HCI_Command, TX_Power_Level_Command):
|
|
|
61
71
|
connection_handle: int = dataclasses.field(metadata=hci.metadata(2))
|
|
62
72
|
tx_power_level: int = dataclasses.field(metadata=hci.metadata(-1))
|
|
63
73
|
|
|
64
|
-
return_parameters_fields = [
|
|
65
|
-
('status', hci.STATUS_SPEC),
|
|
66
|
-
('handle_type', 1),
|
|
67
|
-
('connection_handle', 2),
|
|
68
|
-
('selected_tx_power_level', -1),
|
|
69
|
-
]
|
|
70
|
-
|
|
71
74
|
|
|
72
75
|
# -----------------------------------------------------------------------------
|
|
73
|
-
@hci.HCI_Command.command
|
|
74
76
|
@dataclasses.dataclass
|
|
75
|
-
class
|
|
77
|
+
class HCI_Read_Tx_Power_Level_ReturnParameters(hci.HCI_StatusReturnParameters):
|
|
78
|
+
handle_type: int = hci.field(metadata=hci.metadata(1))
|
|
79
|
+
connection_handle: int = hci.field(metadata=hci.metadata(2))
|
|
80
|
+
tx_power_level: int = hci.field(metadata=hci.metadata(-1))
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
@hci.HCI_SyncCommand.sync_command(HCI_Read_Tx_Power_Level_ReturnParameters)
|
|
84
|
+
@dataclasses.dataclass
|
|
85
|
+
class HCI_Read_Tx_Power_Level_Command(
|
|
86
|
+
hci.HCI_SyncCommand[HCI_Read_Tx_Power_Level_ReturnParameters],
|
|
87
|
+
TX_Power_Level_Command,
|
|
88
|
+
):
|
|
76
89
|
'''
|
|
77
90
|
Read TX power level. See BT_HCI_OP_VS_READ_TX_POWER_LEVEL in
|
|
78
91
|
https://github.com/zephyrproject-rtos/zephyr/blob/main/include/zephyr/bluetooth/hci_vs.h
|
|
@@ -83,10 +96,3 @@ class HCI_Read_Tx_Power_Level_Command(hci.HCI_Command, TX_Power_Level_Command):
|
|
|
83
96
|
|
|
84
97
|
handle_type: int = dataclasses.field(metadata=hci.metadata(1))
|
|
85
98
|
connection_handle: int = dataclasses.field(metadata=hci.metadata(2))
|
|
86
|
-
|
|
87
|
-
return_parameters_fields = [
|
|
88
|
-
('status', hci.STATUS_SPEC),
|
|
89
|
-
('handle_type', 1),
|
|
90
|
-
('connection_handle', 2),
|
|
91
|
-
('tx_power_level', -1),
|
|
92
|
-
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bumble
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.224
|
|
4
4
|
Summary: Bluetooth Stack for Apps, Emulation, Test and Experimentation
|
|
5
5
|
Author-email: Google <bumble-dev@google.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -11,12 +11,13 @@ License-File: LICENSE
|
|
|
11
11
|
Requires-Dist: aiohttp~=3.8; platform_system != "Emscripten"
|
|
12
12
|
Requires-Dist: appdirs>=1.4; platform_system != "Emscripten"
|
|
13
13
|
Requires-Dist: click>=8.1.3; platform_system != "Emscripten"
|
|
14
|
-
Requires-Dist: cryptography>=44.0.3; platform_system != "Emscripten"
|
|
14
|
+
Requires-Dist: cryptography>=44.0.3; platform_system != "Emscripten" and platform_system != "Android"
|
|
15
15
|
Requires-Dist: cryptography>=44.0.3; platform_system == "Emscripten"
|
|
16
|
+
Requires-Dist: cryptography>=42.0.8; platform_system == "Android"
|
|
16
17
|
Requires-Dist: grpcio>=1.62.1; platform_system != "Emscripten"
|
|
17
18
|
Requires-Dist: humanize>=4.6.0; platform_system != "Emscripten"
|
|
18
19
|
Requires-Dist: libusb1>=2.0.1; platform_system != "Emscripten"
|
|
19
|
-
Requires-Dist: libusb-package==1.0.26.1; platform_system != "Emscripten"
|
|
20
|
+
Requires-Dist: libusb-package==1.0.26.1; platform_system != "Emscripten" and platform_system != "Android"
|
|
20
21
|
Requires-Dist: platformdirs>=3.10.0; platform_system != "Emscripten"
|
|
21
22
|
Requires-Dist: prompt_toolkit>=3.0.16; platform_system != "Emscripten"
|
|
22
23
|
Requires-Dist: prettytable>=3.6.0; platform_system != "Emscripten"
|