bumble 0.0.193__tar.gz → 0.0.194__tar.gz
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-0.0.193/bumble.egg-info → bumble-0.0.194}/PKG-INFO +1 -1
- {bumble-0.0.193 → bumble-0.0.194}/apps/bench.py +69 -12
- bumble-0.0.194/apps/rfcomm_bridge.py +511 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/_version.py +2 -2
- {bumble-0.0.193 → bumble-0.0.194}/bumble/l2cap.py +5 -2
- {bumble-0.0.193 → bumble-0.0.194}/bumble/rfcomm.py +148 -60
- {bumble-0.0.193 → bumble-0.0.194}/bumble/sdp.py +1 -1
- {bumble-0.0.193 → bumble-0.0.194/bumble.egg-info}/PKG-INFO +1 -1
- {bumble-0.0.193 → bumble-0.0.194}/bumble.egg-info/SOURCES.txt +1 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble.egg-info/entry_points.txt +1 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/src/main/java/com/github/google/bumble/btbench/SocketClient.kt +7 -1
- {bumble-0.0.193 → bumble-0.0.194}/setup.cfg +1 -0
- {bumble-0.0.193 → bumble-0.0.194}/tests/rfcomm_test.py +6 -1
- {bumble-0.0.193 → bumble-0.0.194}/.git-blame-ignore-revs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/.github/workflows/code-check.yml +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/.github/workflows/codeql-analysis.yml +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/.github/workflows/python-avatar.yml +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/.github/workflows/python-build-test.yml +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/.github/workflows/python-publish.yml +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/.gitignore +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/.vscode/settings.json +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/CONTRIBUTING.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/LICENSE +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/README.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/apps/README.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/apps/__init__.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/apps/ble_rpa_tool.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/apps/console.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/apps/controller_info.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/apps/controller_loopback.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/apps/controllers.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/apps/gatt_dump.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/apps/gg_bridge.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/apps/hci_bridge.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/apps/l2cap_bridge.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/apps/lea_unicast/app.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/apps/lea_unicast/index.html +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/apps/lea_unicast/liblc3.wasm +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/apps/link_relay/__init__.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/apps/link_relay/link_relay.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/apps/link_relay/logging.yml +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/apps/pair.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/apps/pandora_server.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/apps/scan.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/apps/show.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/apps/speaker/__init__.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/apps/speaker/logo.svg +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/apps/speaker/speaker.css +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/apps/speaker/speaker.html +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/apps/speaker/speaker.js +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/apps/speaker/speaker.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/apps/unbond.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/apps/usb_probe.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/__init__.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/a2dp.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/at.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/att.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/avc.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/avctp.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/avdtp.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/avrcp.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/bridge.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/codecs.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/colors.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/company_ids.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/controller.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/core.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/crypto.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/decoder.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/device.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/drivers/__init__.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/drivers/common.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/drivers/intel.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/drivers/rtk.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/gap.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/gatt.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/gatt_client.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/gatt_server.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/hci.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/helpers.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/hfp.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/hid.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/host.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/keys.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/link.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/pairing.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/pandora/__init__.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/pandora/config.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/pandora/device.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/pandora/host.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/pandora/py.typed +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/pandora/security.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/pandora/utils.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/profiles/__init__.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/profiles/asha_service.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/profiles/bap.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/profiles/battery_service.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/profiles/cap.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/profiles/csip.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/profiles/device_information_service.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/profiles/heart_rate_service.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/profiles/py.typed +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/profiles/vcp.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/py.typed +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/smp.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/snoop.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/__init__.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/android_emulator.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/android_netsim.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/common.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/file.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/grpc_protobuf/__init__.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/grpc_protobuf/common_pb2.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/grpc_protobuf/common_pb2.pyi +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/grpc_protobuf/common_pb2_grpc.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/grpc_protobuf/emulated_bluetooth_device_pb2.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/grpc_protobuf/emulated_bluetooth_device_pb2.pyi +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/grpc_protobuf/emulated_bluetooth_device_pb2_grpc.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/grpc_protobuf/emulated_bluetooth_packets_pb2.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/grpc_protobuf/emulated_bluetooth_packets_pb2.pyi +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/grpc_protobuf/emulated_bluetooth_packets_pb2_grpc.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/grpc_protobuf/emulated_bluetooth_pb2.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/grpc_protobuf/emulated_bluetooth_pb2.pyi +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/grpc_protobuf/emulated_bluetooth_pb2_grpc.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/grpc_protobuf/emulated_bluetooth_vhci_pb2.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/grpc_protobuf/emulated_bluetooth_vhci_pb2.pyi +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/grpc_protobuf/emulated_bluetooth_vhci_pb2_grpc.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/grpc_protobuf/grpc_endpoint_description_pb2.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/grpc_protobuf/grpc_endpoint_description_pb2.pyi +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/grpc_protobuf/grpc_endpoint_description_pb2_grpc.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/grpc_protobuf/hci_packet_pb2.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/grpc_protobuf/hci_packet_pb2.pyi +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/grpc_protobuf/hci_packet_pb2_grpc.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/grpc_protobuf/packet_streamer_pb2.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/grpc_protobuf/packet_streamer_pb2.pyi +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/grpc_protobuf/packet_streamer_pb2_grpc.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/grpc_protobuf/startup_pb2.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/grpc_protobuf/startup_pb2.pyi +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/grpc_protobuf/startup_pb2_grpc.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/hci_socket.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/pty.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/py.typed +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/pyusb.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/serial.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/tcp_client.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/tcp_server.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/udp.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/usb.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/vhci.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/ws_client.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/transport/ws_server.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/utils.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/vendor/__init__.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/vendor/android/__init__.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/vendor/android/hci.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/vendor/zephyr/__init__.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble/vendor/zephyr/hci.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble.egg-info/dependency_links.txt +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble.egg-info/requires.txt +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/bumble.egg-info/top_level.txt +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/README.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/images/logo.png +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/images/logo.svg +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/images/logo.vectornator/Artboard0.json +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/images/logo.vectornator/Document.json +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/images/logo.vectornator/Manifest.json +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/images/logo.vectornator/Thumbnail.png +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/images/logo.vectornator/UndoHistory.json +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/images/logo_framed.png +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/images/logo_framed.svg +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/images/logo_framed.vectornator/Artboard0.json +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/images/logo_framed.vectornator/Document.json +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/images/logo_framed.vectornator/Manifest.json +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/images/logo_framed.vectornator/Thumbnail.png +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/images/logo_framed.vectornator/UndoHistory.json +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/mkdocs.yml +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/requirements.txt +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/api/examples.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/api/guide.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/api/reference.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/apps_and_tools/bench.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/apps_and_tools/console.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/apps_and_tools/gatt_dump.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/apps_and_tools/gg_bridge.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/apps_and_tools/hci_bridge.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/apps_and_tools/index.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/apps_and_tools/link_relay.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/apps_and_tools/pair.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/apps_and_tools/show.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/apps_and_tools/speaker.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/apps_and_tools/unbond.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/apps_and_tools/usb_probe.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/components/controller.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/components/gatt.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/components/host.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/components/security_manager.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/development/code_style.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/development/contributing.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/development/python_environments.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/downloads/zephyr/hci_usb.zip +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/drivers/index.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/drivers/realtek.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/examples/index.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/extras/android_bt_bench.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/extras/android_remote_hci.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/extras/index.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/getting_started.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/hardware/index.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/hive/index.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/hive/index.toml +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/hive/web/bumble.js +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/hive/web/heart_rate_monitor/heart_rate_monitor.html +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/hive/web/heart_rate_monitor/heart_rate_monitor.js +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/hive/web/heart_rate_monitor/heart_rate_monitor.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/hive/web/scanner/scanner.css +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/hive/web/scanner/scanner.html +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/hive/web/scanner/scanner.js +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/hive/web/scanner/scanner.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/hive/web/speaker/logo.svg +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/hive/web/speaker/speaker.css +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/hive/web/speaker/speaker.html +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/hive/web/speaker/speaker.js +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/hive/web/speaker/speaker.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/hive/web/ui.js +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/images/bumble_layers.svg +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/images/console_screenshot.png +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/images/favicon.ico +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/images/logo.png +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/images/logo_framed.png +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/images/speaker_screenshot.png +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/index.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/platforms/android.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/platforms/index.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/platforms/linux.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/platforms/macos.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/platforms/windows.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/platforms/winusb_driver.png +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/platforms/zephyr.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/transports/android_emulator.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/transports/file.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/transports/hci_socket.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/transports/index.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/transports/pty.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/transports/serial.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/transports/tcp_client.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/transports/tcp_server.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/transports/udp.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/transports/usb.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/transports/vhci.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/transports/ws_client.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/transports/ws_server.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/use_cases/index.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/use_cases/use_case_1.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/use_cases/use_case_2.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/use_cases/use_case_3.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/use_cases/use_case_4.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/use_cases/use_case_5.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/src/use_cases/use_case_6.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/docs/mkdocs/theme/partials/footer.html +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/environment.yml +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/README.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/a2dp_sink1.json +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/asha_sink1.json +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/asha_sink2.json +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/async_runner.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/avrcp_as_sink.html +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/battery_client.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/battery_server.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/classic1.json +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/classic2.json +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/device1.json +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/device2.json +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/device3.json +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/device_information_client.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/device_information_server.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/heart_rate_client.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/heart_rate_server.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/hfp_gateway.html +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/hfp_gateway.json +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/hfp_handsfree.html +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/hfp_handsfree.json +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/hid_key_map.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/hid_keyboard.json +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/hid_report_parser.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/keyboard.html +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/keyboard.json +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/keyboard.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/leaudio.json +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/leaudio_with_classic.json +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/run_a2dp_info.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/run_a2dp_sink.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/run_a2dp_source.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/run_advertiser.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/run_asha_sink.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/run_avrcp.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/run_cig_setup.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/run_classic_connect.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/run_classic_discoverable.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/run_classic_discovery.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/run_connect_and_encrypt.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/run_controller.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/run_controller_with_scanner.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/run_csis_servers.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/run_device_with_snooper.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/run_esco_connection.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/run_extended_advertiser.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/run_extended_advertiser_2.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/run_gatt_client.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/run_gatt_client_and_server.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/run_gatt_server.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/run_hfp_gateway.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/run_hfp_handsfree.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/run_hid_device.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/run_hid_host.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/run_notifier.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/run_rfcomm_client.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/run_rfcomm_server.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/run_scanner.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/run_unicast_server.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/run_vcp_renderer.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/speaker.json +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/examples/vcp_renderer.html +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/.gitignore +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/.gitignore +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/build.gradle.kts +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/proguard-rules.pro +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/src/main/AndroidManifest.xml +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/src/main/ic_launcher-playstore.png +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/src/main/java/com/github/google/bumble/btbench/L2capClient.kt +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/src/main/java/com/github/google/bumble/btbench/L2capServer.kt +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/src/main/java/com/github/google/bumble/btbench/MainActivity.kt +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/src/main/java/com/github/google/bumble/btbench/Model.kt +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/src/main/java/com/github/google/bumble/btbench/Packet.kt +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/src/main/java/com/github/google/bumble/btbench/Receiver.kt +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/src/main/java/com/github/google/bumble/btbench/RfcommClient.kt +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/src/main/java/com/github/google/bumble/btbench/RfcommServer.kt +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/src/main/java/com/github/google/bumble/btbench/Sender.kt +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/src/main/java/com/github/google/bumble/btbench/SocketServer.kt +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/src/main/java/com/github/google/bumble/btbench/ui/theme/Color.kt +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/src/main/java/com/github/google/bumble/btbench/ui/theme/Theme.kt +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/src/main/java/com/github/google/bumble/btbench/ui/theme/Type.kt +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/src/main/res/drawable/ic_launcher_background.xml +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/src/main/res/drawable/ic_launcher_foreground.xml +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/src/main/res/values/colors.xml +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/src/main/res/values/ic_launcher_background.xml +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/src/main/res/values/strings.xml +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/src/main/res/values/themes.xml +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/src/main/res/xml/backup_rules.xml +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/app/src/main/res/xml/data_extraction_rules.xml +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/build.gradle.kts +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/gradle/libs.versions.toml +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/gradle/wrapper/gradle-wrapper.jar +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/gradle/wrapper/gradle-wrapper.properties +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/gradle.properties +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/gradlew +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/gradlew.bat +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/BtBench/settings.gradle.kts +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/.gitignore +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/.gitignore +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/build.gradle.kts +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/proguard-rules.pro +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/AndroidManifest.xml +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/aidl/android/hardware/bluetooth/IBluetoothHci.aidl +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/aidl/android/hardware/bluetooth/IBluetoothHciCallbacks.aidl +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/aidl/android/hardware/bluetooth/Status.aidl +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/hidl/bluetooth/1.1/IBluetoothHci.hal +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/hidl/bluetooth/1.1/IBluetoothHciCallbacks.hal +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/ic_launcher-playstore.png +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/java/android/hardware/bluetooth/IBluetoothHci.java +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/java/android/hardware/bluetooth/IBluetoothHciCallbacks.java +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/java/android/hardware/bluetooth/Status.java +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/java/android/hardware/bluetooth/V1_0/IBluetoothHci.java +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/java/android/hardware/bluetooth/V1_0/IBluetoothHciCallbacks.java +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/java/android/hardware/bluetooth/V1_0/Status.java +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/java/android/hardware/bluetooth/V1_1/IBluetoothHci.java +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/java/android/hardware/bluetooth/V1_1/IBluetoothHciCallbacks.java +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/java/com/github/google/bumble/remotehci/CommandLineInterface.kt +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/java/com/github/google/bumble/remotehci/HciHal.java +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/java/com/github/google/bumble/remotehci/HciHalCallback.java +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/java/com/github/google/bumble/remotehci/HciPacket.java +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/java/com/github/google/bumble/remotehci/HciParser.java +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/java/com/github/google/bumble/remotehci/HciProxy.java +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/java/com/github/google/bumble/remotehci/HciServer.java +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/java/com/github/google/bumble/remotehci/MainActivity.kt +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/java/com/github/google/bumble/remotehci/ui/theme/Color.kt +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/java/com/github/google/bumble/remotehci/ui/theme/Theme.kt +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/java/com/github/google/bumble/remotehci/ui/theme/Type.kt +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/res/mipmap-hdpi/ic_launcher.webp +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/res/mipmap-mdpi/ic_launcher.webp +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/res/mipmap-xhdpi/ic_launcher.webp +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/res/values/colors.xml +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/res/values/ic_launcher_background.xml +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/res/values/strings.xml +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/res/values/themes.xml +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/res/xml/backup_rules.xml +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/app/src/main/res/xml/data_extraction_rules.xml +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/build.gradle.kts +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/gradle/libs.versions.toml +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/gradle/wrapper/gradle-wrapper.jar +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/gradle/wrapper/gradle-wrapper.properties +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/gradle.properties +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/gradlew +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/gradlew.bat +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/lib/.gitignore +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/lib/build.gradle.kts +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/lib/consumer-rules.pro +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/lib/proguard-rules.pro +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/lib/src/main/AndroidManifest.xml +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/lib/src/main/java/android/internal/hidl/base/V1_0/DebugInfo.java +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/lib/src/main/java/android/internal/hidl/base/V1_0/IBase.java +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/lib/src/main/java/android/os/HidlSupport.java +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/lib/src/main/java/android/os/HwBinder.java +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/lib/src/main/java/android/os/HwBlob.java +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/lib/src/main/java/android/os/HwParcel.java +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/lib/src/main/java/android/os/IHwBinder.java +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/lib/src/main/java/android/os/IHwInterface.java +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/lib/src/main/java/android/os/NativeHandle.java +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/lib/src/main/java/android/os/ServiceManager.java +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/scripts/generate_java_from_aidl.sh +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/extras/android/RemoteHCI/settings.gradle.kts +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/noxfile.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/pyproject.toml +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/.gitignore +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/CHANGELOG.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/Cargo.lock +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/Cargo.toml +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/README.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/examples/battery_client.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/examples/broadcast.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/examples/scanner.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/pytests/assigned_numbers.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/pytests/pytests.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/pytests/wrapper/drivers.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/pytests/wrapper/hci.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/pytests/wrapper/mod.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/pytests/wrapper/transport.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/resources/test/firmware/realtek/README.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/resources/test/firmware/realtek/rtl8723b_fw_structure.bin +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/resources/test/firmware/realtek/rtl8761bu_fw_structure.bin +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/src/adv.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/src/cli/firmware/mod.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/src/cli/firmware/rtk.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/src/cli/l2cap/client_bridge.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/src/cli/l2cap/mod.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/src/cli/l2cap/server_bridge.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/src/cli/mod.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/src/cli/usb/mod.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/src/internal/drivers/mod.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/src/internal/drivers/rtk.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/src/internal/hci/mod.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/src/internal/hci/packets.pdl +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/src/internal/hci/tests.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/src/internal/mod.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/src/lib.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/src/main.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/src/wrapper/assigned_numbers/company_ids.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/src/wrapper/assigned_numbers/mod.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/src/wrapper/assigned_numbers/services.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/src/wrapper/common.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/src/wrapper/controller.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/src/wrapper/core.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/src/wrapper/device/mod.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/src/wrapper/device/tests.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/src/wrapper/drivers/mod.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/src/wrapper/drivers/rtk.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/src/wrapper/gatt_client.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/src/wrapper/hci.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/src/wrapper/host.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/src/wrapper/l2cap.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/src/wrapper/link.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/src/wrapper/logging.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/src/wrapper/mod.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/src/wrapper/profile.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/src/wrapper/transport.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/tools/file_header.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/rust/tools/gen_assigned_numbers.rs +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/scripts/process_android_emulator_protos.sh +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/scripts/process_android_netsim_protos.sh +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/setup.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/tasks.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/tests/__init__.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/tests/a2dp_test.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/tests/at_test.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/tests/avdtp_test.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/tests/avrcp_test.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/tests/bap_test.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/tests/cap_test.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/tests/codecs_test.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/tests/core_test.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/tests/csip_test.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/tests/decoder_test.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/tests/device_test.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/tests/g722_sample.g722 +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/tests/gatt_test.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/tests/hci_data_001.bin +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/tests/hci_test.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/tests/hfp_test.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/tests/host_test.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/tests/import_test.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/tests/keystore_test.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/tests/l2cap_test.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/tests/pytest.ini +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/tests/sdp_test.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/tests/self_test.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/tests/smp_test.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/tests/test_utils.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/tests/transport_tcp_server_test.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/tests/transport_test.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/tests/utils_test.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/tests/vcp_test.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/tools/__init__.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/tools/generate_company_id_list.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/tools/rtk_fw_download.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/tools/rtk_util.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/web/README.md +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/web/bumble.js +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/web/heart_rate_monitor/heart_rate_monitor.html +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/web/heart_rate_monitor/heart_rate_monitor.js +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/web/heart_rate_monitor/heart_rate_monitor.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/web/scanner/scanner.css +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/web/scanner/scanner.html +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/web/scanner/scanner.js +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/web/scanner/scanner.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/web/speaker/logo.svg +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/web/speaker/speaker.css +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/web/speaker/speaker.html +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/web/speaker/speaker.js +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/web/speaker/speaker.py +0 -0
- {bumble-0.0.193 → bumble-0.0.194}/web/ui.js +0 -0
|
@@ -899,14 +899,26 @@ class L2capServer(StreamedPacketIO):
|
|
|
899
899
|
# RfcommClient
|
|
900
900
|
# -----------------------------------------------------------------------------
|
|
901
901
|
class RfcommClient(StreamedPacketIO):
|
|
902
|
-
def __init__(
|
|
902
|
+
def __init__(
|
|
903
|
+
self,
|
|
904
|
+
device,
|
|
905
|
+
channel,
|
|
906
|
+
uuid,
|
|
907
|
+
l2cap_mtu,
|
|
908
|
+
max_frame_size,
|
|
909
|
+
initial_credits,
|
|
910
|
+
max_credits,
|
|
911
|
+
credits_threshold,
|
|
912
|
+
):
|
|
903
913
|
super().__init__()
|
|
904
914
|
self.device = device
|
|
905
915
|
self.channel = channel
|
|
906
916
|
self.uuid = uuid
|
|
907
917
|
self.l2cap_mtu = l2cap_mtu
|
|
908
918
|
self.max_frame_size = max_frame_size
|
|
909
|
-
self.
|
|
919
|
+
self.initial_credits = initial_credits
|
|
920
|
+
self.max_credits = max_credits
|
|
921
|
+
self.credits_threshold = credits_threshold
|
|
910
922
|
self.rfcomm_session = None
|
|
911
923
|
self.ready = asyncio.Event()
|
|
912
924
|
|
|
@@ -940,12 +952,17 @@ class RfcommClient(StreamedPacketIO):
|
|
|
940
952
|
logging.info(color(f'### Opening session for channel {channel}...', 'yellow'))
|
|
941
953
|
try:
|
|
942
954
|
dlc_options = {}
|
|
943
|
-
if self.max_frame_size:
|
|
955
|
+
if self.max_frame_size is not None:
|
|
944
956
|
dlc_options['max_frame_size'] = self.max_frame_size
|
|
945
|
-
if self.
|
|
946
|
-
dlc_options['
|
|
957
|
+
if self.initial_credits is not None:
|
|
958
|
+
dlc_options['initial_credits'] = self.initial_credits
|
|
947
959
|
rfcomm_session = await rfcomm_mux.open_dlc(channel, **dlc_options)
|
|
948
960
|
logging.info(color(f'### Session open: {rfcomm_session}', 'yellow'))
|
|
961
|
+
if self.max_credits is not None:
|
|
962
|
+
rfcomm_session.rx_max_credits = self.max_credits
|
|
963
|
+
if self.credits_threshold is not None:
|
|
964
|
+
rfcomm_session.rx_credits_threshold = self.credits_threshold
|
|
965
|
+
|
|
949
966
|
except bumble.core.ConnectionError as error:
|
|
950
967
|
logging.info(color(f'!!! Session open failed: {error}', 'red'))
|
|
951
968
|
await rfcomm_mux.disconnect()
|
|
@@ -969,8 +986,19 @@ class RfcommClient(StreamedPacketIO):
|
|
|
969
986
|
# RfcommServer
|
|
970
987
|
# -----------------------------------------------------------------------------
|
|
971
988
|
class RfcommServer(StreamedPacketIO):
|
|
972
|
-
def __init__(
|
|
989
|
+
def __init__(
|
|
990
|
+
self,
|
|
991
|
+
device,
|
|
992
|
+
channel,
|
|
993
|
+
l2cap_mtu,
|
|
994
|
+
max_frame_size,
|
|
995
|
+
initial_credits,
|
|
996
|
+
max_credits,
|
|
997
|
+
credits_threshold,
|
|
998
|
+
):
|
|
973
999
|
super().__init__()
|
|
1000
|
+
self.max_credits = max_credits
|
|
1001
|
+
self.credits_threshold = credits_threshold
|
|
974
1002
|
self.dlc = None
|
|
975
1003
|
self.ready = asyncio.Event()
|
|
976
1004
|
|
|
@@ -981,7 +1009,12 @@ class RfcommServer(StreamedPacketIO):
|
|
|
981
1009
|
rfcomm_server = bumble.rfcomm.Server(device, **server_options)
|
|
982
1010
|
|
|
983
1011
|
# Listen for incoming DLC connections
|
|
984
|
-
|
|
1012
|
+
dlc_options = {}
|
|
1013
|
+
if max_frame_size is not None:
|
|
1014
|
+
dlc_options['max_frame_size'] = max_frame_size
|
|
1015
|
+
if initial_credits is not None:
|
|
1016
|
+
dlc_options['initial_credits'] = initial_credits
|
|
1017
|
+
channel_number = rfcomm_server.listen(self.on_dlc, channel, **dlc_options)
|
|
985
1018
|
|
|
986
1019
|
# Setup the SDP to advertise this channel
|
|
987
1020
|
device.sdp_service_records = make_sdp_records(channel_number)
|
|
@@ -1004,6 +1037,10 @@ class RfcommServer(StreamedPacketIO):
|
|
|
1004
1037
|
dlc.sink = self.on_packet
|
|
1005
1038
|
self.io_sink = dlc.write
|
|
1006
1039
|
self.dlc = dlc
|
|
1040
|
+
if self.max_credits is not None:
|
|
1041
|
+
dlc.rx_max_credits = self.max_credits
|
|
1042
|
+
if self.credits_threshold is not None:
|
|
1043
|
+
dlc.rx_credits_threshold = self.credits_threshold
|
|
1007
1044
|
|
|
1008
1045
|
async def drain(self):
|
|
1009
1046
|
assert self.dlc
|
|
@@ -1321,7 +1358,9 @@ def create_mode_factory(ctx, default_mode):
|
|
|
1321
1358
|
uuid=ctx.obj['rfcomm_uuid'],
|
|
1322
1359
|
l2cap_mtu=ctx.obj['rfcomm_l2cap_mtu'],
|
|
1323
1360
|
max_frame_size=ctx.obj['rfcomm_max_frame_size'],
|
|
1324
|
-
|
|
1361
|
+
initial_credits=ctx.obj['rfcomm_initial_credits'],
|
|
1362
|
+
max_credits=ctx.obj['rfcomm_max_credits'],
|
|
1363
|
+
credits_threshold=ctx.obj['rfcomm_credits_threshold'],
|
|
1325
1364
|
)
|
|
1326
1365
|
|
|
1327
1366
|
if mode == 'rfcomm-server':
|
|
@@ -1329,6 +1368,10 @@ def create_mode_factory(ctx, default_mode):
|
|
|
1329
1368
|
device,
|
|
1330
1369
|
channel=ctx.obj['rfcomm_channel'],
|
|
1331
1370
|
l2cap_mtu=ctx.obj['rfcomm_l2cap_mtu'],
|
|
1371
|
+
max_frame_size=ctx.obj['rfcomm_max_frame_size'],
|
|
1372
|
+
initial_credits=ctx.obj['rfcomm_initial_credits'],
|
|
1373
|
+
max_credits=ctx.obj['rfcomm_max_credits'],
|
|
1374
|
+
credits_threshold=ctx.obj['rfcomm_credits_threshold'],
|
|
1332
1375
|
)
|
|
1333
1376
|
|
|
1334
1377
|
raise ValueError('invalid mode')
|
|
@@ -1427,9 +1470,19 @@ def create_role_factory(ctx, default_role):
|
|
|
1427
1470
|
help='RFComm maximum frame size',
|
|
1428
1471
|
)
|
|
1429
1472
|
@click.option(
|
|
1430
|
-
'--rfcomm-
|
|
1473
|
+
'--rfcomm-initial-credits',
|
|
1474
|
+
type=int,
|
|
1475
|
+
help='RFComm initial credits',
|
|
1476
|
+
)
|
|
1477
|
+
@click.option(
|
|
1478
|
+
'--rfcomm-max-credits',
|
|
1479
|
+
type=int,
|
|
1480
|
+
help='RFComm max credits',
|
|
1481
|
+
)
|
|
1482
|
+
@click.option(
|
|
1483
|
+
'--rfcomm-credits-threshold',
|
|
1431
1484
|
type=int,
|
|
1432
|
-
help='RFComm
|
|
1485
|
+
help='RFComm credits threshold',
|
|
1433
1486
|
)
|
|
1434
1487
|
@click.option(
|
|
1435
1488
|
'--l2cap-psm',
|
|
@@ -1530,7 +1583,9 @@ def bench(
|
|
|
1530
1583
|
rfcomm_uuid,
|
|
1531
1584
|
rfcomm_l2cap_mtu,
|
|
1532
1585
|
rfcomm_max_frame_size,
|
|
1533
|
-
|
|
1586
|
+
rfcomm_initial_credits,
|
|
1587
|
+
rfcomm_max_credits,
|
|
1588
|
+
rfcomm_credits_threshold,
|
|
1534
1589
|
l2cap_psm,
|
|
1535
1590
|
l2cap_mtu,
|
|
1536
1591
|
l2cap_mps,
|
|
@@ -1545,7 +1600,9 @@ def bench(
|
|
|
1545
1600
|
ctx.obj['rfcomm_uuid'] = rfcomm_uuid
|
|
1546
1601
|
ctx.obj['rfcomm_l2cap_mtu'] = rfcomm_l2cap_mtu
|
|
1547
1602
|
ctx.obj['rfcomm_max_frame_size'] = rfcomm_max_frame_size
|
|
1548
|
-
ctx.obj['
|
|
1603
|
+
ctx.obj['rfcomm_initial_credits'] = rfcomm_initial_credits
|
|
1604
|
+
ctx.obj['rfcomm_max_credits'] = rfcomm_max_credits
|
|
1605
|
+
ctx.obj['rfcomm_credits_threshold'] = rfcomm_credits_threshold
|
|
1549
1606
|
ctx.obj['l2cap_psm'] = l2cap_psm
|
|
1550
1607
|
ctx.obj['l2cap_mtu'] = l2cap_mtu
|
|
1551
1608
|
ctx.obj['l2cap_mps'] = l2cap_mps
|
|
@@ -0,0 +1,511 @@
|
|
|
1
|
+
# Copyright 2024 Google LLC
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
# -----------------------------------------------------------------------------
|
|
16
|
+
# Imports
|
|
17
|
+
# -----------------------------------------------------------------------------
|
|
18
|
+
import asyncio
|
|
19
|
+
import logging
|
|
20
|
+
import os
|
|
21
|
+
import time
|
|
22
|
+
from typing import Optional
|
|
23
|
+
|
|
24
|
+
import click
|
|
25
|
+
|
|
26
|
+
from bumble.colors import color
|
|
27
|
+
from bumble.device import Device, DeviceConfiguration, Connection
|
|
28
|
+
from bumble import core
|
|
29
|
+
from bumble import hci
|
|
30
|
+
from bumble import rfcomm
|
|
31
|
+
from bumble import transport
|
|
32
|
+
from bumble import utils
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
# -----------------------------------------------------------------------------
|
|
36
|
+
# Constants
|
|
37
|
+
# -----------------------------------------------------------------------------
|
|
38
|
+
DEFAULT_RFCOMM_UUID = "E6D55659-C8B4-4B85-96BB-B1143AF6D3AE"
|
|
39
|
+
DEFAULT_MTU = 4096
|
|
40
|
+
DEFAULT_CLIENT_TCP_PORT = 9544
|
|
41
|
+
DEFAULT_SERVER_TCP_PORT = 9545
|
|
42
|
+
|
|
43
|
+
TRACE_MAX_SIZE = 48
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
# -----------------------------------------------------------------------------
|
|
47
|
+
class Tracer:
|
|
48
|
+
"""
|
|
49
|
+
Trace data buffers transmitted from one endpoint to another, with stats.
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
def __init__(self, channel_name: str) -> None:
|
|
53
|
+
self.channel_name = channel_name
|
|
54
|
+
self.last_ts: float = 0.0
|
|
55
|
+
|
|
56
|
+
def trace_data(self, data: bytes) -> None:
|
|
57
|
+
now = time.time()
|
|
58
|
+
elapsed_s = now - self.last_ts if self.last_ts else 0
|
|
59
|
+
elapsed_ms = int(elapsed_s * 1000)
|
|
60
|
+
instant_throughput_kbps = ((len(data) / elapsed_s) / 1000) if elapsed_s else 0.0
|
|
61
|
+
|
|
62
|
+
hex_str = data[:TRACE_MAX_SIZE].hex() + (
|
|
63
|
+
"..." if len(data) > TRACE_MAX_SIZE else ""
|
|
64
|
+
)
|
|
65
|
+
print(
|
|
66
|
+
f"[{self.channel_name}] {len(data):4} bytes "
|
|
67
|
+
f"(+{elapsed_ms:4}ms, {instant_throughput_kbps: 7.2f}kB/s) "
|
|
68
|
+
f" {hex_str}"
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
self.last_ts = now
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
# -----------------------------------------------------------------------------
|
|
75
|
+
class ServerBridge:
|
|
76
|
+
"""
|
|
77
|
+
RFCOMM server bridge: waits for a peer to connect an RFCOMM channel.
|
|
78
|
+
The RFCOMM channel may be associated with a UUID published in an SDP service
|
|
79
|
+
description, or simply be on a system-assigned channel number.
|
|
80
|
+
When the connection is made, the bridge connects a TCP socket to a remote host and
|
|
81
|
+
bridges the data in both directions, with flow control.
|
|
82
|
+
When the RFCOMM channel is closed, the bridge disconnects the TCP socket
|
|
83
|
+
and waits for a new channel to be connected.
|
|
84
|
+
"""
|
|
85
|
+
|
|
86
|
+
READ_CHUNK_SIZE = 4096
|
|
87
|
+
|
|
88
|
+
def __init__(
|
|
89
|
+
self, channel: int, uuid: str, trace: bool, tcp_host: str, tcp_port: int
|
|
90
|
+
) -> None:
|
|
91
|
+
self.device: Optional[Device] = None
|
|
92
|
+
self.channel = channel
|
|
93
|
+
self.uuid = uuid
|
|
94
|
+
self.tcp_host = tcp_host
|
|
95
|
+
self.tcp_port = tcp_port
|
|
96
|
+
self.rfcomm_channel: Optional[rfcomm.DLC] = None
|
|
97
|
+
self.tcp_tracer: Optional[Tracer]
|
|
98
|
+
self.rfcomm_tracer: Optional[Tracer]
|
|
99
|
+
|
|
100
|
+
if trace:
|
|
101
|
+
self.tcp_tracer = Tracer(color("RFCOMM->TCP", "cyan"))
|
|
102
|
+
self.rfcomm_tracer = Tracer(color("TCP->RFCOMM", "magenta"))
|
|
103
|
+
else:
|
|
104
|
+
self.rfcomm_tracer = None
|
|
105
|
+
self.tcp_tracer = None
|
|
106
|
+
|
|
107
|
+
async def start(self, device: Device) -> None:
|
|
108
|
+
self.device = device
|
|
109
|
+
|
|
110
|
+
# Create and register a server
|
|
111
|
+
rfcomm_server = rfcomm.Server(self.device)
|
|
112
|
+
|
|
113
|
+
# Listen for incoming DLC connections
|
|
114
|
+
self.channel = rfcomm_server.listen(self.on_rfcomm_channel, self.channel)
|
|
115
|
+
|
|
116
|
+
# Setup the SDP to advertise this channel
|
|
117
|
+
service_record_handle = 0x00010001
|
|
118
|
+
self.device.sdp_service_records = {
|
|
119
|
+
service_record_handle: rfcomm.make_service_sdp_records(
|
|
120
|
+
service_record_handle, self.channel, core.UUID(self.uuid)
|
|
121
|
+
)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
# We're ready for a connection
|
|
125
|
+
self.device.on("connection", self.on_connection)
|
|
126
|
+
await self.set_available(True)
|
|
127
|
+
|
|
128
|
+
print(
|
|
129
|
+
color(
|
|
130
|
+
(
|
|
131
|
+
f"### Listening for RFCOMM connection on {device.public_address}, "
|
|
132
|
+
f"channel {self.channel}"
|
|
133
|
+
),
|
|
134
|
+
"yellow",
|
|
135
|
+
)
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
async def set_available(self, available: bool):
|
|
139
|
+
# Become discoverable and connectable
|
|
140
|
+
assert self.device
|
|
141
|
+
await self.device.set_connectable(available)
|
|
142
|
+
await self.device.set_discoverable(available)
|
|
143
|
+
|
|
144
|
+
def on_connection(self, connection):
|
|
145
|
+
print(color(f"@@@ Bluetooth connection: {connection}", "blue"))
|
|
146
|
+
connection.on("disconnection", self.on_disconnection)
|
|
147
|
+
|
|
148
|
+
# Don't accept new connections until we're disconnected
|
|
149
|
+
utils.AsyncRunner.spawn(self.set_available(False))
|
|
150
|
+
|
|
151
|
+
def on_disconnection(self, reason: int):
|
|
152
|
+
print(
|
|
153
|
+
color("@@@ Bluetooth disconnection:", "red"),
|
|
154
|
+
hci.HCI_Constant.error_name(reason),
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
# We're ready for a new connection
|
|
158
|
+
utils.AsyncRunner.spawn(self.set_available(True))
|
|
159
|
+
|
|
160
|
+
# Called when an RFCOMM channel is established
|
|
161
|
+
@utils.AsyncRunner.run_in_task()
|
|
162
|
+
async def on_rfcomm_channel(self, rfcomm_channel):
|
|
163
|
+
print(color("*** RFCOMM channel:", "cyan"), rfcomm_channel)
|
|
164
|
+
|
|
165
|
+
# Connect to the TCP server
|
|
166
|
+
print(
|
|
167
|
+
color(
|
|
168
|
+
f"### Connecting to TCP {self.tcp_host}:{self.tcp_port}",
|
|
169
|
+
"yellow",
|
|
170
|
+
)
|
|
171
|
+
)
|
|
172
|
+
try:
|
|
173
|
+
reader, writer = await asyncio.open_connection(self.tcp_host, self.tcp_port)
|
|
174
|
+
except OSError:
|
|
175
|
+
print(color("!!! Connection failed", "red"))
|
|
176
|
+
await rfcomm_channel.disconnect()
|
|
177
|
+
return
|
|
178
|
+
|
|
179
|
+
# Pipe data from RFCOMM to TCP
|
|
180
|
+
def on_rfcomm_channel_closed():
|
|
181
|
+
print(color("*** RFCOMM channel closed", "cyan"))
|
|
182
|
+
writer.close()
|
|
183
|
+
|
|
184
|
+
def write_rfcomm_data(data):
|
|
185
|
+
if self.rfcomm_tracer:
|
|
186
|
+
self.rfcomm_tracer.trace_data(data)
|
|
187
|
+
|
|
188
|
+
writer.write(data)
|
|
189
|
+
|
|
190
|
+
rfcomm_channel.sink = write_rfcomm_data
|
|
191
|
+
rfcomm_channel.on("close", on_rfcomm_channel_closed)
|
|
192
|
+
|
|
193
|
+
# Pipe data from TCP to RFCOMM
|
|
194
|
+
while True:
|
|
195
|
+
try:
|
|
196
|
+
data = await reader.read(self.READ_CHUNK_SIZE)
|
|
197
|
+
|
|
198
|
+
if len(data) == 0:
|
|
199
|
+
print(color("### TCP end of stream", "yellow"))
|
|
200
|
+
if rfcomm_channel.state == rfcomm.DLC.State.CONNECTED:
|
|
201
|
+
await rfcomm_channel.disconnect()
|
|
202
|
+
return
|
|
203
|
+
|
|
204
|
+
if self.tcp_tracer:
|
|
205
|
+
self.tcp_tracer.trace_data(data)
|
|
206
|
+
|
|
207
|
+
rfcomm_channel.write(data)
|
|
208
|
+
await rfcomm_channel.drain()
|
|
209
|
+
except Exception as error:
|
|
210
|
+
print(f"!!! Exception: {error}")
|
|
211
|
+
break
|
|
212
|
+
|
|
213
|
+
writer.close()
|
|
214
|
+
await writer.wait_closed()
|
|
215
|
+
print(color("~~~ Bye bye", "magenta"))
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
# -----------------------------------------------------------------------------
|
|
219
|
+
class ClientBridge:
|
|
220
|
+
"""
|
|
221
|
+
RFCOMM client bridge: connects to a BR/EDR device, then waits for an inbound
|
|
222
|
+
TCP connection on a specified port number. When a TCP client connects, an
|
|
223
|
+
RFCOMM connection to the device is established, and the data is bridged in both
|
|
224
|
+
directions, with flow control.
|
|
225
|
+
When the TCP connection is closed by the client, the RFCOMM channel is
|
|
226
|
+
disconnected, but the connection to the device remains, ready for a new TCP client
|
|
227
|
+
to connect.
|
|
228
|
+
"""
|
|
229
|
+
|
|
230
|
+
READ_CHUNK_SIZE = 4096
|
|
231
|
+
|
|
232
|
+
def __init__(
|
|
233
|
+
self,
|
|
234
|
+
channel: int,
|
|
235
|
+
uuid: str,
|
|
236
|
+
trace: bool,
|
|
237
|
+
address: str,
|
|
238
|
+
tcp_host: str,
|
|
239
|
+
tcp_port: int,
|
|
240
|
+
encrypt: bool,
|
|
241
|
+
):
|
|
242
|
+
self.channel = channel
|
|
243
|
+
self.uuid = uuid
|
|
244
|
+
self.trace = trace
|
|
245
|
+
self.address = address
|
|
246
|
+
self.tcp_host = tcp_host
|
|
247
|
+
self.tcp_port = tcp_port
|
|
248
|
+
self.encrypt = encrypt
|
|
249
|
+
self.device: Optional[Device] = None
|
|
250
|
+
self.connection: Optional[Connection] = None
|
|
251
|
+
self.rfcomm_client: Optional[rfcomm.Client]
|
|
252
|
+
self.rfcomm_mux: Optional[rfcomm.Multiplexer]
|
|
253
|
+
self.tcp_connected: bool = False
|
|
254
|
+
|
|
255
|
+
self.tcp_tracer: Optional[Tracer]
|
|
256
|
+
self.rfcomm_tracer: Optional[Tracer]
|
|
257
|
+
|
|
258
|
+
if trace:
|
|
259
|
+
self.tcp_tracer = Tracer(color("RFCOMM->TCP", "cyan"))
|
|
260
|
+
self.rfcomm_tracer = Tracer(color("TCP->RFCOMM", "magenta"))
|
|
261
|
+
else:
|
|
262
|
+
self.rfcomm_tracer = None
|
|
263
|
+
self.tcp_tracer = None
|
|
264
|
+
|
|
265
|
+
async def connect(self) -> None:
|
|
266
|
+
if self.connection:
|
|
267
|
+
return
|
|
268
|
+
|
|
269
|
+
print(color(f"@@@ Connecting to Bluetooth {self.address}", "blue"))
|
|
270
|
+
assert self.device
|
|
271
|
+
self.connection = await self.device.connect(
|
|
272
|
+
self.address, transport=core.BT_BR_EDR_TRANSPORT
|
|
273
|
+
)
|
|
274
|
+
print(color(f"@@@ Bluetooth connection: {self.connection}", "blue"))
|
|
275
|
+
self.connection.on("disconnection", self.on_disconnection)
|
|
276
|
+
|
|
277
|
+
if self.encrypt:
|
|
278
|
+
print(color("@@@ Encrypting Bluetooth connection", "blue"))
|
|
279
|
+
await self.connection.encrypt()
|
|
280
|
+
print(color("@@@ Bluetooth connection encrypted", "blue"))
|
|
281
|
+
|
|
282
|
+
self.rfcomm_client = rfcomm.Client(self.connection)
|
|
283
|
+
try:
|
|
284
|
+
self.rfcomm_mux = await self.rfcomm_client.start()
|
|
285
|
+
except BaseException as e:
|
|
286
|
+
print(color("!!! Failed to setup RFCOMM connection", "red"), e)
|
|
287
|
+
raise
|
|
288
|
+
|
|
289
|
+
async def start(self, device: Device) -> None:
|
|
290
|
+
self.device = device
|
|
291
|
+
await device.set_connectable(False)
|
|
292
|
+
await device.set_discoverable(False)
|
|
293
|
+
|
|
294
|
+
# Called when a TCP connection is established
|
|
295
|
+
async def on_tcp_connection(reader, writer):
|
|
296
|
+
print(color("<<< TCP connection", "magenta"))
|
|
297
|
+
if self.tcp_connected:
|
|
298
|
+
print(
|
|
299
|
+
color("!!! TCP connection already active, rejecting new one", "red")
|
|
300
|
+
)
|
|
301
|
+
writer.close()
|
|
302
|
+
return
|
|
303
|
+
self.tcp_connected = True
|
|
304
|
+
|
|
305
|
+
try:
|
|
306
|
+
await self.pipe(reader, writer)
|
|
307
|
+
except BaseException as error:
|
|
308
|
+
print(color("!!! Exception while piping data:", "red"), error)
|
|
309
|
+
return
|
|
310
|
+
finally:
|
|
311
|
+
writer.close()
|
|
312
|
+
await writer.wait_closed()
|
|
313
|
+
self.tcp_connected = False
|
|
314
|
+
|
|
315
|
+
await asyncio.start_server(
|
|
316
|
+
on_tcp_connection,
|
|
317
|
+
host=self.tcp_host if self.tcp_host != "_" else None,
|
|
318
|
+
port=self.tcp_port,
|
|
319
|
+
)
|
|
320
|
+
print(
|
|
321
|
+
color(
|
|
322
|
+
f"### Listening for TCP connections on port {self.tcp_port}", "magenta"
|
|
323
|
+
)
|
|
324
|
+
)
|
|
325
|
+
|
|
326
|
+
async def pipe(
|
|
327
|
+
self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter
|
|
328
|
+
) -> None:
|
|
329
|
+
# Resolve the channel number from the UUID if needed
|
|
330
|
+
if self.channel == 0:
|
|
331
|
+
await self.connect()
|
|
332
|
+
assert self.connection
|
|
333
|
+
channel = await rfcomm.find_rfcomm_channel_with_uuid(
|
|
334
|
+
self.connection, self.uuid
|
|
335
|
+
)
|
|
336
|
+
if channel:
|
|
337
|
+
print(color(f"### Found RFCOMM channel {channel}", "yellow"))
|
|
338
|
+
else:
|
|
339
|
+
print(color(f"!!! RFCOMM channel with UUID {self.uuid} not found"))
|
|
340
|
+
return
|
|
341
|
+
else:
|
|
342
|
+
channel = self.channel
|
|
343
|
+
|
|
344
|
+
# Connect a new RFCOMM channel
|
|
345
|
+
await self.connect()
|
|
346
|
+
assert self.rfcomm_mux
|
|
347
|
+
print(color(f"*** Opening RFCOMM channel {channel}", "green"))
|
|
348
|
+
try:
|
|
349
|
+
rfcomm_channel = await self.rfcomm_mux.open_dlc(channel)
|
|
350
|
+
print(color(f"*** RFCOMM channel open: {rfcomm_channel}", "green"))
|
|
351
|
+
except Exception as error:
|
|
352
|
+
print(color(f"!!! RFCOMM open failed: {error}", "red"))
|
|
353
|
+
return
|
|
354
|
+
|
|
355
|
+
# Pipe data from RFCOMM to TCP
|
|
356
|
+
def on_rfcomm_channel_closed():
|
|
357
|
+
print(color("*** RFCOMM channel closed", "green"))
|
|
358
|
+
|
|
359
|
+
def write_rfcomm_data(data):
|
|
360
|
+
if self.trace:
|
|
361
|
+
self.rfcomm_tracer.trace_data(data)
|
|
362
|
+
|
|
363
|
+
writer.write(data)
|
|
364
|
+
|
|
365
|
+
rfcomm_channel.on("close", on_rfcomm_channel_closed)
|
|
366
|
+
rfcomm_channel.sink = write_rfcomm_data
|
|
367
|
+
|
|
368
|
+
# Pipe data from TCP to RFCOMM
|
|
369
|
+
while True:
|
|
370
|
+
try:
|
|
371
|
+
data = await reader.read(self.READ_CHUNK_SIZE)
|
|
372
|
+
|
|
373
|
+
if len(data) == 0:
|
|
374
|
+
print(color("### TCP end of stream", "yellow"))
|
|
375
|
+
if rfcomm_channel.state == rfcomm.DLC.State.CONNECTED:
|
|
376
|
+
await rfcomm_channel.disconnect()
|
|
377
|
+
self.tcp_connected = False
|
|
378
|
+
return
|
|
379
|
+
|
|
380
|
+
if self.tcp_tracer:
|
|
381
|
+
self.tcp_tracer.trace_data(data)
|
|
382
|
+
|
|
383
|
+
rfcomm_channel.write(data)
|
|
384
|
+
await rfcomm_channel.drain()
|
|
385
|
+
except Exception as error:
|
|
386
|
+
print(f"!!! Exception: {error}")
|
|
387
|
+
break
|
|
388
|
+
|
|
389
|
+
print(color("~~~ Bye bye", "magenta"))
|
|
390
|
+
|
|
391
|
+
def on_disconnection(self, reason: int) -> None:
|
|
392
|
+
print(
|
|
393
|
+
color("@@@ Bluetooth disconnection:", "red"),
|
|
394
|
+
hci.HCI_Constant.error_name(reason),
|
|
395
|
+
)
|
|
396
|
+
self.connection = None
|
|
397
|
+
|
|
398
|
+
|
|
399
|
+
# -----------------------------------------------------------------------------
|
|
400
|
+
async def run(device_config, hci_transport, bridge):
|
|
401
|
+
print("<<< connecting to HCI...")
|
|
402
|
+
async with await transport.open_transport_or_link(hci_transport) as (
|
|
403
|
+
hci_source,
|
|
404
|
+
hci_sink,
|
|
405
|
+
):
|
|
406
|
+
print("<<< connected")
|
|
407
|
+
|
|
408
|
+
if device_config:
|
|
409
|
+
device = Device.from_config_file_with_hci(
|
|
410
|
+
device_config, hci_source, hci_sink
|
|
411
|
+
)
|
|
412
|
+
else:
|
|
413
|
+
device = Device.from_config_with_hci(
|
|
414
|
+
DeviceConfiguration(), hci_source, hci_sink
|
|
415
|
+
)
|
|
416
|
+
device.classic_enabled = True
|
|
417
|
+
|
|
418
|
+
# Let's go
|
|
419
|
+
await device.power_on()
|
|
420
|
+
try:
|
|
421
|
+
await bridge.start(device)
|
|
422
|
+
|
|
423
|
+
# Wait until the transport terminates
|
|
424
|
+
await hci_source.wait_for_termination()
|
|
425
|
+
except core.ConnectionError as error:
|
|
426
|
+
print(color(f"!!! Bluetooth connection failed: {error}", "red"))
|
|
427
|
+
except Exception as error:
|
|
428
|
+
print(f"Exception while running bridge: {error}")
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
# -----------------------------------------------------------------------------
|
|
432
|
+
@click.group()
|
|
433
|
+
@click.pass_context
|
|
434
|
+
@click.option(
|
|
435
|
+
"--device-config",
|
|
436
|
+
metavar="CONFIG_FILE",
|
|
437
|
+
help="Device configuration file",
|
|
438
|
+
)
|
|
439
|
+
@click.option(
|
|
440
|
+
"--hci-transport", metavar="TRANSPORT_NAME", help="HCI transport", required=True
|
|
441
|
+
)
|
|
442
|
+
@click.option("--trace", is_flag=True, help="Trace bridged data to stdout")
|
|
443
|
+
@click.option(
|
|
444
|
+
"--channel",
|
|
445
|
+
metavar="CHANNEL_NUMER",
|
|
446
|
+
help="RFCOMM channel number",
|
|
447
|
+
type=int,
|
|
448
|
+
default=0,
|
|
449
|
+
)
|
|
450
|
+
@click.option(
|
|
451
|
+
"--uuid",
|
|
452
|
+
metavar="UUID",
|
|
453
|
+
help="UUID for the RFCOMM channel",
|
|
454
|
+
default=DEFAULT_RFCOMM_UUID,
|
|
455
|
+
)
|
|
456
|
+
def cli(
|
|
457
|
+
context,
|
|
458
|
+
device_config,
|
|
459
|
+
hci_transport,
|
|
460
|
+
trace,
|
|
461
|
+
channel,
|
|
462
|
+
uuid,
|
|
463
|
+
):
|
|
464
|
+
context.ensure_object(dict)
|
|
465
|
+
context.obj["device_config"] = device_config
|
|
466
|
+
context.obj["hci_transport"] = hci_transport
|
|
467
|
+
context.obj["trace"] = trace
|
|
468
|
+
context.obj["channel"] = channel
|
|
469
|
+
context.obj["uuid"] = uuid
|
|
470
|
+
|
|
471
|
+
|
|
472
|
+
# -----------------------------------------------------------------------------
|
|
473
|
+
@cli.command()
|
|
474
|
+
@click.pass_context
|
|
475
|
+
@click.option("--tcp-host", help="TCP host", default="localhost")
|
|
476
|
+
@click.option("--tcp-port", help="TCP port", default=DEFAULT_SERVER_TCP_PORT)
|
|
477
|
+
def server(context, tcp_host, tcp_port):
|
|
478
|
+
bridge = ServerBridge(
|
|
479
|
+
context.obj["channel"],
|
|
480
|
+
context.obj["uuid"],
|
|
481
|
+
context.obj["trace"],
|
|
482
|
+
tcp_host,
|
|
483
|
+
tcp_port,
|
|
484
|
+
)
|
|
485
|
+
asyncio.run(run(context.obj["device_config"], context.obj["hci_transport"], bridge))
|
|
486
|
+
|
|
487
|
+
|
|
488
|
+
# -----------------------------------------------------------------------------
|
|
489
|
+
@cli.command()
|
|
490
|
+
@click.pass_context
|
|
491
|
+
@click.argument("bluetooth-address")
|
|
492
|
+
@click.option("--tcp-host", help="TCP host", default="_")
|
|
493
|
+
@click.option("--tcp-port", help="TCP port", default=DEFAULT_CLIENT_TCP_PORT)
|
|
494
|
+
@click.option("--encrypt", is_flag=True, help="Encrypt the connection")
|
|
495
|
+
def client(context, bluetooth_address, tcp_host, tcp_port, encrypt):
|
|
496
|
+
bridge = ClientBridge(
|
|
497
|
+
context.obj["channel"],
|
|
498
|
+
context.obj["uuid"],
|
|
499
|
+
context.obj["trace"],
|
|
500
|
+
bluetooth_address,
|
|
501
|
+
tcp_host,
|
|
502
|
+
tcp_port,
|
|
503
|
+
encrypt,
|
|
504
|
+
)
|
|
505
|
+
asyncio.run(run(context.obj["device_config"], context.obj["hci_transport"], bridge))
|
|
506
|
+
|
|
507
|
+
|
|
508
|
+
# -----------------------------------------------------------------------------
|
|
509
|
+
logging.basicConfig(level=os.environ.get("BUMBLE_LOGLEVEL", "WARNING").upper())
|
|
510
|
+
if __name__ == "__main__":
|
|
511
|
+
cli(obj={}) # pylint: disable=no-value-for-parameter
|