bumble 0.0.179__py3-none-any.whl → 0.0.181__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/bench.py +110 -81
- bumble/apps/ble_rpa_tool.py +63 -0
- bumble/apps/console.py +4 -4
- bumble/apps/controller_info.py +34 -2
- bumble/apps/pair.py +6 -8
- bumble/att.py +53 -11
- bumble/controller.py +28 -1
- bumble/crypto.py +10 -0
- bumble/device.py +630 -134
- bumble/drivers/__init__.py +27 -31
- bumble/drivers/common.py +45 -0
- bumble/drivers/rtk.py +11 -4
- bumble/gatt.py +183 -58
- bumble/gatt_client.py +56 -20
- bumble/gatt_server.py +30 -22
- bumble/hci.py +227 -92
- bumble/helpers.py +81 -42
- bumble/hfp.py +37 -27
- bumble/hid.py +282 -61
- bumble/host.py +158 -93
- bumble/l2cap.py +11 -3
- bumble/profiles/asha_service.py +2 -2
- bumble/profiles/bap.py +1247 -0
- bumble/profiles/cap.py +52 -0
- bumble/profiles/csip.py +205 -0
- bumble/rfcomm.py +24 -17
- bumble/smp.py +1 -1
- bumble/transport/__init__.py +49 -21
- bumble/transport/android_emulator.py +1 -1
- bumble/transport/common.py +3 -2
- bumble/transport/hci_socket.py +1 -4
- bumble/transport/usb.py +1 -1
- bumble/utils.py +3 -6
- {bumble-0.0.179.dist-info → bumble-0.0.181.dist-info}/METADATA +1 -1
- {bumble-0.0.179.dist-info → bumble-0.0.181.dist-info}/RECORD +40 -35
- {bumble-0.0.179.dist-info → bumble-0.0.181.dist-info}/entry_points.txt +1 -0
- {bumble-0.0.179.dist-info → bumble-0.0.181.dist-info}/LICENSE +0 -0
- {bumble-0.0.179.dist-info → bumble-0.0.181.dist-info}/WHEEL +0 -0
- {bumble-0.0.179.dist-info → bumble-0.0.181.dist-info}/top_level.txt +0 -0
bumble/helpers.py
CHANGED
|
@@ -15,30 +15,41 @@
|
|
|
15
15
|
# -----------------------------------------------------------------------------
|
|
16
16
|
# Imports
|
|
17
17
|
# -----------------------------------------------------------------------------
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
|
|
20
|
+
from collections.abc import Callable, MutableMapping
|
|
21
|
+
from typing import cast, Any
|
|
18
22
|
import logging
|
|
19
23
|
|
|
20
|
-
from
|
|
21
|
-
from .
|
|
22
|
-
from .
|
|
23
|
-
from .
|
|
24
|
-
from .
|
|
24
|
+
from bumble import avdtp
|
|
25
|
+
from bumble.colors import color
|
|
26
|
+
from bumble.att import ATT_CID, ATT_PDU
|
|
27
|
+
from bumble.smp import SMP_CID, SMP_Command
|
|
28
|
+
from bumble.core import name_or_number
|
|
29
|
+
from bumble.l2cap import (
|
|
25
30
|
L2CAP_PDU,
|
|
26
31
|
L2CAP_CONNECTION_REQUEST,
|
|
27
32
|
L2CAP_CONNECTION_RESPONSE,
|
|
28
33
|
L2CAP_SIGNALING_CID,
|
|
29
34
|
L2CAP_LE_SIGNALING_CID,
|
|
30
35
|
L2CAP_Control_Frame,
|
|
36
|
+
L2CAP_Connection_Request,
|
|
31
37
|
L2CAP_Connection_Response,
|
|
32
38
|
)
|
|
33
|
-
from .hci import (
|
|
39
|
+
from bumble.hci import (
|
|
40
|
+
Address,
|
|
34
41
|
HCI_EVENT_PACKET,
|
|
35
42
|
HCI_ACL_DATA_PACKET,
|
|
36
43
|
HCI_DISCONNECTION_COMPLETE_EVENT,
|
|
37
44
|
HCI_AclDataPacketAssembler,
|
|
45
|
+
HCI_Packet,
|
|
46
|
+
HCI_Event,
|
|
47
|
+
HCI_AclDataPacket,
|
|
48
|
+
HCI_Disconnection_Complete_Event,
|
|
38
49
|
)
|
|
39
|
-
from .rfcomm import RFCOMM_Frame, RFCOMM_PSM
|
|
40
|
-
from .sdp import SDP_PDU, SDP_PSM
|
|
41
|
-
from
|
|
50
|
+
from bumble.rfcomm import RFCOMM_Frame, RFCOMM_PSM
|
|
51
|
+
from bumble.sdp import SDP_PDU, SDP_PSM
|
|
52
|
+
from bumble import crypto
|
|
42
53
|
|
|
43
54
|
# -----------------------------------------------------------------------------
|
|
44
55
|
# Logging
|
|
@@ -50,23 +61,25 @@ logger = logging.getLogger(__name__)
|
|
|
50
61
|
PSM_NAMES = {
|
|
51
62
|
RFCOMM_PSM: 'RFCOMM',
|
|
52
63
|
SDP_PSM: 'SDP',
|
|
53
|
-
AVDTP_PSM: 'AVDTP'
|
|
54
|
-
# TODO: add more PSM values
|
|
64
|
+
avdtp.AVDTP_PSM: 'AVDTP',
|
|
55
65
|
}
|
|
56
66
|
|
|
57
67
|
|
|
58
68
|
# -----------------------------------------------------------------------------
|
|
59
69
|
class PacketTracer:
|
|
60
70
|
class AclStream:
|
|
61
|
-
|
|
71
|
+
psms: MutableMapping[int, int]
|
|
72
|
+
peer: PacketTracer.AclStream
|
|
73
|
+
avdtp_assemblers: MutableMapping[int, avdtp.MessageAssembler]
|
|
74
|
+
|
|
75
|
+
def __init__(self, analyzer: PacketTracer.Analyzer) -> None:
|
|
62
76
|
self.analyzer = analyzer
|
|
63
77
|
self.packet_assembler = HCI_AclDataPacketAssembler(self.on_acl_pdu)
|
|
64
78
|
self.avdtp_assemblers = {} # AVDTP assemblers, by source_cid
|
|
65
79
|
self.psms = {} # PSM, by source_cid
|
|
66
|
-
self.peer = None # ACL stream in the other direction
|
|
67
80
|
|
|
68
81
|
# pylint: disable=too-many-nested-blocks
|
|
69
|
-
def on_acl_pdu(self, pdu):
|
|
82
|
+
def on_acl_pdu(self, pdu: bytes) -> None:
|
|
70
83
|
l2cap_pdu = L2CAP_PDU.from_bytes(pdu)
|
|
71
84
|
|
|
72
85
|
if l2cap_pdu.cid == ATT_CID:
|
|
@@ -81,26 +94,30 @@ class PacketTracer:
|
|
|
81
94
|
|
|
82
95
|
# Check if this signals a new channel
|
|
83
96
|
if control_frame.code == L2CAP_CONNECTION_REQUEST:
|
|
84
|
-
|
|
97
|
+
connection_request = cast(L2CAP_Connection_Request, control_frame)
|
|
98
|
+
self.psms[connection_request.source_cid] = connection_request.psm
|
|
85
99
|
elif control_frame.code == L2CAP_CONNECTION_RESPONSE:
|
|
100
|
+
connection_response = cast(L2CAP_Connection_Response, control_frame)
|
|
86
101
|
if (
|
|
87
|
-
|
|
102
|
+
connection_response.result
|
|
88
103
|
== L2CAP_Connection_Response.CONNECTION_SUCCESSFUL
|
|
89
104
|
):
|
|
90
105
|
if self.peer:
|
|
91
|
-
if psm := self.peer.psms.get(
|
|
106
|
+
if psm := self.peer.psms.get(
|
|
107
|
+
connection_response.source_cid
|
|
108
|
+
):
|
|
92
109
|
# Found a pending connection
|
|
93
|
-
self.psms[
|
|
110
|
+
self.psms[connection_response.destination_cid] = psm
|
|
94
111
|
|
|
95
112
|
# For AVDTP connections, create a packet assembler for
|
|
96
113
|
# each direction
|
|
97
|
-
if psm == AVDTP_PSM:
|
|
114
|
+
if psm == avdtp.AVDTP_PSM:
|
|
98
115
|
self.avdtp_assemblers[
|
|
99
|
-
|
|
100
|
-
] =
|
|
116
|
+
connection_response.source_cid
|
|
117
|
+
] = avdtp.MessageAssembler(self.on_avdtp_message)
|
|
101
118
|
self.peer.avdtp_assemblers[
|
|
102
|
-
|
|
103
|
-
] =
|
|
119
|
+
connection_response.destination_cid
|
|
120
|
+
] = avdtp.MessageAssembler(
|
|
104
121
|
self.peer.on_avdtp_message
|
|
105
122
|
)
|
|
106
123
|
|
|
@@ -113,7 +130,7 @@ class PacketTracer:
|
|
|
113
130
|
elif psm == RFCOMM_PSM:
|
|
114
131
|
rfcomm_frame = RFCOMM_Frame.from_bytes(l2cap_pdu.payload)
|
|
115
132
|
self.analyzer.emit(rfcomm_frame)
|
|
116
|
-
elif psm == AVDTP_PSM:
|
|
133
|
+
elif psm == avdtp.AVDTP_PSM:
|
|
117
134
|
self.analyzer.emit(
|
|
118
135
|
f'{color("L2CAP", "green")} [CID={l2cap_pdu.cid}, '
|
|
119
136
|
f'PSM=AVDTP]: {l2cap_pdu.payload.hex()}'
|
|
@@ -130,22 +147,26 @@ class PacketTracer:
|
|
|
130
147
|
else:
|
|
131
148
|
self.analyzer.emit(l2cap_pdu)
|
|
132
149
|
|
|
133
|
-
def on_avdtp_message(
|
|
150
|
+
def on_avdtp_message(
|
|
151
|
+
self, transaction_label: int, message: avdtp.Message
|
|
152
|
+
) -> None:
|
|
134
153
|
self.analyzer.emit(
|
|
135
154
|
f'{color("AVDTP", "green")} [{transaction_label}] {message}'
|
|
136
155
|
)
|
|
137
156
|
|
|
138
|
-
def feed_packet(self, packet):
|
|
157
|
+
def feed_packet(self, packet: HCI_AclDataPacket) -> None:
|
|
139
158
|
self.packet_assembler.feed_packet(packet)
|
|
140
159
|
|
|
141
160
|
class Analyzer:
|
|
142
|
-
|
|
161
|
+
acl_streams: MutableMapping[int, PacketTracer.AclStream]
|
|
162
|
+
peer: PacketTracer.Analyzer
|
|
163
|
+
|
|
164
|
+
def __init__(self, label: str, emit_message: Callable[..., None]) -> None:
|
|
143
165
|
self.label = label
|
|
144
166
|
self.emit_message = emit_message
|
|
145
167
|
self.acl_streams = {} # ACL streams, by connection handle
|
|
146
|
-
self.peer = None # Analyzer in the other direction
|
|
147
168
|
|
|
148
|
-
def start_acl_stream(self, connection_handle):
|
|
169
|
+
def start_acl_stream(self, connection_handle: int) -> PacketTracer.AclStream:
|
|
149
170
|
logger.info(
|
|
150
171
|
f'[{self.label}] +++ Creating ACL stream for connection '
|
|
151
172
|
f'0x{connection_handle:04X}'
|
|
@@ -160,7 +181,7 @@ class PacketTracer:
|
|
|
160
181
|
|
|
161
182
|
return stream
|
|
162
183
|
|
|
163
|
-
def end_acl_stream(self, connection_handle):
|
|
184
|
+
def end_acl_stream(self, connection_handle: int) -> None:
|
|
164
185
|
if connection_handle in self.acl_streams:
|
|
165
186
|
logger.info(
|
|
166
187
|
f'[{self.label}] --- Removing ACL stream for connection '
|
|
@@ -171,23 +192,29 @@ class PacketTracer:
|
|
|
171
192
|
# Let the other forwarder know so it can cleanup its stream as well
|
|
172
193
|
self.peer.end_acl_stream(connection_handle)
|
|
173
194
|
|
|
174
|
-
def on_packet(self, packet):
|
|
195
|
+
def on_packet(self, packet: HCI_Packet) -> None:
|
|
175
196
|
self.emit(packet)
|
|
176
197
|
|
|
177
198
|
if packet.hci_packet_type == HCI_ACL_DATA_PACKET:
|
|
199
|
+
acl_packet = cast(HCI_AclDataPacket, packet)
|
|
178
200
|
# Look for an existing stream for this handle, create one if it is the
|
|
179
201
|
# first ACL packet for that connection handle
|
|
180
|
-
if (
|
|
181
|
-
stream
|
|
182
|
-
|
|
202
|
+
if (
|
|
203
|
+
stream := self.acl_streams.get(acl_packet.connection_handle)
|
|
204
|
+
) is None:
|
|
205
|
+
stream = self.start_acl_stream(acl_packet.connection_handle)
|
|
206
|
+
stream.feed_packet(acl_packet)
|
|
183
207
|
elif packet.hci_packet_type == HCI_EVENT_PACKET:
|
|
184
|
-
|
|
185
|
-
|
|
208
|
+
event_packet = cast(HCI_Event, packet)
|
|
209
|
+
if event_packet.event_code == HCI_DISCONNECTION_COMPLETE_EVENT:
|
|
210
|
+
self.end_acl_stream(
|
|
211
|
+
cast(HCI_Disconnection_Complete_Event, packet).connection_handle
|
|
212
|
+
)
|
|
186
213
|
|
|
187
|
-
def emit(self, message):
|
|
214
|
+
def emit(self, message: Any) -> None:
|
|
188
215
|
self.emit_message(f'[{self.label}] {message}')
|
|
189
216
|
|
|
190
|
-
def trace(self, packet, direction=0):
|
|
217
|
+
def trace(self, packet: HCI_Packet, direction: int = 0) -> None:
|
|
191
218
|
if direction == 0:
|
|
192
219
|
self.host_to_controller_analyzer.on_packet(packet)
|
|
193
220
|
else:
|
|
@@ -195,10 +222,10 @@ class PacketTracer:
|
|
|
195
222
|
|
|
196
223
|
def __init__(
|
|
197
224
|
self,
|
|
198
|
-
host_to_controller_label=color('HOST->CONTROLLER', 'blue'),
|
|
199
|
-
controller_to_host_label=color('CONTROLLER->HOST', 'cyan'),
|
|
200
|
-
emit_message=logger.info,
|
|
201
|
-
):
|
|
225
|
+
host_to_controller_label: str = color('HOST->CONTROLLER', 'blue'),
|
|
226
|
+
controller_to_host_label: str = color('CONTROLLER->HOST', 'cyan'),
|
|
227
|
+
emit_message: Callable[..., None] = logger.info,
|
|
228
|
+
) -> None:
|
|
202
229
|
self.host_to_controller_analyzer = PacketTracer.Analyzer(
|
|
203
230
|
host_to_controller_label, emit_message
|
|
204
231
|
)
|
|
@@ -207,3 +234,15 @@ class PacketTracer:
|
|
|
207
234
|
)
|
|
208
235
|
self.host_to_controller_analyzer.peer = self.controller_to_host_analyzer
|
|
209
236
|
self.controller_to_host_analyzer.peer = self.host_to_controller_analyzer
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
def generate_irk() -> bytes:
|
|
240
|
+
return crypto.r()
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
def verify_rpa_with_irk(rpa: Address, irk: bytes) -> bool:
|
|
244
|
+
rpa_bytes = bytes(rpa)
|
|
245
|
+
prand_given = rpa_bytes[3:]
|
|
246
|
+
hash_given = rpa_bytes[:3]
|
|
247
|
+
hash_local = crypto.ah(irk, prand_given)
|
|
248
|
+
return hash_local[:3] == hash_given
|
bumble/hfp.py
CHANGED
|
@@ -22,7 +22,7 @@ import dataclasses
|
|
|
22
22
|
import enum
|
|
23
23
|
import traceback
|
|
24
24
|
import warnings
|
|
25
|
-
from typing import Dict, List, Union, Set, TYPE_CHECKING
|
|
25
|
+
from typing import Dict, List, Union, Set, Any, TYPE_CHECKING
|
|
26
26
|
|
|
27
27
|
from . import at
|
|
28
28
|
from . import rfcomm
|
|
@@ -35,7 +35,11 @@ from bumble.core import (
|
|
|
35
35
|
BT_L2CAP_PROTOCOL_ID,
|
|
36
36
|
BT_RFCOMM_PROTOCOL_ID,
|
|
37
37
|
)
|
|
38
|
-
from bumble.hci import
|
|
38
|
+
from bumble.hci import (
|
|
39
|
+
HCI_Enhanced_Setup_Synchronous_Connection_Command,
|
|
40
|
+
CodingFormat,
|
|
41
|
+
CodecID,
|
|
42
|
+
)
|
|
39
43
|
from bumble.sdp import (
|
|
40
44
|
DataElement,
|
|
41
45
|
ServiceAttribute,
|
|
@@ -66,6 +70,7 @@ class HfpProtocolError(ProtocolError):
|
|
|
66
70
|
# Protocol Support
|
|
67
71
|
# -----------------------------------------------------------------------------
|
|
68
72
|
|
|
73
|
+
|
|
69
74
|
# -----------------------------------------------------------------------------
|
|
70
75
|
class HfpProtocol:
|
|
71
76
|
dlc: rfcomm.DLC
|
|
@@ -842,19 +847,15 @@ class DefaultCodecParameters(enum.IntEnum):
|
|
|
842
847
|
@dataclasses.dataclass
|
|
843
848
|
class EscoParameters:
|
|
844
849
|
# Codec specific
|
|
845
|
-
transmit_coding_format:
|
|
846
|
-
receive_coding_format:
|
|
850
|
+
transmit_coding_format: CodingFormat
|
|
851
|
+
receive_coding_format: CodingFormat
|
|
847
852
|
packet_type: HCI_Enhanced_Setup_Synchronous_Connection_Command.PacketType
|
|
848
853
|
retransmission_effort: HCI_Enhanced_Setup_Synchronous_Connection_Command.RetransmissionEffort
|
|
849
854
|
max_latency: int
|
|
850
855
|
|
|
851
856
|
# Common
|
|
852
|
-
input_coding_format:
|
|
853
|
-
|
|
854
|
-
)
|
|
855
|
-
output_coding_format: HCI_Enhanced_Setup_Synchronous_Connection_Command.CodingFormat = (
|
|
856
|
-
HCI_Enhanced_Setup_Synchronous_Connection_Command.CodingFormat.TRANSPARENT
|
|
857
|
-
)
|
|
857
|
+
input_coding_format: CodingFormat = CodingFormat(CodecID.LINEAR_PCM)
|
|
858
|
+
output_coding_format: CodingFormat = CodingFormat(CodecID.LINEAR_PCM)
|
|
858
859
|
input_coded_data_size: int = 16
|
|
859
860
|
output_coded_data_size: int = 16
|
|
860
861
|
input_pcm_data_format: HCI_Enhanced_Setup_Synchronous_Connection_Command.PcmDataFormat = (
|
|
@@ -880,26 +881,31 @@ class EscoParameters:
|
|
|
880
881
|
transmit_codec_frame_size: int = 60
|
|
881
882
|
receive_codec_frame_size: int = 60
|
|
882
883
|
|
|
884
|
+
def asdict(self) -> Dict[str, Any]:
|
|
885
|
+
# dataclasses.asdict() will recursively deep-copy the entire object,
|
|
886
|
+
# which is expensive and breaks CodingFormat object, so let it simply copy here.
|
|
887
|
+
return self.__dict__
|
|
888
|
+
|
|
883
889
|
|
|
884
890
|
_ESCO_PARAMETERS_CVSD_D0 = EscoParameters(
|
|
885
|
-
transmit_coding_format=
|
|
886
|
-
receive_coding_format=
|
|
891
|
+
transmit_coding_format=CodingFormat(CodecID.CVSD),
|
|
892
|
+
receive_coding_format=CodingFormat(CodecID.CVSD),
|
|
887
893
|
max_latency=0xFFFF,
|
|
888
894
|
packet_type=HCI_Enhanced_Setup_Synchronous_Connection_Command.PacketType.HV1,
|
|
889
895
|
retransmission_effort=HCI_Enhanced_Setup_Synchronous_Connection_Command.RetransmissionEffort.NO_RETRANSMISSION,
|
|
890
896
|
)
|
|
891
897
|
|
|
892
898
|
_ESCO_PARAMETERS_CVSD_D1 = EscoParameters(
|
|
893
|
-
transmit_coding_format=
|
|
894
|
-
receive_coding_format=
|
|
899
|
+
transmit_coding_format=CodingFormat(CodecID.CVSD),
|
|
900
|
+
receive_coding_format=CodingFormat(CodecID.CVSD),
|
|
895
901
|
max_latency=0xFFFF,
|
|
896
902
|
packet_type=HCI_Enhanced_Setup_Synchronous_Connection_Command.PacketType.HV3,
|
|
897
903
|
retransmission_effort=HCI_Enhanced_Setup_Synchronous_Connection_Command.RetransmissionEffort.NO_RETRANSMISSION,
|
|
898
904
|
)
|
|
899
905
|
|
|
900
906
|
_ESCO_PARAMETERS_CVSD_S1 = EscoParameters(
|
|
901
|
-
transmit_coding_format=
|
|
902
|
-
receive_coding_format=
|
|
907
|
+
transmit_coding_format=CodingFormat(CodecID.CVSD),
|
|
908
|
+
receive_coding_format=CodingFormat(CodecID.CVSD),
|
|
903
909
|
max_latency=0x0007,
|
|
904
910
|
packet_type=(
|
|
905
911
|
HCI_Enhanced_Setup_Synchronous_Connection_Command.PacketType.EV3
|
|
@@ -912,8 +918,8 @@ _ESCO_PARAMETERS_CVSD_S1 = EscoParameters(
|
|
|
912
918
|
)
|
|
913
919
|
|
|
914
920
|
_ESCO_PARAMETERS_CVSD_S2 = EscoParameters(
|
|
915
|
-
transmit_coding_format=
|
|
916
|
-
receive_coding_format=
|
|
921
|
+
transmit_coding_format=CodingFormat(CodecID.CVSD),
|
|
922
|
+
receive_coding_format=CodingFormat(CodecID.CVSD),
|
|
917
923
|
max_latency=0x0007,
|
|
918
924
|
packet_type=(
|
|
919
925
|
HCI_Enhanced_Setup_Synchronous_Connection_Command.PacketType.EV3
|
|
@@ -925,8 +931,8 @@ _ESCO_PARAMETERS_CVSD_S2 = EscoParameters(
|
|
|
925
931
|
)
|
|
926
932
|
|
|
927
933
|
_ESCO_PARAMETERS_CVSD_S3 = EscoParameters(
|
|
928
|
-
transmit_coding_format=
|
|
929
|
-
receive_coding_format=
|
|
934
|
+
transmit_coding_format=CodingFormat(CodecID.CVSD),
|
|
935
|
+
receive_coding_format=CodingFormat(CodecID.CVSD),
|
|
930
936
|
max_latency=0x000A,
|
|
931
937
|
packet_type=(
|
|
932
938
|
HCI_Enhanced_Setup_Synchronous_Connection_Command.PacketType.EV3
|
|
@@ -938,8 +944,8 @@ _ESCO_PARAMETERS_CVSD_S3 = EscoParameters(
|
|
|
938
944
|
)
|
|
939
945
|
|
|
940
946
|
_ESCO_PARAMETERS_CVSD_S4 = EscoParameters(
|
|
941
|
-
transmit_coding_format=
|
|
942
|
-
receive_coding_format=
|
|
947
|
+
transmit_coding_format=CodingFormat(CodecID.CVSD),
|
|
948
|
+
receive_coding_format=CodingFormat(CodecID.CVSD),
|
|
943
949
|
max_latency=0x000C,
|
|
944
950
|
packet_type=(
|
|
945
951
|
HCI_Enhanced_Setup_Synchronous_Connection_Command.PacketType.EV3
|
|
@@ -951,8 +957,8 @@ _ESCO_PARAMETERS_CVSD_S4 = EscoParameters(
|
|
|
951
957
|
)
|
|
952
958
|
|
|
953
959
|
_ESCO_PARAMETERS_MSBC_T1 = EscoParameters(
|
|
954
|
-
transmit_coding_format=
|
|
955
|
-
receive_coding_format=
|
|
960
|
+
transmit_coding_format=CodingFormat(CodecID.MSBC),
|
|
961
|
+
receive_coding_format=CodingFormat(CodecID.MSBC),
|
|
956
962
|
max_latency=0x0008,
|
|
957
963
|
packet_type=(
|
|
958
964
|
HCI_Enhanced_Setup_Synchronous_Connection_Command.PacketType.EV3
|
|
@@ -960,12 +966,14 @@ _ESCO_PARAMETERS_MSBC_T1 = EscoParameters(
|
|
|
960
966
|
| HCI_Enhanced_Setup_Synchronous_Connection_Command.PacketType.NO_2_EV5
|
|
961
967
|
| HCI_Enhanced_Setup_Synchronous_Connection_Command.PacketType.NO_3_EV5
|
|
962
968
|
),
|
|
969
|
+
input_bandwidth=32000,
|
|
970
|
+
output_bandwidth=32000,
|
|
963
971
|
retransmission_effort=HCI_Enhanced_Setup_Synchronous_Connection_Command.RetransmissionEffort.OPTIMIZE_FOR_QUALITY,
|
|
964
972
|
)
|
|
965
973
|
|
|
966
974
|
_ESCO_PARAMETERS_MSBC_T2 = EscoParameters(
|
|
967
|
-
transmit_coding_format=
|
|
968
|
-
receive_coding_format=
|
|
975
|
+
transmit_coding_format=CodingFormat(CodecID.MSBC),
|
|
976
|
+
receive_coding_format=CodingFormat(CodecID.MSBC),
|
|
969
977
|
max_latency=0x000D,
|
|
970
978
|
packet_type=(
|
|
971
979
|
HCI_Enhanced_Setup_Synchronous_Connection_Command.PacketType.EV3
|
|
@@ -974,10 +982,12 @@ _ESCO_PARAMETERS_MSBC_T2 = EscoParameters(
|
|
|
974
982
|
| HCI_Enhanced_Setup_Synchronous_Connection_Command.PacketType.NO_2_EV5
|
|
975
983
|
| HCI_Enhanced_Setup_Synchronous_Connection_Command.PacketType.NO_3_EV5
|
|
976
984
|
),
|
|
985
|
+
input_bandwidth=32000,
|
|
986
|
+
output_bandwidth=32000,
|
|
977
987
|
retransmission_effort=HCI_Enhanced_Setup_Synchronous_Connection_Command.RetransmissionEffort.OPTIMIZE_FOR_QUALITY,
|
|
978
988
|
)
|
|
979
989
|
|
|
980
|
-
|
|
990
|
+
ESCO_PARAMETERS = {
|
|
981
991
|
DefaultCodecParameters.SCO_CVSD_D0: _ESCO_PARAMETERS_CVSD_D0,
|
|
982
992
|
DefaultCodecParameters.SCO_CVSD_D1: _ESCO_PARAMETERS_CVSD_D1,
|
|
983
993
|
DefaultCodecParameters.ESCO_CVSD_S1: _ESCO_PARAMETERS_CVSD_S1,
|