bumble 0.0.159__py3-none-any.whl → 0.0.161__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/controller.py +73 -55
- bumble/core.py +74 -3
- bumble/device.py +30 -22
- bumble/gatt.py +23 -22
- bumble/l2cap.py +210 -122
- bumble/smp.py +105 -71
- {bumble-0.0.159.dist-info → bumble-0.0.161.dist-info}/METADATA +1 -1
- {bumble-0.0.159.dist-info → bumble-0.0.161.dist-info}/RECORD +13 -13
- {bumble-0.0.159.dist-info → bumble-0.0.161.dist-info}/WHEEL +1 -1
- {bumble-0.0.159.dist-info → bumble-0.0.161.dist-info}/LICENSE +0 -0
- {bumble-0.0.159.dist-info → bumble-0.0.161.dist-info}/entry_points.txt +0 -0
- {bumble-0.0.159.dist-info → bumble-0.0.161.dist-info}/top_level.txt +0 -0
bumble/smp.py
CHANGED
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
from __future__ import annotations
|
|
26
26
|
import logging
|
|
27
27
|
import asyncio
|
|
28
|
+
import enum
|
|
28
29
|
import secrets
|
|
29
30
|
from typing import (
|
|
30
31
|
TYPE_CHECKING,
|
|
@@ -553,20 +554,16 @@ class AddressResolver:
|
|
|
553
554
|
|
|
554
555
|
|
|
555
556
|
# -----------------------------------------------------------------------------
|
|
556
|
-
class
|
|
557
|
-
# Pairing methods
|
|
557
|
+
class PairingMethod(enum.IntEnum):
|
|
558
558
|
JUST_WORKS = 0
|
|
559
559
|
NUMERIC_COMPARISON = 1
|
|
560
560
|
PASSKEY = 2
|
|
561
561
|
OOB = 3
|
|
562
|
+
CTKD_OVER_CLASSIC = 4
|
|
562
563
|
|
|
563
|
-
PAIRING_METHOD_NAMES = {
|
|
564
|
-
JUST_WORKS: 'JUST_WORKS',
|
|
565
|
-
NUMERIC_COMPARISON: 'NUMERIC_COMPARISON',
|
|
566
|
-
PASSKEY: 'PASSKEY',
|
|
567
|
-
OOB: 'OOB',
|
|
568
|
-
}
|
|
569
564
|
|
|
565
|
+
# -----------------------------------------------------------------------------
|
|
566
|
+
class Session:
|
|
570
567
|
# I/O Capability to pairing method decision matrix
|
|
571
568
|
#
|
|
572
569
|
# See Bluetooth spec @ Vol 3, part H - Table 2.8: Mapping of IO Capabilities to Key
|
|
@@ -581,47 +578,50 @@ class Session:
|
|
|
581
578
|
# (False).
|
|
582
579
|
PAIRING_METHODS = {
|
|
583
580
|
SMP_DISPLAY_ONLY_IO_CAPABILITY: {
|
|
584
|
-
SMP_DISPLAY_ONLY_IO_CAPABILITY: JUST_WORKS,
|
|
585
|
-
SMP_DISPLAY_YES_NO_IO_CAPABILITY: JUST_WORKS,
|
|
586
|
-
SMP_KEYBOARD_ONLY_IO_CAPABILITY: (PASSKEY, True, False),
|
|
587
|
-
SMP_NO_INPUT_NO_OUTPUT_IO_CAPABILITY: JUST_WORKS,
|
|
588
|
-
SMP_KEYBOARD_DISPLAY_IO_CAPABILITY: (PASSKEY, True, False),
|
|
581
|
+
SMP_DISPLAY_ONLY_IO_CAPABILITY: PairingMethod.JUST_WORKS,
|
|
582
|
+
SMP_DISPLAY_YES_NO_IO_CAPABILITY: PairingMethod.JUST_WORKS,
|
|
583
|
+
SMP_KEYBOARD_ONLY_IO_CAPABILITY: (PairingMethod.PASSKEY, True, False),
|
|
584
|
+
SMP_NO_INPUT_NO_OUTPUT_IO_CAPABILITY: PairingMethod.JUST_WORKS,
|
|
585
|
+
SMP_KEYBOARD_DISPLAY_IO_CAPABILITY: (PairingMethod.PASSKEY, True, False),
|
|
589
586
|
},
|
|
590
587
|
SMP_DISPLAY_YES_NO_IO_CAPABILITY: {
|
|
591
|
-
SMP_DISPLAY_ONLY_IO_CAPABILITY: JUST_WORKS,
|
|
592
|
-
SMP_DISPLAY_YES_NO_IO_CAPABILITY: (
|
|
593
|
-
|
|
594
|
-
|
|
588
|
+
SMP_DISPLAY_ONLY_IO_CAPABILITY: PairingMethod.JUST_WORKS,
|
|
589
|
+
SMP_DISPLAY_YES_NO_IO_CAPABILITY: (
|
|
590
|
+
PairingMethod.JUST_WORKS,
|
|
591
|
+
PairingMethod.NUMERIC_COMPARISON,
|
|
592
|
+
),
|
|
593
|
+
SMP_KEYBOARD_ONLY_IO_CAPABILITY: (PairingMethod.PASSKEY, True, False),
|
|
594
|
+
SMP_NO_INPUT_NO_OUTPUT_IO_CAPABILITY: PairingMethod.JUST_WORKS,
|
|
595
595
|
SMP_KEYBOARD_DISPLAY_IO_CAPABILITY: (
|
|
596
|
-
(PASSKEY, True, False),
|
|
597
|
-
NUMERIC_COMPARISON,
|
|
596
|
+
(PairingMethod.PASSKEY, True, False),
|
|
597
|
+
PairingMethod.NUMERIC_COMPARISON,
|
|
598
598
|
),
|
|
599
599
|
},
|
|
600
600
|
SMP_KEYBOARD_ONLY_IO_CAPABILITY: {
|
|
601
|
-
SMP_DISPLAY_ONLY_IO_CAPABILITY: (PASSKEY, False, True),
|
|
602
|
-
SMP_DISPLAY_YES_NO_IO_CAPABILITY: (PASSKEY, False, True),
|
|
603
|
-
SMP_KEYBOARD_ONLY_IO_CAPABILITY: (PASSKEY, False, False),
|
|
604
|
-
SMP_NO_INPUT_NO_OUTPUT_IO_CAPABILITY: JUST_WORKS,
|
|
605
|
-
SMP_KEYBOARD_DISPLAY_IO_CAPABILITY: (PASSKEY, False, True),
|
|
601
|
+
SMP_DISPLAY_ONLY_IO_CAPABILITY: (PairingMethod.PASSKEY, False, True),
|
|
602
|
+
SMP_DISPLAY_YES_NO_IO_CAPABILITY: (PairingMethod.PASSKEY, False, True),
|
|
603
|
+
SMP_KEYBOARD_ONLY_IO_CAPABILITY: (PairingMethod.PASSKEY, False, False),
|
|
604
|
+
SMP_NO_INPUT_NO_OUTPUT_IO_CAPABILITY: PairingMethod.JUST_WORKS,
|
|
605
|
+
SMP_KEYBOARD_DISPLAY_IO_CAPABILITY: (PairingMethod.PASSKEY, False, True),
|
|
606
606
|
},
|
|
607
607
|
SMP_NO_INPUT_NO_OUTPUT_IO_CAPABILITY: {
|
|
608
|
-
SMP_DISPLAY_ONLY_IO_CAPABILITY: JUST_WORKS,
|
|
609
|
-
SMP_DISPLAY_YES_NO_IO_CAPABILITY: JUST_WORKS,
|
|
610
|
-
SMP_KEYBOARD_ONLY_IO_CAPABILITY: JUST_WORKS,
|
|
611
|
-
SMP_NO_INPUT_NO_OUTPUT_IO_CAPABILITY: JUST_WORKS,
|
|
612
|
-
SMP_KEYBOARD_DISPLAY_IO_CAPABILITY: JUST_WORKS,
|
|
608
|
+
SMP_DISPLAY_ONLY_IO_CAPABILITY: PairingMethod.JUST_WORKS,
|
|
609
|
+
SMP_DISPLAY_YES_NO_IO_CAPABILITY: PairingMethod.JUST_WORKS,
|
|
610
|
+
SMP_KEYBOARD_ONLY_IO_CAPABILITY: PairingMethod.JUST_WORKS,
|
|
611
|
+
SMP_NO_INPUT_NO_OUTPUT_IO_CAPABILITY: PairingMethod.JUST_WORKS,
|
|
612
|
+
SMP_KEYBOARD_DISPLAY_IO_CAPABILITY: PairingMethod.JUST_WORKS,
|
|
613
613
|
},
|
|
614
614
|
SMP_KEYBOARD_DISPLAY_IO_CAPABILITY: {
|
|
615
|
-
SMP_DISPLAY_ONLY_IO_CAPABILITY: (PASSKEY, False, True),
|
|
615
|
+
SMP_DISPLAY_ONLY_IO_CAPABILITY: (PairingMethod.PASSKEY, False, True),
|
|
616
616
|
SMP_DISPLAY_YES_NO_IO_CAPABILITY: (
|
|
617
|
-
(PASSKEY, False, True),
|
|
618
|
-
NUMERIC_COMPARISON,
|
|
617
|
+
(PairingMethod.PASSKEY, False, True),
|
|
618
|
+
PairingMethod.NUMERIC_COMPARISON,
|
|
619
619
|
),
|
|
620
|
-
SMP_KEYBOARD_ONLY_IO_CAPABILITY: (PASSKEY, True, False),
|
|
621
|
-
SMP_NO_INPUT_NO_OUTPUT_IO_CAPABILITY: JUST_WORKS,
|
|
620
|
+
SMP_KEYBOARD_ONLY_IO_CAPABILITY: (PairingMethod.PASSKEY, True, False),
|
|
621
|
+
SMP_NO_INPUT_NO_OUTPUT_IO_CAPABILITY: PairingMethod.JUST_WORKS,
|
|
622
622
|
SMP_KEYBOARD_DISPLAY_IO_CAPABILITY: (
|
|
623
|
-
(PASSKEY, True, False),
|
|
624
|
-
NUMERIC_COMPARISON,
|
|
623
|
+
(PairingMethod.PASSKEY, True, False),
|
|
624
|
+
PairingMethod.NUMERIC_COMPARISON,
|
|
625
625
|
),
|
|
626
626
|
},
|
|
627
627
|
}
|
|
@@ -664,7 +664,7 @@ class Session:
|
|
|
664
664
|
self.passkey_ready = asyncio.Event()
|
|
665
665
|
self.passkey_step = 0
|
|
666
666
|
self.passkey_display = False
|
|
667
|
-
self.pairing_method =
|
|
667
|
+
self.pairing_method: PairingMethod = PairingMethod.JUST_WORKS
|
|
668
668
|
self.pairing_config = pairing_config
|
|
669
669
|
self.wait_before_continuing: Optional[asyncio.Future[None]] = None
|
|
670
670
|
self.completed = False
|
|
@@ -769,19 +769,23 @@ class Session:
|
|
|
769
769
|
def decide_pairing_method(
|
|
770
770
|
self, auth_req: int, initiator_io_capability: int, responder_io_capability: int
|
|
771
771
|
) -> None:
|
|
772
|
+
if self.connection.transport == BT_BR_EDR_TRANSPORT:
|
|
773
|
+
self.pairing_method = PairingMethod.CTKD_OVER_CLASSIC
|
|
774
|
+
return
|
|
772
775
|
if (not self.mitm) and (auth_req & SMP_MITM_AUTHREQ == 0):
|
|
773
|
-
self.pairing_method =
|
|
776
|
+
self.pairing_method = PairingMethod.JUST_WORKS
|
|
774
777
|
return
|
|
775
778
|
|
|
776
779
|
details = self.PAIRING_METHODS[initiator_io_capability][responder_io_capability] # type: ignore[index]
|
|
777
780
|
if isinstance(details, tuple) and len(details) == 2:
|
|
778
781
|
# One entry for legacy pairing and one for secure connections
|
|
779
782
|
details = details[1 if self.sc else 0]
|
|
780
|
-
if isinstance(details,
|
|
783
|
+
if isinstance(details, PairingMethod):
|
|
781
784
|
# Just a method ID
|
|
782
785
|
self.pairing_method = details
|
|
783
786
|
else:
|
|
784
787
|
# PASSKEY method, with a method ID and display/input flags
|
|
788
|
+
assert isinstance(details[0], PairingMethod)
|
|
785
789
|
self.pairing_method = details[0]
|
|
786
790
|
self.passkey_display = details[1 if self.is_initiator else 2]
|
|
787
791
|
|
|
@@ -858,10 +862,13 @@ class Session:
|
|
|
858
862
|
self.tk = self.passkey.to_bytes(16, byteorder='little')
|
|
859
863
|
logger.debug(f'TK from passkey = {self.tk.hex()}')
|
|
860
864
|
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
+
try:
|
|
866
|
+
self.connection.abort_on(
|
|
867
|
+
'disconnection',
|
|
868
|
+
self.pairing_config.delegate.display_number(self.passkey, digits=6),
|
|
869
|
+
)
|
|
870
|
+
except Exception as error:
|
|
871
|
+
logger.warning(f'exception while displaying number: {error}')
|
|
865
872
|
|
|
866
873
|
def input_passkey(self, next_steps: Optional[Callable[[], None]] = None) -> None:
|
|
867
874
|
# Prompt the user for the passkey displayed on the peer
|
|
@@ -929,9 +936,12 @@ class Session:
|
|
|
929
936
|
if self.sc:
|
|
930
937
|
|
|
931
938
|
async def next_steps() -> None:
|
|
932
|
-
if self.pairing_method in (
|
|
939
|
+
if self.pairing_method in (
|
|
940
|
+
PairingMethod.JUST_WORKS,
|
|
941
|
+
PairingMethod.NUMERIC_COMPARISON,
|
|
942
|
+
):
|
|
933
943
|
z = 0
|
|
934
|
-
elif self.pairing_method ==
|
|
944
|
+
elif self.pairing_method == PairingMethod.PASSKEY:
|
|
935
945
|
# We need a passkey
|
|
936
946
|
await self.passkey_ready.wait()
|
|
937
947
|
assert self.passkey
|
|
@@ -1224,7 +1234,7 @@ class Session:
|
|
|
1224
1234
|
# Create an object to hold the keys
|
|
1225
1235
|
keys = PairingKeys()
|
|
1226
1236
|
keys.address_type = peer_address.address_type
|
|
1227
|
-
authenticated = self.pairing_method !=
|
|
1237
|
+
authenticated = self.pairing_method != PairingMethod.JUST_WORKS
|
|
1228
1238
|
if self.sc or self.connection.transport == BT_BR_EDR_TRANSPORT:
|
|
1229
1239
|
keys.ltk = PairingKeys.Key(value=self.ltk, authenticated=authenticated)
|
|
1230
1240
|
else:
|
|
@@ -1300,7 +1310,11 @@ class Session:
|
|
|
1300
1310
|
self, command: SMP_Pairing_Request_Command
|
|
1301
1311
|
) -> None:
|
|
1302
1312
|
# Check if the request should proceed
|
|
1303
|
-
|
|
1313
|
+
try:
|
|
1314
|
+
accepted = await self.pairing_config.delegate.accept()
|
|
1315
|
+
except Exception as error:
|
|
1316
|
+
logger.warning(f'exception while accepting: {error}')
|
|
1317
|
+
accepted = False
|
|
1304
1318
|
if not accepted:
|
|
1305
1319
|
logger.debug('pairing rejected by delegate')
|
|
1306
1320
|
self.send_pairing_failed(SMP_PAIRING_NOT_SUPPORTED_ERROR)
|
|
@@ -1323,9 +1337,7 @@ class Session:
|
|
|
1323
1337
|
self.decide_pairing_method(
|
|
1324
1338
|
command.auth_req, command.io_capability, self.io_capability
|
|
1325
1339
|
)
|
|
1326
|
-
logger.debug(
|
|
1327
|
-
f'pairing method: {self.PAIRING_METHOD_NAMES[self.pairing_method]}'
|
|
1328
|
-
)
|
|
1340
|
+
logger.debug(f'pairing method: {self.pairing_method.name}')
|
|
1329
1341
|
|
|
1330
1342
|
# Key distribution
|
|
1331
1343
|
(
|
|
@@ -1341,7 +1353,7 @@ class Session:
|
|
|
1341
1353
|
|
|
1342
1354
|
# Display a passkey if we need to
|
|
1343
1355
|
if not self.sc:
|
|
1344
|
-
if self.pairing_method ==
|
|
1356
|
+
if self.pairing_method == PairingMethod.PASSKEY and self.passkey_display:
|
|
1345
1357
|
self.display_passkey()
|
|
1346
1358
|
|
|
1347
1359
|
# Respond
|
|
@@ -1382,9 +1394,7 @@ class Session:
|
|
|
1382
1394
|
self.decide_pairing_method(
|
|
1383
1395
|
command.auth_req, self.io_capability, command.io_capability
|
|
1384
1396
|
)
|
|
1385
|
-
logger.debug(
|
|
1386
|
-
f'pairing method: {self.PAIRING_METHOD_NAMES[self.pairing_method]}'
|
|
1387
|
-
)
|
|
1397
|
+
logger.debug(f'pairing method: {self.pairing_method.name}')
|
|
1388
1398
|
|
|
1389
1399
|
# Key distribution
|
|
1390
1400
|
if (
|
|
@@ -1400,13 +1410,16 @@ class Session:
|
|
|
1400
1410
|
self.compute_peer_expected_distributions(self.responder_key_distribution)
|
|
1401
1411
|
|
|
1402
1412
|
# Start phase 2
|
|
1403
|
-
if self.
|
|
1404
|
-
|
|
1413
|
+
if self.pairing_method == PairingMethod.CTKD_OVER_CLASSIC:
|
|
1414
|
+
# Authentication is already done in SMP, so remote shall start keys distribution immediately
|
|
1415
|
+
return
|
|
1416
|
+
elif self.sc:
|
|
1417
|
+
if self.pairing_method == PairingMethod.PASSKEY:
|
|
1405
1418
|
self.display_or_input_passkey()
|
|
1406
1419
|
|
|
1407
1420
|
self.send_public_key_command()
|
|
1408
1421
|
else:
|
|
1409
|
-
if self.pairing_method ==
|
|
1422
|
+
if self.pairing_method == PairingMethod.PASSKEY:
|
|
1410
1423
|
self.display_or_input_passkey(self.send_pairing_confirm_command)
|
|
1411
1424
|
else:
|
|
1412
1425
|
self.send_pairing_confirm_command()
|
|
@@ -1418,7 +1431,10 @@ class Session:
|
|
|
1418
1431
|
self.send_pairing_random_command()
|
|
1419
1432
|
else:
|
|
1420
1433
|
# If the method is PASSKEY, now is the time to input the code
|
|
1421
|
-
if
|
|
1434
|
+
if (
|
|
1435
|
+
self.pairing_method == PairingMethod.PASSKEY
|
|
1436
|
+
and not self.passkey_display
|
|
1437
|
+
):
|
|
1422
1438
|
self.input_passkey(self.send_pairing_confirm_command)
|
|
1423
1439
|
else:
|
|
1424
1440
|
self.send_pairing_confirm_command()
|
|
@@ -1426,11 +1442,14 @@ class Session:
|
|
|
1426
1442
|
def on_smp_pairing_confirm_command_secure_connections(
|
|
1427
1443
|
self, _: SMP_Pairing_Confirm_Command
|
|
1428
1444
|
) -> None:
|
|
1429
|
-
if self.pairing_method in (
|
|
1445
|
+
if self.pairing_method in (
|
|
1446
|
+
PairingMethod.JUST_WORKS,
|
|
1447
|
+
PairingMethod.NUMERIC_COMPARISON,
|
|
1448
|
+
):
|
|
1430
1449
|
if self.is_initiator:
|
|
1431
1450
|
self.r = crypto.r()
|
|
1432
1451
|
self.send_pairing_random_command()
|
|
1433
|
-
elif self.pairing_method ==
|
|
1452
|
+
elif self.pairing_method == PairingMethod.PASSKEY:
|
|
1434
1453
|
if self.is_initiator:
|
|
1435
1454
|
self.send_pairing_random_command()
|
|
1436
1455
|
else:
|
|
@@ -1486,13 +1505,16 @@ class Session:
|
|
|
1486
1505
|
def on_smp_pairing_random_command_secure_connections(
|
|
1487
1506
|
self, command: SMP_Pairing_Random_Command
|
|
1488
1507
|
) -> None:
|
|
1489
|
-
if self.pairing_method ==
|
|
1508
|
+
if self.pairing_method == PairingMethod.PASSKEY and self.passkey is None:
|
|
1490
1509
|
logger.warning('no passkey entered, ignoring command')
|
|
1491
1510
|
return
|
|
1492
1511
|
|
|
1493
1512
|
# pylint: disable=too-many-return-statements
|
|
1494
1513
|
if self.is_initiator:
|
|
1495
|
-
if self.pairing_method in (
|
|
1514
|
+
if self.pairing_method in (
|
|
1515
|
+
PairingMethod.JUST_WORKS,
|
|
1516
|
+
PairingMethod.NUMERIC_COMPARISON,
|
|
1517
|
+
):
|
|
1496
1518
|
assert self.confirm_value
|
|
1497
1519
|
# Check that the random value matches what was committed to earlier
|
|
1498
1520
|
confirm_verifier = crypto.f4(
|
|
@@ -1502,7 +1524,7 @@ class Session:
|
|
|
1502
1524
|
self.confirm_value, confirm_verifier, SMP_CONFIRM_VALUE_FAILED_ERROR
|
|
1503
1525
|
):
|
|
1504
1526
|
return
|
|
1505
|
-
elif self.pairing_method ==
|
|
1527
|
+
elif self.pairing_method == PairingMethod.PASSKEY:
|
|
1506
1528
|
assert self.passkey and self.confirm_value
|
|
1507
1529
|
# Check that the random value matches what was committed to earlier
|
|
1508
1530
|
confirm_verifier = crypto.f4(
|
|
@@ -1525,9 +1547,12 @@ class Session:
|
|
|
1525
1547
|
else:
|
|
1526
1548
|
return
|
|
1527
1549
|
else:
|
|
1528
|
-
if self.pairing_method in (
|
|
1550
|
+
if self.pairing_method in (
|
|
1551
|
+
PairingMethod.JUST_WORKS,
|
|
1552
|
+
PairingMethod.NUMERIC_COMPARISON,
|
|
1553
|
+
):
|
|
1529
1554
|
self.send_pairing_random_command()
|
|
1530
|
-
elif self.pairing_method ==
|
|
1555
|
+
elif self.pairing_method == PairingMethod.PASSKEY:
|
|
1531
1556
|
assert self.passkey and self.confirm_value
|
|
1532
1557
|
# Check that the random value matches what was committed to earlier
|
|
1533
1558
|
confirm_verifier = crypto.f4(
|
|
@@ -1558,10 +1583,13 @@ class Session:
|
|
|
1558
1583
|
(mac_key, self.ltk) = crypto.f5(self.dh_key, self.na, self.nb, a, b)
|
|
1559
1584
|
|
|
1560
1585
|
# Compute the DH Key checks
|
|
1561
|
-
if self.pairing_method in (
|
|
1586
|
+
if self.pairing_method in (
|
|
1587
|
+
PairingMethod.JUST_WORKS,
|
|
1588
|
+
PairingMethod.NUMERIC_COMPARISON,
|
|
1589
|
+
):
|
|
1562
1590
|
ra = bytes(16)
|
|
1563
1591
|
rb = ra
|
|
1564
|
-
elif self.pairing_method ==
|
|
1592
|
+
elif self.pairing_method == PairingMethod.PASSKEY:
|
|
1565
1593
|
assert self.passkey
|
|
1566
1594
|
ra = self.passkey.to_bytes(16, byteorder='little')
|
|
1567
1595
|
rb = ra
|
|
@@ -1585,13 +1613,16 @@ class Session:
|
|
|
1585
1613
|
self.wait_before_continuing.set_result(None)
|
|
1586
1614
|
|
|
1587
1615
|
# Prompt the user for confirmation if needed
|
|
1588
|
-
if self.pairing_method in (
|
|
1616
|
+
if self.pairing_method in (
|
|
1617
|
+
PairingMethod.JUST_WORKS,
|
|
1618
|
+
PairingMethod.NUMERIC_COMPARISON,
|
|
1619
|
+
):
|
|
1589
1620
|
# Compute the 6-digit code
|
|
1590
1621
|
code = crypto.g2(self.pka, self.pkb, self.na, self.nb) % 1000000
|
|
1591
1622
|
|
|
1592
1623
|
# Ask for user confirmation
|
|
1593
1624
|
self.wait_before_continuing = asyncio.get_running_loop().create_future()
|
|
1594
|
-
if self.pairing_method ==
|
|
1625
|
+
if self.pairing_method == PairingMethod.JUST_WORKS:
|
|
1595
1626
|
self.prompt_user_for_confirmation(next_steps)
|
|
1596
1627
|
else:
|
|
1597
1628
|
self.prompt_user_for_numeric_comparison(code, next_steps)
|
|
@@ -1628,13 +1659,16 @@ class Session:
|
|
|
1628
1659
|
if self.is_initiator:
|
|
1629
1660
|
self.send_pairing_confirm_command()
|
|
1630
1661
|
else:
|
|
1631
|
-
if self.pairing_method ==
|
|
1662
|
+
if self.pairing_method == PairingMethod.PASSKEY:
|
|
1632
1663
|
self.display_or_input_passkey()
|
|
1633
1664
|
|
|
1634
1665
|
# Send our public key back to the initiator
|
|
1635
1666
|
self.send_public_key_command()
|
|
1636
1667
|
|
|
1637
|
-
if self.pairing_method in (
|
|
1668
|
+
if self.pairing_method in (
|
|
1669
|
+
PairingMethod.JUST_WORKS,
|
|
1670
|
+
PairingMethod.NUMERIC_COMPARISON,
|
|
1671
|
+
):
|
|
1638
1672
|
# We can now send the confirmation value
|
|
1639
1673
|
self.send_pairing_confirm_command()
|
|
1640
1674
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
bumble/__init__.py,sha256=Q8jkz6rgl95IMAeInQVt_2GLoJl3DcEP2cxtrQ-ho5c,110
|
|
2
|
-
bumble/_version.py,sha256=
|
|
2
|
+
bumble/_version.py,sha256=z2uj4v0zOw20JF0drVkUjMouxtJipeDu3RBasPE26ks,164
|
|
3
3
|
bumble/a2dp.py,sha256=vwnKknvSKPR7IdTz8JHHNvHGObjepVy1kFRWm0kNWEI,21923
|
|
4
4
|
bumble/att.py,sha256=qXwC5gtC-4Bwjqul0sCm_bWA_BbK4NVf5xNlOCRE7LI,30231
|
|
5
5
|
bumble/avdtp.py,sha256=sT0mFeFvp9jTEP-dOp4_ibdtKX3mtw1Gyi-72tHfkiE,72268
|
|
@@ -7,13 +7,13 @@ bumble/bridge.py,sha256=T6es5oS1dy8QgkxQ8iOD-YcZ0SWOv8jaqC7TGxqodk4,3003
|
|
|
7
7
|
bumble/codecs.py,sha256=Vc7FOo6d-6VCgDI0ibnLmX8vCZ4-jtX_-0vEUM-yOrI,15343
|
|
8
8
|
bumble/colors.py,sha256=9H-qzGgMr-YoWdIFpcGPaiRvTvkCzz7FPIkpwqKyKug,3033
|
|
9
9
|
bumble/company_ids.py,sha256=mHmG9mk_0lkjiRm-IMggDnuXzY2QlZzH9jugy_ijhDc,95931
|
|
10
|
-
bumble/controller.py,sha256=
|
|
11
|
-
bumble/core.py,sha256=
|
|
10
|
+
bumble/controller.py,sha256=AaRNjz8-1UYH3HgSIVdBvLLwHOLNbxj5J9ScG518PE0,44940
|
|
11
|
+
bumble/core.py,sha256=5gvUyF8aJKg2T_8QPVGiv6wtP-zsWJZ6w89UTGKQHrQ,52293
|
|
12
12
|
bumble/crypto.py,sha256=JX3wg6kd-aFMxkxJz2FYFvyXHOukD-z0QcGH9jpEYvk,8679
|
|
13
13
|
bumble/decoder.py,sha256=N9nMvuVhuwpnfw7EDVuNe9uYY6B6c3RY2dh8RhRPC1U,9608
|
|
14
|
-
bumble/device.py,sha256=
|
|
14
|
+
bumble/device.py,sha256=UPusLfD-sb3wpeDXTHMVS-MqoFRF39tKtCWLLfHfFOc,122493
|
|
15
15
|
bumble/gap.py,sha256=axlOZIv99357Ehq2vMokeioU85z81qdQvplGn0pF70Q,2137
|
|
16
|
-
bumble/gatt.py,sha256=
|
|
16
|
+
bumble/gatt.py,sha256=HwjxuFjuH0LvRyP4HUfslPd-qZ0P17e5Xx8E9usehz0,28295
|
|
17
17
|
bumble/gatt_client.py,sha256=0NrwW7Y3oy1HUWisIyBLwnBpYNnuI9jtbcNkS6CD__U,40297
|
|
18
18
|
bumble/gatt_server.py,sha256=vi_-sofp5NjPWDYX5K_hldsAaoFuNlt8GFA-eVzFkb8,35277
|
|
19
19
|
bumble/hci.py,sha256=7WleGG4Mp80qFGPGoRxUDP2qs6mpRRAWywkgTHJkPHM,217086
|
|
@@ -21,13 +21,13 @@ bumble/helpers.py,sha256=AgtOigAqQzzTEMMwHQJ2EO7dOTp77qhnyfHQ2LCDd-k,8896
|
|
|
21
21
|
bumble/hfp.py,sha256=BQEuh7A9WkP2V-YuuveuI5W-k1-O1Ovq2DvRao_2psk,3434
|
|
22
22
|
bumble/host.py,sha256=BzxDA4crNZrj0u0Gm_hW-uanXn6mFwjRVWKdfd4jrvw,34574
|
|
23
23
|
bumble/keys.py,sha256=_ibaJ4CxM5zyxnTp7wnihIQSsEAEkCiPxx9qHsGA04Q,12601
|
|
24
|
-
bumble/l2cap.py,sha256=
|
|
24
|
+
bumble/l2cap.py,sha256=lk8hNofT04uTiPZ169zgipHWxnq48bz3VcGs3t4CfWE,75417
|
|
25
25
|
bumble/link.py,sha256=dvb3fdmV8689A4rLhFVHHKMR3u4wQbUapFi-GeheK0M,20220
|
|
26
26
|
bumble/pairing.py,sha256=smMCrWdgtdLXKJ_Ix9e5x1SuvSs_49mKtwzJS94ygd4,7002
|
|
27
27
|
bumble/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
28
28
|
bumble/rfcomm.py,sha256=LgcHvRelcToJy3PiPedqkrj4CRZjCg2zFVba-hTkZCY,31632
|
|
29
29
|
bumble/sdp.py,sha256=h0DyXOYpQ5OLzwVZsE4b5YZq_jxxu7m_QSbFkaPy9mQ,42464
|
|
30
|
-
bumble/smp.py,sha256=
|
|
30
|
+
bumble/smp.py,sha256=kh8CA9wnyNT4kqz4Rt9_K6xqFeWDd7POdp4karCKsdU,70430
|
|
31
31
|
bumble/snoop.py,sha256=_QfF36eylBW6Snd-_KYOwKaGiM8i_Ed-B5XoFIPt3Dg,5631
|
|
32
32
|
bumble/utils.py,sha256=x7AKW6QD35Dl1OkROLJ6TX4dNN6ajwFjW8w_BZGGcA4,10195
|
|
33
33
|
bumble/apps/README.md,sha256=XTwjRAY-EJWDXpl1V8K3Mw8B7kIqzUIUizRjVBVhoIE,1769
|
|
@@ -119,9 +119,9 @@ bumble/transport/grpc_protobuf/packet_streamer_pb2_grpc.py,sha256=k4RDFvE5Y4QgGL
|
|
|
119
119
|
bumble/transport/grpc_protobuf/startup_pb2.py,sha256=viPPlvFuRE1HoM3zg3Ayy5wfNnuSSAX80MNqtKVqv-o,1854
|
|
120
120
|
bumble/transport/grpc_protobuf/startup_pb2.pyi,sha256=8bDHVKJ_PIZuPvXRVK7tJCPOY8E8ZKW-5xzqbRLEJcw,2140
|
|
121
121
|
bumble/transport/grpc_protobuf/startup_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
|
|
122
|
-
bumble-0.0.
|
|
123
|
-
bumble-0.0.
|
|
124
|
-
bumble-0.0.
|
|
125
|
-
bumble-0.0.
|
|
126
|
-
bumble-0.0.
|
|
127
|
-
bumble-0.0.
|
|
122
|
+
bumble-0.0.161.dist-info/LICENSE,sha256=FvaYh4NRWIGgS_OwoBs5gFgkCmAghZ-DYnIGBZPuw-s,12142
|
|
123
|
+
bumble-0.0.161.dist-info/METADATA,sha256=Xy3VY03sptPDb03hJdGpFK6WqP476EPk6J63eAhvU0c,5221
|
|
124
|
+
bumble-0.0.161.dist-info/WHEEL,sha256=AtBG6SXL3KF_v0NxLf0ehyVOh0cold-JbJYXNGorC6Q,92
|
|
125
|
+
bumble-0.0.161.dist-info/entry_points.txt,sha256=AjCwgm9SvZDOhV7T6jWwAhWdE728pd759LQCscMLjnM,765
|
|
126
|
+
bumble-0.0.161.dist-info/top_level.txt,sha256=tV6JJKaHPYMFiJYiBYFW24PCcfLxTJZdlu6BmH3Cb00,7
|
|
127
|
+
bumble-0.0.161.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|