bumble 0.0.211__py3-none-any.whl → 0.0.213__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.
Files changed (95) hide show
  1. bumble/_version.py +2 -2
  2. bumble/a2dp.py +6 -0
  3. bumble/apps/README.md +0 -3
  4. bumble/apps/auracast.py +11 -9
  5. bumble/apps/bench.py +482 -31
  6. bumble/apps/console.py +5 -5
  7. bumble/apps/controller_info.py +47 -10
  8. bumble/apps/controller_loopback.py +7 -3
  9. bumble/apps/controllers.py +2 -2
  10. bumble/apps/device_info.py +2 -2
  11. bumble/apps/gatt_dump.py +2 -2
  12. bumble/apps/gg_bridge.py +2 -2
  13. bumble/apps/hci_bridge.py +2 -2
  14. bumble/apps/l2cap_bridge.py +2 -2
  15. bumble/apps/lea_unicast/app.py +6 -1
  16. bumble/apps/pair.py +204 -43
  17. bumble/apps/pandora_server.py +2 -2
  18. bumble/apps/rfcomm_bridge.py +1 -1
  19. bumble/apps/scan.py +2 -2
  20. bumble/apps/show.py +4 -2
  21. bumble/apps/speaker/speaker.html +1 -0
  22. bumble/apps/speaker/speaker.js +113 -62
  23. bumble/apps/speaker/speaker.py +126 -18
  24. bumble/at.py +4 -4
  25. bumble/att.py +15 -18
  26. bumble/avc.py +7 -7
  27. bumble/avctp.py +5 -5
  28. bumble/avdtp.py +138 -88
  29. bumble/avrcp.py +52 -58
  30. bumble/colors.py +2 -2
  31. bumble/controller.py +84 -23
  32. bumble/core.py +13 -7
  33. bumble/{crypto.py → crypto/__init__.py} +11 -95
  34. bumble/crypto/builtin.py +652 -0
  35. bumble/crypto/cryptography.py +84 -0
  36. bumble/device.py +688 -345
  37. bumble/drivers/__init__.py +2 -2
  38. bumble/drivers/common.py +0 -2
  39. bumble/drivers/intel.py +40 -40
  40. bumble/drivers/rtk.py +28 -35
  41. bumble/gatt.py +7 -9
  42. bumble/gatt_adapters.py +4 -5
  43. bumble/gatt_client.py +31 -34
  44. bumble/gatt_server.py +15 -17
  45. bumble/hci.py +2635 -2878
  46. bumble/helpers.py +4 -5
  47. bumble/hfp.py +76 -57
  48. bumble/hid.py +24 -12
  49. bumble/host.py +117 -34
  50. bumble/keys.py +68 -52
  51. bumble/l2cap.py +329 -403
  52. bumble/link.py +6 -270
  53. bumble/pairing.py +23 -20
  54. bumble/pandora/__init__.py +1 -1
  55. bumble/pandora/config.py +2 -2
  56. bumble/pandora/device.py +6 -6
  57. bumble/pandora/host.py +38 -39
  58. bumble/pandora/l2cap.py +4 -4
  59. bumble/pandora/security.py +73 -57
  60. bumble/pandora/utils.py +3 -3
  61. bumble/profiles/aics.py +3 -5
  62. bumble/profiles/ancs.py +3 -1
  63. bumble/profiles/ascs.py +143 -136
  64. bumble/profiles/asha.py +13 -8
  65. bumble/profiles/bap.py +3 -4
  66. bumble/profiles/csip.py +3 -5
  67. bumble/profiles/device_information_service.py +2 -2
  68. bumble/profiles/gap.py +2 -2
  69. bumble/profiles/gatt_service.py +1 -3
  70. bumble/profiles/hap.py +42 -58
  71. bumble/profiles/le_audio.py +4 -4
  72. bumble/profiles/mcp.py +16 -13
  73. bumble/profiles/vcs.py +8 -10
  74. bumble/profiles/vocs.py +6 -9
  75. bumble/rfcomm.py +27 -18
  76. bumble/rtp.py +1 -2
  77. bumble/sdp.py +2 -2
  78. bumble/smp.py +71 -69
  79. bumble/tools/rtk_util.py +2 -2
  80. bumble/transport/__init__.py +2 -16
  81. bumble/transport/android_netsim.py +5 -5
  82. bumble/transport/common.py +4 -4
  83. bumble/transport/pyusb.py +2 -2
  84. bumble/utils.py +2 -5
  85. bumble/vendor/android/hci.py +118 -200
  86. bumble/vendor/zephyr/hci.py +32 -27
  87. {bumble-0.0.211.dist-info → bumble-0.0.213.dist-info}/METADATA +5 -5
  88. {bumble-0.0.211.dist-info → bumble-0.0.213.dist-info}/RECORD +92 -93
  89. {bumble-0.0.211.dist-info → bumble-0.0.213.dist-info}/WHEEL +1 -1
  90. {bumble-0.0.211.dist-info → bumble-0.0.213.dist-info}/entry_points.txt +0 -1
  91. bumble/apps/link_relay/__init__.py +0 -0
  92. bumble/apps/link_relay/link_relay.py +0 -289
  93. bumble/apps/link_relay/logging.yml +0 -21
  94. {bumble-0.0.211.dist-info → bumble-0.0.213.dist-info}/licenses/LICENSE +0 -0
  95. {bumble-0.0.211.dist-info → bumble-0.0.213.dist-info}/top_level.txt +0 -0
