35
35
**Hardware:**
36
36
37
37
Adafruit Feather nRF52840 Express <https://www.adafruit.com/product/4062>
38
+ Adafruit Circuit Playground Bluefruit <https://www.adafruit.com/product/4333>
38
39
39
40
**Software and Dependencies:**
40
41
53
54
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_BLE.git"
54
55
55
56
class BLEConnection :
56
- """This represents a connection to a peer BLE device.
57
-
58
- It acts as a map from a Service type to a Service instance for the connection.
59
57
"""
60
- def __init__ (self , connection ):
61
- self ._connection = connection
62
- self ._discovered_services = {}
63
- """These are the bare remote services from _bleio."""
58
+ Represents a connection to a peer BLE device.
59
+ It acts as a map from a `Service` type to a `Service` instance for the connection.
64
60
61
+ :param bleio_connection _bleio.connection
62
+ """
63
+ def __init__ (self , bleio_connection ):
64
+ self ._bleio_connection = bleio_connection
65
+ # _bleio.Service objects representing services found during discoery.
66
+ self ._discovered_bleio_services = {}
67
+ # Service objects that wrap remote services.
65
68
self ._constructed_services = {}
66
- """These are the Service instances from the library that wrap the remote services."""
67
69
68
70
def _discover_remote (self , uuid ):
69
71
remote_service = None
70
- if uuid in self ._discovered_services :
71
- remote_service = self ._discovered_services [uuid ]
72
+ if uuid in self ._discovered_bleio_services :
73
+ remote_service = self ._discovered_bleio_services [uuid ]
72
74
else :
73
- results = self ._connection .discover_remote_services ((uuid .bleio_uuid ,))
75
+ results = self ._bleio_connection .discover_remote_services ((uuid .bleio_uuid ,))
74
76
if results :
75
77
remote_service = results [0 ]
76
- self ._discovered_services [uuid ] = remote_service
78
+ self ._discovered_bleio_services [uuid ] = remote_service
77
79
return remote_service
78
80
79
81
def __contains__ (self , key ):
82
+ """
83
+ Allows easy testing for a particular Service class or a particular UUID
84
+ associated with this connection.
85
+
86
+ Example::
87
+
88
+ if UARTService in connection:
89
+ # do something
90
+
91
+ if StandardUUID(0x1234) in connection:
92
+ # do something
93
+ """
80
94
uuid = key
81
95
if hasattr (key , "uuid" ):
82
96
uuid = key .uuid
83
97
return self ._discover_remote (uuid ) is not None
84
98
85
99
def __getitem__ (self , key ):
100
+ """Return the Service for the given Service class or uuid, if any."""
86
101
uuid = key
87
102
maybe_service = False
88
103
if hasattr (key , "uuid" ):
89
104
uuid = key .uuid
90
105
maybe_service = True
91
106
92
- remote_service = self ._discover_remote (uuid )
93
-
94
107
if uuid in self ._constructed_services :
95
108
return self ._constructed_services [uuid ]
109
+
110
+ remote_service = self ._discover_remote (uuid )
96
111
if remote_service :
97
112
constructed_service = None
98
113
if maybe_service :
@@ -105,16 +120,19 @@ def __getitem__(self, key):
105
120
@property
106
121
def connected (self ):
107
122
"""True if the connection to the peer is still active."""
108
- return self ._connection .connected
123
+ return self ._bleio_connection .connected
109
124
110
125
def disconnect (self ):
111
126
"""Disconnect from peer."""
112
- self ._connection .disconnect ()
127
+ self ._bleio_connection .disconnect ()
113
128
114
129
class BLERadio :
115
- """The BLERadio class enhances the normal `_bleio.Adapter`.
130
+ """
131
+ BLERadio provides the interfaces for BLE advertising,
132
+ scanning for advertisements, and connecting to peers. There may be
133
+ multiple connections active at once.
116
134
117
- It uses the library's `Advertisement` classes and the `BLEConnection` class."""
135
+ It uses this library's `Advertisement` classes and the `BLEConnection` class."""
118
136
119
137
def __init__ (self , adapter = None ):
120
138
if not adapter :
@@ -123,34 +141,62 @@ def __init__(self, adapter=None):
123
141
self ._current_advertisement = None
124
142
self ._connection_cache = {}
125
143
126
- def start_advertising (self , advertisement , scan_response = None , ** kwargs ):
127
- """Starts advertising the given advertisement.
144
+ def start_advertising (self , advertisement , scan_response = None , interval = 0.1 ):
145
+ """
146
+ Starts advertising the given advertisement.
128
147
129
- It takes most kwargs of `_bleio.Adapter.start_advertising`."""
148
+ :param buf scan_response: scan response data packet bytes.
149
+ ``None`` if no scan response is needed.
150
+ :param float interval: advertising interval, in seconds
151
+ """
130
152
scan_response_data = None
131
153
if scan_response :
132
154
scan_response_data = bytes (scan_response )
133
155
self ._adapter .start_advertising (bytes (advertisement ),
134
156
scan_response = scan_response_data ,
135
157
connectable = advertisement .connectable ,
136
- ** kwargs )
158
+ interval = interval )
137
159
138
160
def stop_advertising (self ):
139
161
"""Stops advertising."""
140
162
self ._adapter .stop_advertising ()
141
163
142
- def start_scan (self , * advertisement_types , ** kwargs ):
143
- """Starts scanning. Returns an iterator of advertisement objects of the types given in
144
- advertisement_types. The iterator will block until an advertisement is heard or the scan
145
- times out.
146
-
147
- If any ``advertisement_types`` are given, only Advertisements of those types are produced
148
- by the returned iterator. If none are given then `Advertisement` objects will be
149
- returned."""
164
+ def start_scan (self , * advertisement_types , buffer_size = 512 , extended = False , timeout = None ,
165
+ interval = 0.1 , window = 0.1 , minimum_rssi = - 80 , active = True ):
166
+ """
167
+ Starts scanning. Returns an iterator of advertisement objects of the types given in
168
+ advertisement_types. The iterator will block until an advertisement is heard or the scan
169
+ times out.
170
+
171
+ If any ``advertisement_types`` are given, only Advertisements of those types are produced
172
+ by the returned iterator. If none are given then `Advertisement` objects will be
173
+ returned.
174
+
175
+ Advertisements and scan responses are filtered and returned separately.
176
+
177
+ :param int buffer_size: the maximum number of advertising bytes to buffer.
178
+ :param bool extended: When True, support extended advertising packets.
179
+ Increasing buffer_size is recommended when this is set.
180
+ :param float timeout: the scan timeout in seconds.
181
+ If None, will scan until `stop_scan` is called.
182
+ :param float interval: the interval (in seconds) between the start
183
+ of two consecutive scan windows
184
+ Must be in the range 0.0025 - 40.959375 seconds.
185
+ :param float window: the duration (in seconds) to scan a single BLE channel.
186
+ window must be <= interval.
187
+ :param int minimum_rssi: the minimum rssi of entries to return.
188
+ :param bool active: request and retrieve scan responses for scannable advertisements.
189
+ :returns: iterable: If any ``advertisement_types`` are given,
190
+ only Advertisements of those types are produced by the returned iterator.
191
+ If none are given then `Advertisement` objects will be returned.
192
+ """
150
193
prefixes = b""
151
194
if advertisement_types :
152
195
prefixes = b"" .join (adv .prefix for adv in advertisement_types )
153
- for entry in self ._adapter .start_scan (prefixes = prefixes , ** kwargs ):
196
+ for entry in self ._adapter .start_scan (prefixes = prefixes , buffer_size = buffer_size ,
197
+ extended = extended , timeout = timeout ,
198
+ interval = interval , window = window ,
199
+ minimum_rssi = minimum_rssi , active = active ):
154
200
adv_type = Advertisement
155
201
for possible_type in advertisement_types :
156
202
if possible_type .matches (entry ) and issubclass (possible_type , adv_type ):
@@ -167,7 +213,14 @@ def stop_scan(self):
167
213
self ._adapter .stop_scan ()
168
214
169
215
def connect (self , advertisement , * , timeout = 4 ):
170
- """Initiates a `BLEConnection` to the peer that advertised the given advertisement."""
216
+ """
217
+ Initiates a `BLEConnection` to the peer that advertised the given advertisement.
218
+
219
+ :param advertisement Advertisement: An `Advertisement` or a subclass of `Advertisement`
220
+ :param timeout float: how long to wait for a connection
221
+ :returns the connection to the peer
222
+ :rtype BLEConnection
223
+ """
171
224
connection = self ._adapter .connect (advertisement .address , timeout = timeout )
172
225
self ._connection_cache [connection ] = BLEConnection (connection )
173
226
return self ._connection_cache [connection ]
0 commit comments