bumble 0.0.221__py3-none-any.whl → 0.0.222__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/l2cap.py +117 -62
- {bumble-0.0.221.dist-info → bumble-0.0.222.dist-info}/METADATA +1 -1
- {bumble-0.0.221.dist-info → bumble-0.0.222.dist-info}/RECORD +8 -8
- {bumble-0.0.221.dist-info → bumble-0.0.222.dist-info}/WHEEL +0 -0
- {bumble-0.0.221.dist-info → bumble-0.0.222.dist-info}/entry_points.txt +0 -0
- {bumble-0.0.221.dist-info → bumble-0.0.222.dist-info}/licenses/LICENSE +0 -0
- {bumble-0.0.221.dist-info → bumble-0.0.222.dist-info}/top_level.txt +0 -0
bumble/_version.py
CHANGED
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '0.0.
|
|
32
|
-
__version_tuple__ = version_tuple = (0, 0,
|
|
31
|
+
__version__ = version = '0.0.222'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 0, 222)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
bumble/l2cap.py
CHANGED
|
@@ -20,6 +20,7 @@ from __future__ import annotations
|
|
|
20
20
|
import asyncio
|
|
21
21
|
import dataclasses
|
|
22
22
|
import enum
|
|
23
|
+
import itertools
|
|
23
24
|
import logging
|
|
24
25
|
import struct
|
|
25
26
|
from collections import deque
|
|
@@ -302,11 +303,9 @@ class EnhancedControlField(ControlField):
|
|
|
302
303
|
|
|
303
304
|
@dataclasses.dataclass
|
|
304
305
|
class InformationEnhancedControlField(EnhancedControlField):
|
|
305
|
-
tx_seq: int
|
|
306
|
+
tx_seq: int
|
|
307
|
+
sar: int
|
|
306
308
|
req_seq: int = 0
|
|
307
|
-
segmentation_and_reassembly: int = (
|
|
308
|
-
EnhancedControlField.SegmentationAndReassembly.UNSEGMENTED
|
|
309
|
-
)
|
|
310
309
|
final: int = 1
|
|
311
310
|
|
|
312
311
|
frame_type = EnhancedControlField.FieldType.I_FRAME
|
|
@@ -316,15 +315,15 @@ class InformationEnhancedControlField(EnhancedControlField):
|
|
|
316
315
|
return cls(
|
|
317
316
|
tx_seq=(data[0] >> 1) & 0b0111111,
|
|
318
317
|
final=(data[0] >> 7) & 0b1,
|
|
319
|
-
req_seq=(data[1] &
|
|
320
|
-
|
|
318
|
+
req_seq=(data[1] & 0b00111111),
|
|
319
|
+
sar=(data[1] >> 6) & 0b11,
|
|
321
320
|
)
|
|
322
321
|
|
|
323
322
|
def __bytes__(self) -> bytes:
|
|
324
323
|
return bytes(
|
|
325
324
|
[
|
|
326
325
|
self.frame_type | (self.tx_seq << 1) | (self.final << 7),
|
|
327
|
-
self.req_seq | (self.
|
|
326
|
+
self.req_seq | (self.sar << 6),
|
|
328
327
|
]
|
|
329
328
|
)
|
|
330
329
|
|
|
@@ -889,27 +888,38 @@ class EnhancedRetransmissionProcessor(Processor):
|
|
|
889
888
|
class _PendingPdu:
|
|
890
889
|
payload: bytes
|
|
891
890
|
tx_seq: int
|
|
891
|
+
sar: InformationEnhancedControlField.SegmentationAndReassembly
|
|
892
|
+
sdu_length: int = 0
|
|
892
893
|
req_seq: int = 0
|
|
893
894
|
|
|
894
895
|
def __bytes__(self) -> bytes:
|
|
895
896
|
return (
|
|
896
897
|
bytes(
|
|
897
898
|
InformationEnhancedControlField(
|
|
898
|
-
tx_seq=self.tx_seq,
|
|
899
|
+
tx_seq=self.tx_seq,
|
|
900
|
+
req_seq=self.req_seq,
|
|
901
|
+
sar=self.sar,
|
|
899
902
|
)
|
|
900
903
|
)
|
|
904
|
+
+ (
|
|
905
|
+
struct.pack('<H', self.sdu_length)
|
|
906
|
+
if self.sar
|
|
907
|
+
== InformationEnhancedControlField.SegmentationAndReassembly.START
|
|
908
|
+
else b''
|
|
909
|
+
)
|
|
901
910
|
+ self.payload
|
|
902
911
|
)
|
|
903
912
|
|
|
904
|
-
|
|
913
|
+
_last_acked_tx_seq: int = 0
|
|
914
|
+
_last_acked_rx_seq: int = 0
|
|
905
915
|
_next_tx_seq: int = 0
|
|
906
|
-
_last_tx_seq: int = 0
|
|
907
916
|
_req_seq_num: int = 0
|
|
908
|
-
_next_seq_num: int = 0
|
|
909
917
|
_remote_is_busy: bool = False
|
|
918
|
+
_in_sdu: bytes = b''
|
|
910
919
|
|
|
911
920
|
_num_receiver_ready_polls_sent: int = 0
|
|
912
921
|
_pending_pdus: list[_PendingPdu]
|
|
922
|
+
_tx_window: list[_PendingPdu]
|
|
913
923
|
_monitor_handle: asyncio.TimerHandle | None = None
|
|
914
924
|
_receiver_ready_poll_handle: asyncio.TimerHandle | None = None
|
|
915
925
|
|
|
@@ -917,12 +927,6 @@ class EnhancedRetransmissionProcessor(Processor):
|
|
|
917
927
|
monitor_timeout: float
|
|
918
928
|
retransmission_timeout: float
|
|
919
929
|
|
|
920
|
-
@classmethod
|
|
921
|
-
def _num_frames_between(cls, low: int, high: int) -> int:
|
|
922
|
-
if high < low:
|
|
923
|
-
high += cls.MAX_SEQ_NUM
|
|
924
|
-
return high - low
|
|
925
|
-
|
|
926
930
|
def __init__(
|
|
927
931
|
self,
|
|
928
932
|
channel: ClassicChannel,
|
|
@@ -935,6 +939,7 @@ class EnhancedRetransmissionProcessor(Processor):
|
|
|
935
939
|
self.peer_mps = peer_mps
|
|
936
940
|
self.peer_tx_window_size = peer_tx_window_size
|
|
937
941
|
self._pending_pdus = []
|
|
942
|
+
self._tx_window = []
|
|
938
943
|
self.monitor_timeout = spec.monitor_timeout
|
|
939
944
|
self.channel = channel
|
|
940
945
|
self.retransmission_timeout = spec.retransmission_timeout
|
|
@@ -972,12 +977,9 @@ class EnhancedRetransmissionProcessor(Processor):
|
|
|
972
977
|
|
|
973
978
|
def _send_receiver_ready_poll(self) -> None:
|
|
974
979
|
self._num_receiver_ready_polls_sent += 1
|
|
975
|
-
self.
|
|
976
|
-
SupervisoryEnhancedControlField
|
|
977
|
-
|
|
978
|
-
final=1,
|
|
979
|
-
req_seq=self._next_seq_num,
|
|
980
|
-
)
|
|
980
|
+
self._send_s_frame(
|
|
981
|
+
supervision_function=SupervisoryEnhancedControlField.SupervisoryFunction.RR,
|
|
982
|
+
final=1,
|
|
981
983
|
)
|
|
982
984
|
|
|
983
985
|
def _get_next_tx_seq(self) -> int:
|
|
@@ -987,12 +989,35 @@ class EnhancedRetransmissionProcessor(Processor):
|
|
|
987
989
|
|
|
988
990
|
@override
|
|
989
991
|
def send_sdu(self, sdu: bytes) -> None:
|
|
990
|
-
if len(sdu)
|
|
991
|
-
|
|
992
|
-
|
|
992
|
+
if len(sdu) <= self.peer_mps:
|
|
993
|
+
pdu = self._PendingPdu(
|
|
994
|
+
payload=sdu,
|
|
995
|
+
tx_seq=self._get_next_tx_seq(),
|
|
996
|
+
req_seq=self._req_seq_num,
|
|
997
|
+
sar=InformationEnhancedControlField.SegmentationAndReassembly.UNSEGMENTED,
|
|
993
998
|
)
|
|
994
|
-
|
|
995
|
-
|
|
999
|
+
self._pending_pdus.append(pdu)
|
|
1000
|
+
else:
|
|
1001
|
+
for offset in range(0, len(sdu), self.peer_mps):
|
|
1002
|
+
payload = sdu[offset : offset + self.peer_mps]
|
|
1003
|
+
if offset == 0:
|
|
1004
|
+
sar = (
|
|
1005
|
+
InformationEnhancedControlField.SegmentationAndReassembly.START
|
|
1006
|
+
)
|
|
1007
|
+
elif offset + len(payload) >= len(sdu):
|
|
1008
|
+
sar = InformationEnhancedControlField.SegmentationAndReassembly.END
|
|
1009
|
+
else:
|
|
1010
|
+
sar = (
|
|
1011
|
+
InformationEnhancedControlField.SegmentationAndReassembly.CONTINUATION
|
|
1012
|
+
)
|
|
1013
|
+
pdu = self._PendingPdu(
|
|
1014
|
+
payload=payload,
|
|
1015
|
+
tx_seq=self._get_next_tx_seq(),
|
|
1016
|
+
req_seq=self._req_seq_num,
|
|
1017
|
+
sar=sar,
|
|
1018
|
+
sdu_length=len(sdu),
|
|
1019
|
+
)
|
|
1020
|
+
self._pending_pdus.append(pdu)
|
|
996
1021
|
self._process_output()
|
|
997
1022
|
|
|
998
1023
|
@override
|
|
@@ -1000,17 +1025,37 @@ class EnhancedRetransmissionProcessor(Processor):
|
|
|
1000
1025
|
control_field = EnhancedControlField.from_bytes(pdu)
|
|
1001
1026
|
self._update_ack_seq(control_field.req_seq, control_field.final != 0)
|
|
1002
1027
|
if isinstance(control_field, InformationEnhancedControlField):
|
|
1003
|
-
if control_field.tx_seq != self.
|
|
1028
|
+
if control_field.tx_seq != self._req_seq_num:
|
|
1029
|
+
logger.error(
|
|
1030
|
+
"tx_seq != self._req_seq_num, tx_seq: %d, self._req_seq_num: %d",
|
|
1031
|
+
control_field.tx_seq,
|
|
1032
|
+
self._req_seq_num,
|
|
1033
|
+
)
|
|
1004
1034
|
return
|
|
1005
|
-
self.
|
|
1006
|
-
self._req_seq_num = self._next_seq_num
|
|
1035
|
+
self._req_seq_num = (control_field.tx_seq + 1) % self.MAX_SEQ_NUM
|
|
1007
1036
|
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
)
|
|
1012
|
-
|
|
1013
|
-
|
|
1037
|
+
if (
|
|
1038
|
+
control_field.sar
|
|
1039
|
+
== InformationEnhancedControlField.SegmentationAndReassembly.START
|
|
1040
|
+
):
|
|
1041
|
+
# Drop Control Field(2) + SDU Length(2)
|
|
1042
|
+
self._in_sdu += pdu[4:]
|
|
1043
|
+
else:
|
|
1044
|
+
# Drop Control Field(2)
|
|
1045
|
+
self._in_sdu += pdu[2:]
|
|
1046
|
+
if control_field.sar in (
|
|
1047
|
+
InformationEnhancedControlField.SegmentationAndReassembly.END,
|
|
1048
|
+
InformationEnhancedControlField.SegmentationAndReassembly.UNSEGMENTED,
|
|
1049
|
+
):
|
|
1050
|
+
self.channel.on_sdu(self._in_sdu)
|
|
1051
|
+
self._in_sdu = b''
|
|
1052
|
+
|
|
1053
|
+
# If sink doesn't trigger any I-frame, ack this frame.
|
|
1054
|
+
if self._req_seq_num != self._last_acked_rx_seq:
|
|
1055
|
+
self._send_s_frame(
|
|
1056
|
+
supervision_function=SupervisoryEnhancedControlField.SupervisoryFunction.RR,
|
|
1057
|
+
final=0,
|
|
1058
|
+
)
|
|
1014
1059
|
elif isinstance(control_field, SupervisoryEnhancedControlField):
|
|
1015
1060
|
self._remote_is_busy = (
|
|
1016
1061
|
control_field.supervision_function
|
|
@@ -1022,56 +1067,66 @@ class EnhancedRetransmissionProcessor(Processor):
|
|
|
1022
1067
|
SupervisoryEnhancedControlField.SupervisoryFunction.RNR,
|
|
1023
1068
|
):
|
|
1024
1069
|
if control_field.poll:
|
|
1025
|
-
self.
|
|
1026
|
-
SupervisoryEnhancedControlField
|
|
1027
|
-
|
|
1028
|
-
final=1,
|
|
1029
|
-
req_seq=self._next_seq_num,
|
|
1030
|
-
)
|
|
1070
|
+
self._send_s_frame(
|
|
1071
|
+
supervision_function=SupervisoryEnhancedControlField.SupervisoryFunction.RR,
|
|
1072
|
+
final=1,
|
|
1031
1073
|
)
|
|
1032
1074
|
else:
|
|
1033
1075
|
# TODO: Handle Retransmission.
|
|
1034
1076
|
pass
|
|
1035
1077
|
|
|
1036
1078
|
def _process_output(self) -> None:
|
|
1037
|
-
if self._remote_is_busy
|
|
1079
|
+
if self._remote_is_busy:
|
|
1080
|
+
logger.debug("Remote is busy")
|
|
1081
|
+
return
|
|
1082
|
+
if self._monitor_handle:
|
|
1083
|
+
logger.debug("Monitor handle is not None")
|
|
1038
1084
|
return
|
|
1039
1085
|
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
self._last_tx_seq = pdu.tx_seq
|
|
1045
|
-
|
|
1046
|
-
@property
|
|
1047
|
-
def _num_unacked_frames(self) -> int:
|
|
1048
|
-
if not self._pending_pdus:
|
|
1049
|
-
return 0
|
|
1050
|
-
return self._num_frames_between(self._expected_ack_seq, self._last_tx_seq + 1)
|
|
1086
|
+
pdu_to_send = self.peer_tx_window_size - len(self._tx_window)
|
|
1087
|
+
for pdu in itertools.islice(self._pending_pdus, pdu_to_send):
|
|
1088
|
+
self._send_i_frame(pdu)
|
|
1089
|
+
self._pending_pdus = self._pending_pdus[pdu_to_send:]
|
|
1051
1090
|
|
|
1052
|
-
def
|
|
1091
|
+
def _send_i_frame(self, pdu: _PendingPdu) -> None:
|
|
1053
1092
|
pdu.req_seq = self._req_seq_num
|
|
1054
1093
|
|
|
1055
1094
|
self._start_receiver_ready_poll()
|
|
1095
|
+
self._tx_window.append(pdu)
|
|
1056
1096
|
self.channel.send_pdu(bytes(pdu))
|
|
1097
|
+
self._last_acked_rx_seq = self._req_seq_num
|
|
1098
|
+
|
|
1099
|
+
def _send_s_frame(
|
|
1100
|
+
self,
|
|
1101
|
+
supervision_function: SupervisoryEnhancedControlField.SupervisoryFunction,
|
|
1102
|
+
final: int,
|
|
1103
|
+
) -> None:
|
|
1104
|
+
self.channel.send_pdu(
|
|
1105
|
+
SupervisoryEnhancedControlField(
|
|
1106
|
+
supervision_function=supervision_function,
|
|
1107
|
+
final=final,
|
|
1108
|
+
req_seq=self._req_seq_num,
|
|
1109
|
+
)
|
|
1110
|
+
)
|
|
1111
|
+
self._last_acked_rx_seq = self._req_seq_num
|
|
1057
1112
|
|
|
1058
1113
|
def _update_ack_seq(self, new_seq: int, is_poll_response: bool) -> None:
|
|
1059
|
-
num_frames_acked = self.
|
|
1060
|
-
if num_frames_acked > self.
|
|
1114
|
+
num_frames_acked = (new_seq - self._last_acked_tx_seq) % self.MAX_SEQ_NUM
|
|
1115
|
+
if num_frames_acked > len(self._tx_window):
|
|
1061
1116
|
logger.error(
|
|
1062
1117
|
"Received acknowledgment for %d frames but only %d frames are pending",
|
|
1063
1118
|
num_frames_acked,
|
|
1064
|
-
self.
|
|
1119
|
+
len(self._tx_window),
|
|
1065
1120
|
)
|
|
1066
1121
|
return
|
|
1067
1122
|
if is_poll_response and self._monitor_handle:
|
|
1068
1123
|
self._monitor_handle.cancel()
|
|
1069
1124
|
self._monitor_handle = None
|
|
1070
1125
|
|
|
1071
|
-
del self.
|
|
1072
|
-
self.
|
|
1126
|
+
del self._tx_window[:num_frames_acked]
|
|
1127
|
+
self._last_acked_tx_seq = new_seq
|
|
1073
1128
|
if (
|
|
1074
|
-
self.
|
|
1129
|
+
self._last_acked_tx_seq == self._next_tx_seq
|
|
1075
1130
|
and self._receiver_ready_poll_handle
|
|
1076
1131
|
):
|
|
1077
1132
|
self._receiver_ready_poll_handle.cancel()
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
bumble/__init__.py,sha256=Q8jkz6rgl95IMAeInQVt_2GLoJl3DcEP2cxtrQ-ho5c,110
|
|
2
|
-
bumble/_version.py,sha256=
|
|
2
|
+
bumble/_version.py,sha256=iCVPnXJk250i-zuGezYSSco90VVqd3Imnx_2NCDTb8M,708
|
|
3
3
|
bumble/a2dp.py,sha256=4eFKYOXkl10TRAJqVw4no6aCilYHdmgtd2ZMNY0yNQo,33436
|
|
4
4
|
bumble/at.py,sha256=xtboorCqSdRDoIfRFOIhvV5x2cgXaYqKk5FSMNzuYPo,3062
|
|
5
5
|
bumble/att.py,sha256=H-6zsJhM59KH7iuDZ3mksHXKdywPlng-AwSSd9SHLZE,36039
|
|
@@ -27,7 +27,7 @@ bumble/hfp.py,sha256=OwANwtXWBU3cwAnZ6oODvI0reZfKwCuG0DLI18mevr0,76696
|
|
|
27
27
|
bumble/hid.py,sha256=dEFUN22YYjVcf7h6bdXsjWK8xUp6kDT6ffuDr9zSq-I,21031
|
|
28
28
|
bumble/host.py,sha256=2W_BFI3q7ZBoL231Ii6oEuBDxcbV2phA9vDpk9ZKZ-Q,67833
|
|
29
29
|
bumble/keys.py,sha256=iioiJZkqCoK2qopjDLLM0aeSy9l4bBrSyHfit4tNJek,13356
|
|
30
|
-
bumble/l2cap.py,sha256=
|
|
30
|
+
bumble/l2cap.py,sha256=DluqPOWcG0vuw4H6fU1PWHDg6a1d8U9NCkHkU_bouEE,111741
|
|
31
31
|
bumble/link.py,sha256=3dvwLyUlkfUPHsOthdOvl9wytToQqVweLmXWlub7Z34,5403
|
|
32
32
|
bumble/ll.py,sha256=EH3OIM-6KL1Q22bqa6G1x-SgFqHOqc3_8nVj66RII0Q,5380
|
|
33
33
|
bumble/lmp.py,sha256=9TsV8W1lbudCEytzhWg0N492xFbNEWy1-a3VuF1US-k,10433
|
|
@@ -177,9 +177,9 @@ bumble/vendor/android/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3h
|
|
|
177
177
|
bumble/vendor/android/hci.py,sha256=Fk1SQVhhdoMGg65TIBX7C3FcgqqKfJ3ulMb5n2jfvkc,10457
|
|
178
178
|
bumble/vendor/zephyr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
179
179
|
bumble/vendor/zephyr/hci.py,sha256=ysct40uIVohaKKLrWjcWo-7YqozU17xGia2dWeHoMoI,3435
|
|
180
|
-
bumble-0.0.
|
|
181
|
-
bumble-0.0.
|
|
182
|
-
bumble-0.0.
|
|
183
|
-
bumble-0.0.
|
|
184
|
-
bumble-0.0.
|
|
185
|
-
bumble-0.0.
|
|
180
|
+
bumble-0.0.222.dist-info/licenses/LICENSE,sha256=FvaYh4NRWIGgS_OwoBs5gFgkCmAghZ-DYnIGBZPuw-s,12142
|
|
181
|
+
bumble-0.0.222.dist-info/METADATA,sha256=jd7Hsfxcgz2mNZH-dMImjU_S5x4ohYLW9pIBY256RfA,6218
|
|
182
|
+
bumble-0.0.222.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
183
|
+
bumble-0.0.222.dist-info/entry_points.txt,sha256=mX5dzixNMRo4CTAEQqiYTr-JIaWF62TYrRvJOstjjL8,1081
|
|
184
|
+
bumble-0.0.222.dist-info/top_level.txt,sha256=tV6JJKaHPYMFiJYiBYFW24PCcfLxTJZdlu6BmH3Cb00,7
|
|
185
|
+
bumble-0.0.222.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|