@@ -15,21 +15,12 @@
15
15
  # -----------------------------------------------------------------------------
16
16
  # Imports
17
17
  # -----------------------------------------------------------------------------
18
+ import dataclasses
19
+ from dataclasses import field
18
20
  import struct
19
- from typing import Dict, Optional, Type
20
-
21
- from bumble.hci import (
22
- name_or_number,
23
- hci_vendor_command_op_code,
24
- Address,
25
- HCI_Constant,
26
- HCI_Object,
27
- HCI_Command,
28
- HCI_Event,
29
- HCI_Extended_Event,
30
- HCI_VENDOR_EVENT,
31
- STATUS_SPEC,
32
- )
21
+ from typing import Optional
22
+
23
+ from bumble import hci
33
24
 
34
25
 
35
26
  # -----------------------------------------------------------------------------
@@ -41,22 +32,28 @@ from bumble.hci import (
41
32
  #
42
33
  # pylint: disable-next=line-too-long
43
34
  # See https://source.android.com/docs/core/connect/bluetooth/hci_requirements#chip-capabilities-and-configuration
44
- HCI_LE_GET_VENDOR_CAPABILITIES_COMMAND = hci_vendor_command_op_code(0x153)
45
- HCI_LE_APCF_COMMAND = hci_vendor_command_op_code(0x157)
46
- HCI_GET_CONTROLLER_ACTIVITY_ENERGY_INFO_COMMAND = hci_vendor_command_op_code(0x159)
47
- HCI_A2DP_HARDWARE_OFFLOAD_COMMAND = hci_vendor_command_op_code(0x15D)
48
- HCI_BLUETOOTH_QUALITY_REPORT_COMMAND = hci_vendor_command_op_code(0x15E)
49
- HCI_DYNAMIC_AUDIO_BUFFER_COMMAND = hci_vendor_command_op_code(0x15F)
35
+ HCI_LE_GET_VENDOR_CAPABILITIES_COMMAND = hci.hci_vendor_command_op_code(0x153)
36
+ HCI_LE_APCF_COMMAND = hci.hci_vendor_command_op_code(0x157)
37
+ HCI_GET_CONTROLLER_ACTIVITY_ENERGY_INFO_COMMAND = hci.hci_vendor_command_op_code(0x159)
38
+ HCI_A2DP_HARDWARE_OFFLOAD_COMMAND = hci.hci_vendor_command_op_code(0x15D)
39
+ HCI_BLUETOOTH_QUALITY_REPORT_COMMAND = hci.hci_vendor_command_op_code(0x15E)
40
+ HCI_DYNAMIC_AUDIO_BUFFER_COMMAND = hci.hci_vendor_command_op_code(0x15F)
50
41
 
51
42
  HCI_BLUETOOTH_QUALITY_REPORT_EVENT = 0x58
52
43
 
53
- HCI_Command.register_commands(globals())
44
+ hci.HCI_Command.register_commands(globals())
54
45
 
55
46
 
56
47
  # -----------------------------------------------------------------------------
57
- @HCI_Command.command(
58
- return_parameters_fields=[
59
- ('status', STATUS_SPEC),
48
+ @hci.HCI_Command.command
49
+ @dataclasses.dataclass
50
+ class HCI_LE_Get_Vendor_Capabilities_Command(hci.HCI_Command):
51
+ # pylint: disable=line-too-long
52
+ '''
53
+ See https://source.android.com/docs/core/connect/bluetooth/hci_requirements#vendor-specific-capabilities
54
+ '''
55
+ return_parameters_fields = [
56
+ ('status', hci.STATUS_SPEC),
60
57
  ('max_advt_instances', 1),
61
58
  ('offloaded_resolution_of_private_address', 1),
62
59
  ('total_scan_results_storage', 2),
@@ -73,12 +70,6 @@ HCI_Command.register_commands(globals())
73
70
  ('bluetooth_quality_report_support', 1),
74
71
  ('dynamic_audio_buffer_support', 4),
75
72
  ]
76
- )
77
- class HCI_LE_Get_Vendor_Capabilities_Command(HCI_Command):
78
- # pylint: disable=line-too-long
79
- '''
80
- See https://source.android.com/docs/core/connect/bluetooth/hci_requirements#vendor-specific-capabilities
81
- '''
82
73
 
83
74
  @classmethod
84
75
  def parse_return_parameters(cls, parameters):
@@ -86,13 +77,13 @@ class HCI_LE_Get_Vendor_Capabilities_Command(HCI_Command):
86
77
  # there are no more bytes to parse, and leave un-signal parameters set to
87
78
  # None (older versions)
88
79
  nones = {field: None for field, _ in cls.return_parameters_fields}
89
- return_parameters = HCI_Object(cls.return_parameters_fields, **nones)
80
+ return_parameters = hci.HCI_Object(cls.return_parameters_fields, **nones)
90
81
 
91
82
  try:
92
83
  offset = 0
93
84
  for field in cls.return_parameters_fields:
94
85
  field_name, field_type = field
95
- field_value, field_size = HCI_Object.parse_field(
86
+ field_value, field_size = hci.HCI_Object.parse_field(
96
87
  parameters, offset, field_type
97
88
  )
98
89
  setattr(return_parameters, field_name, field_value)
@@ -104,30 +95,9 @@ class HCI_LE_Get_Vendor_Capabilities_Command(HCI_Command):
104
95
 
105
96
 
106
97
  # -----------------------------------------------------------------------------
107
- @HCI_Command.command(
108
- fields=[
109
- (
110
- 'opcode',
111
- {
112
- 'size': 1,
113
- 'mapper': lambda x: HCI_LE_APCF_Command.opcode_name(x),
114
- },
115
- ),
116
- ('payload', '*'),
117
- ],
118
- return_parameters_fields=[
119
- ('status', STATUS_SPEC),
120
- (
121
- 'opcode',
122
- {
123
- 'size': 1,
124
- 'mapper': lambda x: HCI_LE_APCF_Command.opcode_name(x),
125
- },
126
- ),
127
- ('payload', '*'),
128
- ],
129
- )
130
- class HCI_LE_APCF_Command(HCI_Command):
98
+ @hci.HCI_Command.command
99
+ @dataclasses.dataclass
100
+ class HCI_LE_APCF_Command(hci.HCI_Command):
131
101
  # pylint: disable=line-too-long
132
102
  '''
133
103
  See https://source.android.com/docs/core/connect/bluetooth/hci_requirements#le_apcf_command
@@ -137,80 +107,50 @@ class HCI_LE_APCF_Command(HCI_Command):
137
107
  '''
138
108
 
139
109
  # APCF Subcommands
140
- # TODO: use the OpenIntEnum class (when upcoming PR is merged)
141
- APCF_ENABLE = 0x00
142
- APCF_SET_FILTERING_PARAMETERS = 0x01
143
- APCF_BROADCASTER_ADDRESS = 0x02
144
- APCF_SERVICE_UUID = 0x03
145
- APCF_SERVICE_SOLICITATION_UUID = 0x04
146
- APCF_LOCAL_NAME = 0x05
147
- APCF_MANUFACTURER_DATA = 0x06
148
- APCF_SERVICE_DATA = 0x07
149
- APCF_TRANSPORT_DISCOVERY_SERVICE = 0x08
150
- APCF_AD_TYPE_FILTER = 0x09
151
- APCF_READ_EXTENDED_FEATURES = 0xFF
152
-
153
- OPCODE_NAMES = {
154
- APCF_ENABLE: 'APCF_ENABLE',
155
- APCF_SET_FILTERING_PARAMETERS: 'APCF_SET_FILTERING_PARAMETERS',
156
- APCF_BROADCASTER_ADDRESS: 'APCF_BROADCASTER_ADDRESS',
157
- APCF_SERVICE_UUID: 'APCF_SERVICE_UUID',
158
- APCF_SERVICE_SOLICITATION_UUID: 'APCF_SERVICE_SOLICITATION_UUID',
159
- APCF_LOCAL_NAME: 'APCF_LOCAL_NAME',
160
- APCF_MANUFACTURER_DATA: 'APCF_MANUFACTURER_DATA',
161
- APCF_SERVICE_DATA: 'APCF_SERVICE_DATA',
162
- APCF_TRANSPORT_DISCOVERY_SERVICE: 'APCF_TRANSPORT_DISCOVERY_SERVICE',
163
- APCF_AD_TYPE_FILTER: 'APCF_AD_TYPE_FILTER',
164
- APCF_READ_EXTENDED_FEATURES: 'APCF_READ_EXTENDED_FEATURES',
165
- }
166
-
167
- @classmethod
168
- def opcode_name(cls, opcode):
169
- return name_or_number(cls.OPCODE_NAMES, opcode)
110
+ class Opcode(hci.SpecableEnum):
111
+ ENABLE = 0x00
112
+ SET_FILTERING_PARAMETERS = 0x01
113
+ BROADCASTER_ADDRESS = 0x02
114
+ SERVICE_UUID = 0x03
115
+ SERVICE_SOLICITATION_UUID = 0x04
116
+ LOCAL_NAME = 0x05
117
+ MANUFACTURER_DATA = 0x06
118
+ SERVICE_DATA = 0x07
119
+ TRANSPORT_DISCOVERY_SERVICE = 0x08
120
+ AD_TYPE_FILTER = 0x09
121
+ READ_EXTENDED_FEATURES = 0xFF
122
+
123
+ opcode: int = dataclasses.field(metadata=Opcode.type_metadata(1))
124
+ payload: bytes = dataclasses.field(metadata=hci.metadata("*"))
125
+
126
+ return_parameters_fields = [
127
+ ('status', hci.STATUS_SPEC),
128
+ ('opcode', Opcode.type_spec(1)),
129
+ ('payload', '*'),
130
+ ]
170
131
 
171
132
 
172
133
  # -----------------------------------------------------------------------------
173
- @HCI_Command.command(
174
- return_parameters_fields=[
175
- ('status', STATUS_SPEC),
176
- ('total_tx_time_ms', 4),
177
- ('total_rx_time_ms', 4),
178
- ('total_idle_time_ms', 4),
179
- ('total_energy_used', 4),
180
- ],
181
- )
182
- class HCI_Get_Controller_Activity_Energy_Info_Command(HCI_Command):
134
+ @hci.HCI_Command.command
135
+ @dataclasses.dataclass
136
+ class HCI_Get_Controller_Activity_Energy_Info_Command(hci.HCI_Command):
183
137
  # pylint: disable=line-too-long
184
138
  '''
185
139
  See https://source.android.com/docs/core/connect/bluetooth/hci_requirements#le_get_controller_activity_energy_info
186
140
  '''
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
+ ]
187
148
 
188
149
 
189
150
  # -----------------------------------------------------------------------------
190
- @HCI_Command.command(
191
- fields=[
192
- (
193
- 'opcode',
194
- {
195
- 'size': 1,
196
- 'mapper': lambda x: HCI_A2DP_Hardware_Offload_Command.opcode_name(x),
197
- },
198
- ),
199
- ('payload', '*'),
200
- ],
201
- return_parameters_fields=[
202
- ('status', STATUS_SPEC),
203
- (
204
- 'opcode',
205
- {
206
- 'size': 1,
207
- 'mapper': lambda x: HCI_A2DP_Hardware_Offload_Command.opcode_name(x),
208
- },
209
- ),
210
- ('payload', '*'),
211
- ],
212
- )
213
- class HCI_A2DP_Hardware_Offload_Command(HCI_Command):
151
+ @hci.HCI_Command.command
152
+ @dataclasses.dataclass
153
+ class HCI_A2DP_Hardware_Offload_Command(hci.HCI_Command):
214
154
  # pylint: disable=line-too-long
215
155
  '''
216
156
  See https://source.android.com/docs/core/connect/bluetooth/hci_requirements#a2dp-hardware-offload-support
@@ -220,45 +160,24 @@ class HCI_A2DP_Hardware_Offload_Command(HCI_Command):
220
160
  '''
221
161
 
222
162
  # A2DP Hardware Offload Subcommands
223
- # TODO: use the OpenIntEnum class (when upcoming PR is merged)
224
- START_A2DP_OFFLOAD = 0x01
225
- STOP_A2DP_OFFLOAD = 0x02
163
+ class Opcode(hci.SpecableEnum):
164
+ START_A2DP_OFFLOAD = 0x01
165
+ STOP_A2DP_OFFLOAD = 0x02
226
166
 
227
- OPCODE_NAMES = {
228
- START_A2DP_OFFLOAD: 'START_A2DP_OFFLOAD',
229
- STOP_A2DP_OFFLOAD: 'STOP_A2DP_OFFLOAD',
230
- }
167
+ opcode: int = dataclasses.field(metadata=Opcode.type_metadata(1))
168
+ payload: bytes = dataclasses.field(metadata=hci.metadata("*"))
231
169
 
232
- @classmethod
233
- def opcode_name(cls, opcode):
234
- return name_or_number(cls.OPCODE_NAMES, opcode)
170
+ return_parameters_fields = [
171
+ ('status', hci.STATUS_SPEC),
172
+ ('opcode', Opcode.type_spec(1)),
173
+ ('payload', '*'),
174
+ ]
235
175
 
236
176
 
237
177
  # -----------------------------------------------------------------------------
238
- @HCI_Command.command(
239
- fields=[
240
- (
241
- 'opcode',
242
- {
243
- 'size': 1,
244
- 'mapper': lambda x: HCI_Dynamic_Audio_Buffer_Command.opcode_name(x),
245
- },
246
- ),
247
- ('payload', '*'),
248
- ],
249
- return_parameters_fields=[
250
- ('status', STATUS_SPEC),
251
- (
252
- 'opcode',
253
- {
254
- 'size': 1,
255
- 'mapper': lambda x: HCI_Dynamic_Audio_Buffer_Command.opcode_name(x),
256
- },
257
- ),
258
- ('payload', '*'),
259
- ],
260
- )
261
- class HCI_Dynamic_Audio_Buffer_Command(HCI_Command):
178
+ @hci.HCI_Command.command
179
+ @dataclasses.dataclass
180
+ class HCI_Dynamic_Audio_Buffer_Command(hci.HCI_Command):
262
181
  # pylint: disable=line-too-long
263
182
  '''
264
183
  See https://source.android.com/docs/core/connect/bluetooth/hci_requirements#dynamic-audio-buffer-command
@@ -268,27 +187,28 @@ class HCI_Dynamic_Audio_Buffer_Command(HCI_Command):
268
187
  '''
269
188
 
270
189
  # Dynamic Audio Buffer Subcommands
271
- # TODO: use the OpenIntEnum class (when upcoming PR is merged)
272
- GET_AUDIO_BUFFER_TIME_CAPABILITY = 0x01
190
+ class Opcode(hci.SpecableEnum):
191
+ GET_AUDIO_BUFFER_TIME_CAPABILITY = 0x01
273
192
 
274
- OPCODE_NAMES = {
275
- GET_AUDIO_BUFFER_TIME_CAPABILITY: 'GET_AUDIO_BUFFER_TIME_CAPABILITY',
276
- }
193
+ opcode: int = dataclasses.field(metadata=Opcode.type_metadata(1))
194
+ payload: bytes = dataclasses.field(metadata=hci.metadata("*"))
277
195
 
278
- @classmethod
279
- def opcode_name(cls, opcode):
280
- return name_or_number(cls.OPCODE_NAMES, opcode)
196
+ return_parameters_fields = [
197
+ ('status', hci.STATUS_SPEC),
198
+ ('opcode', Opcode.type_spec(1)),
199
+ ('payload', '*'),
200
+ ]
281
201
 
282
202
 
283
203
  # -----------------------------------------------------------------------------
284
- class HCI_Android_Vendor_Event(HCI_Extended_Event):
285
- event_code: int = HCI_VENDOR_EVENT
286
- subevent_classes: Dict[int, Type[HCI_Extended_Event]] = {}
204
+ class HCI_Android_Vendor_Event(hci.HCI_Extended_Event):
205
+ event_code: int = hci.HCI_VENDOR_EVENT
206
+ subevent_classes: dict[int, type[hci.HCI_Extended_Event]] = {}
287
207
 
288
208
  @classmethod
289
209
  def subclass_from_parameters(
290
210
  cls, parameters: bytes
291
- ) -> Optional[HCI_Extended_Event]:
211
+ ) -> Optional[hci.HCI_Extended_Event]:
292
212
  subevent_code = parameters[0]
293
213
  if subevent_code == HCI_BLUETOOTH_QUALITY_REPORT_EVENT:
294
214
  quality_report_id = parameters[1]
@@ -299,45 +219,43 @@ class HCI_Android_Vendor_Event(HCI_Extended_Event):
299
219
 
300
220
 
301
221
  HCI_Android_Vendor_Event.register_subevents(globals())
302
- HCI_Event.add_vendor_factory(HCI_Android_Vendor_Event.subclass_from_parameters)
222
+ hci.HCI_Event.add_vendor_factory(HCI_Android_Vendor_Event.subclass_from_parameters)
303
223
 
304
224
 
305
225
  # -----------------------------------------------------------------------------
306
- @HCI_Extended_Event.event(
307
- fields=[
308
- ('quality_report_id', 1),
309
- ('packet_types', 1),
310
- ('connection_handle', 2),
311
- ('connection_role', {'size': 1, 'mapper': HCI_Constant.role_name}),
312
- ('tx_power_level', -1),
313
- ('rssi', -1),
314
- ('snr', 1),
315
- ('unused_afh_channel_count', 1),
316
- ('afh_select_unideal_channel_count', 1),
317
- ('lsto', 2),
318
- ('connection_piconet_clock', 4),
319
- ('retransmission_count', 4),
320
- ('no_rx_count', 4),
321
- ('nak_count', 4),
322
- ('last_tx_ack_timestamp', 4),
323
- ('flow_off_count', 4),
324
- ('last_flow_on_timestamp', 4),
325
- ('buffer_overflow_bytes', 4),
326
- ('buffer_underflow_bytes', 4),
327
- ('bdaddr', Address.parse_address),
328
- ('cal_failed_item_count', 1),
329
- ('tx_total_packets', 4),
330
- ('tx_unacked_packets', 4),
331
- ('tx_flushed_packets', 4),
332
- ('tx_last_subevent_packets', 4),
333
- ('crc_error_packets', 4),
334
- ('rx_duplicate_packets', 4),
335
- ('rx_unreceived_packets', 4),
336
- ('vendor_specific_parameters', '*'),
337
- ]
338
- )
226
+ @hci.HCI_Extended_Event.event
227
+ @dataclasses.dataclass
339
228
  class HCI_Bluetooth_Quality_Report_Event(HCI_Android_Vendor_Event):
340
229
  # pylint: disable=line-too-long
341
230
  '''
342
231
  See https://source.android.com/docs/core/connect/bluetooth/hci_requirements#bluetooth-quality-report-sub-event
343
232
  '''
233
+ quality_report_id: int = field(metadata=hci.metadata(1))
234
+ packet_types: int = field(metadata=hci.metadata(1))
235
+ connection_handle: int = field(metadata=hci.metadata(2))
236
+ connection_role: int = field(metadata=hci.Role.type_metadata(1))
237
+ tx_power_level: int = field(metadata=hci.metadata(-1))
238
+ rssi: int = field(metadata=hci.metadata(-1))
239
+ snr: int = field(metadata=hci.metadata(1))
240
+ unused_afh_channel_count: int = field(metadata=hci.metadata(1))
241
+ afh_select_unideal_channel_count: int = field(metadata=hci.metadata(1))
242
+ lsto: int = field(metadata=hci.metadata(2))
243
+ connection_piconet_clock: int = field(metadata=hci.metadata(4))
244
+ retransmission_count: int = field(metadata=hci.metadata(4))
245
+ no_rx_count: int = field(metadata=hci.metadata(4))
246
+ nak_count: int = field(metadata=hci.metadata(4))
247
+ last_tx_ack_timestamp: int = field(metadata=hci.metadata(4))
248
+ flow_off_count: int = field(metadata=hci.metadata(4))
249
+ last_flow_on_timestamp: int = field(metadata=hci.metadata(4))
250
+ buffer_overflow_bytes: int = field(metadata=hci.metadata(4))
251
+ buffer_underflow_bytes: int = field(metadata=hci.metadata(4))
252
+ bdaddr: hci.Address = field(metadata=hci.metadata(hci.Address.parse_address))
253
+ cal_failed_item_count: int = field(metadata=hci.metadata(1))
254
+ tx_total_packets: int = field(metadata=hci.metadata(4))
255
+ tx_unacked_packets: int = field(metadata=hci.metadata(4))
256
+ tx_flushed_packets: int = field(metadata=hci.metadata(4))
257
+ tx_last_subevent_packets: int = field(metadata=hci.metadata(4))
258
+ crc_error_packets: int = field(metadata=hci.metadata(4))
259
+ rx_duplicate_packets: int = field(metadata=hci.metadata(4))
260
+ rx_unreceived_packets: int = field(metadata=hci.metadata(4))
261
+ vendor_specific_parameters: bytes = field(metadata=hci.metadata('*'))
@@ -15,11 +15,9 @@
15
15
  # -----------------------------------------------------------------------------
16
16
  # Imports
17
17
  # -----------------------------------------------------------------------------
18
- from bumble.hci import (
19
- hci_vendor_command_op_code,
20
- HCI_Command,
21
- STATUS_SPEC,
22
- )
18
+ import dataclasses
19
+
20
+ from bumble import hci
23
21
 
24
22
 
25
23
  # -----------------------------------------------------------------------------
@@ -31,10 +29,10 @@ from bumble.hci import (
31
29
  #
32
30
  # pylint: disable-next=line-too-long
33
31
  # See https://github.com/zephyrproject-rtos/zephyr/blob/main/include/zephyr/bluetooth/hci_vs.h
34
- HCI_WRITE_TX_POWER_LEVEL_COMMAND = hci_vendor_command_op_code(0x000E)
35
- HCI_READ_TX_POWER_LEVEL_COMMAND = hci_vendor_command_op_code(0x000F)
32
+ HCI_WRITE_TX_POWER_LEVEL_COMMAND = hci.hci_vendor_command_op_code(0x000E)
33
+ HCI_READ_TX_POWER_LEVEL_COMMAND = hci.hci_vendor_command_op_code(0x000F)
36
34
 
37
- HCI_Command.register_commands(globals())
35
+ hci.HCI_Command.register_commands(globals())
38
36
 
39
37
 
40
38
  # -----------------------------------------------------------------------------
@@ -49,16 +47,9 @@ class TX_Power_Level_Command:
49
47
 
50
48
 
51
49
  # -----------------------------------------------------------------------------
52
- @HCI_Command.command(
53
- fields=[('handle_type', 1), ('connection_handle', 2), ('tx_power_level', -1)],
54
- return_parameters_fields=[
55
- ('status', STATUS_SPEC),
56
- ('handle_type', 1),
57
- ('connection_handle', 2),
58
- ('selected_tx_power_level', -1),
59
- ],
60
- )
61
- class HCI_Write_Tx_Power_Level_Command(HCI_Command, TX_Power_Level_Command):
50
+ @hci.HCI_Command.command
51
+ @dataclasses.dataclass
52
+ class HCI_Write_Tx_Power_Level_Command(hci.HCI_Command, TX_Power_Level_Command):
62
53
  '''
63
54
  Write TX power level. See BT_HCI_OP_VS_WRITE_TX_POWER_LEVEL in
64
55
  https://github.com/zephyrproject-rtos/zephyr/blob/main/include/zephyr/bluetooth/hci_vs.h
@@ -67,18 +58,22 @@ class HCI_Write_Tx_Power_Level_Command(HCI_Command, TX_Power_Level_Command):
67
58
  TX_POWER_HANDLE_TYPE_SCAN should be zero.
68
59
  '''
69
60
 
61
+ handle_type: int = dataclasses.field(metadata=hci.metadata(1))
62
+ connection_handle: int = dataclasses.field(metadata=hci.metadata(2))
63
+ tx_power_level: int = dataclasses.field(metadata=hci.metadata(-1))
70
64
 
71
- # -----------------------------------------------------------------------------
72
- @HCI_Command.command(
73
- fields=[('handle_type', 1), ('connection_handle', 2)],
74
- return_parameters_fields=[
75
- ('status', STATUS_SPEC),
65
+ return_parameters_fields = [
66
+ ('status', hci.STATUS_SPEC),
76
67
  ('handle_type', 1),
77
68
  ('connection_handle', 2),
78
- ('tx_power_level', -1),
79
- ],
80
- )
81
- class HCI_Read_Tx_Power_Level_Command(HCI_Command, TX_Power_Level_Command):
69
+ ('selected_tx_power_level', -1),
70
+ ]
71
+
72
+
73
+ # -----------------------------------------------------------------------------
74
+ @hci.HCI_Command.command
75
+ @dataclasses.dataclass
76
+ class HCI_Read_Tx_Power_Level_Command(hci.HCI_Command, TX_Power_Level_Command):
82
77
  '''
83
78
  Read TX power level. See BT_HCI_OP_VS_READ_TX_POWER_LEVEL in
84
79
  https://github.com/zephyrproject-rtos/zephyr/blob/main/include/zephyr/bluetooth/hci_vs.h
@@ -86,3 +81,13 @@ class HCI_Read_Tx_Power_Level_Command(HCI_Command, TX_Power_Level_Command):
86
81
  Power level is in dB. Connection handle for TX_POWER_HANDLE_TYPE_ADV and
87
82
  TX_POWER_HANDLE_TYPE_SCAN should be zero.
88
83
  '''
84
+
85
+ handle_type: int = dataclasses.field(metadata=hci.metadata(1))
86
+ connection_handle: int = dataclasses.field(metadata=hci.metadata(2))
87
+
88
+ return_parameters_fields = [
89
+ ('status', hci.STATUS_SPEC),
90
+ ('handle_type', 1),
91
+ ('connection_handle', 2),
92
+ ('tx_power_level', -1),
93
+ ]
@@ -1,17 +1,17 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bumble
3
- Version: 0.0.211
3
+ Version: 0.0.213
4
4
  Summary: Bluetooth Stack for Apps, Emulation, Test and Experimentation
5
5
  Author-email: Google <bumble-dev@google.com>
6
6
  Project-URL: Homepage, https://github.com/google/bumble
7
- Requires-Python: >=3.8
7
+ Requires-Python: >=3.9
8
8
  Description-Content-Type: text/markdown
9
9
  License-File: LICENSE
10
10
  Requires-Dist: aiohttp~=3.8; platform_system != "Emscripten"
11
11
  Requires-Dist: appdirs>=1.4; platform_system != "Emscripten"
12
12
  Requires-Dist: click>=8.1.3; platform_system != "Emscripten"
13
- Requires-Dist: cryptography>=39; platform_system != "Emscripten"
14
- Requires-Dist: cryptography>=39.0; platform_system == "Emscripten"
13
+ Requires-Dist: cryptography>=44.0.3; platform_system != "Emscripten"
14
+ Requires-Dist: cryptography>=44.0.3; platform_system == "Emscripten"
15
15
  Requires-Dist: grpcio>=1.62.1; platform_system != "Emscripten"
16
16
  Requires-Dist: humanize>=4.6.0; platform_system != "Emscripten"
17
17
  Requires-Dist: libusb1>=2.0.1; platform_system != "Emscripten"
@@ -20,7 +20,7 @@ Requires-Dist: platformdirs>=3.10.0; platform_system != "Emscripten"
20
20
  Requires-Dist: prompt_toolkit>=3.0.16; platform_system != "Emscripten"
21
21
  Requires-Dist: prettytable>=3.6.0; platform_system != "Emscripten"
22
22
  Requires-Dist: protobuf>=3.12.4; platform_system != "Emscripten"
23
- Requires-Dist: pyee>=8.2.2
23
+ Requires-Dist: pyee>=13.0.0
24
24
  Requires-Dist: pyserial-asyncio>=0.5; platform_system != "Emscripten"
25
25
  Requires-Dist: pyserial>=3.5; platform_system != "Emscripten"
26
26
  Requires-Dist: pyusb>=1.2; platform_system != "Emscripten"