• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2021-2022 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# -----------------------------------------------------------------------------
18from bumble.hci import *
19
20
21# -----------------------------------------------------------------------------
22def basic_check(x):
23    packet = x.to_bytes()
24    print(packet.hex())
25    parsed = HCI_Packet.from_bytes(packet)
26    x_str = str(x)
27    parsed_str = str(parsed)
28    print(x_str)
29    parsed_bytes = parsed.to_bytes()
30    assert(x_str == parsed_str)
31    assert(packet == parsed_bytes)
32
33
34# -----------------------------------------------------------------------------
35def test_HCI_Event():
36    event = HCI_Event(0xF9)
37    basic_check(event)
38
39    event = HCI_Event(0xF8, bytes.fromhex('AABBCC'))
40    basic_check(event)
41
42
43# -----------------------------------------------------------------------------
44def test_HCI_LE_Connection_Complete_Event():
45    address = Address('00:11:22:33:44:55')
46    event = HCI_LE_Connection_Complete_Event(
47        status = HCI_SUCCESS,
48        connection_handle = 1,
49        role = 1,
50        peer_address_type = 1,
51        peer_address = address,
52        conn_interval = 3,
53        conn_latency = 4,
54        supervision_timeout = 5,
55        master_clock_accuracy = 6
56    )
57    basic_check(event)
58
59
60# -----------------------------------------------------------------------------
61def test_HCI_LE_Advertising_Report_Event():
62    address = Address('00:11:22:33:44:55')
63    report = HCI_Object(
64        HCI_LE_Advertising_Report_Event.REPORT_FIELDS,
65        event_type   = HCI_LE_Advertising_Report_Event.ADV_IND,
66        address_type = Address.PUBLIC_DEVICE_ADDRESS,
67        address      = address,
68        data         = bytes.fromhex('0201061106ba5689a6fabfa2bd01467d6e00fbabad08160a181604659b03'),
69        rssi         = 100
70    )
71    event = HCI_LE_Advertising_Report_Event([report])
72    basic_check(event)
73
74
75# -----------------------------------------------------------------------------
76def test_HCI_LE_Read_Remote_Features_Complete_Event():
77    event = HCI_LE_Read_Remote_Features_Complete_Event(
78        status            = HCI_SUCCESS,
79        connection_handle = 0x007,
80        le_features       = bytes.fromhex('0011223344556677')
81    )
82    basic_check(event)
83
84
85# -----------------------------------------------------------------------------
86def test_HCI_LE_Connection_Update_Complete_Event():
87    event = HCI_LE_Connection_Update_Complete_Event(
88        status              = HCI_SUCCESS,
89        connection_handle   = 0x007,
90        conn_interval       = 10,
91        conn_latency        = 3,
92        supervision_timeout = 5
93    )
94    basic_check(event)
95
96
97# -----------------------------------------------------------------------------
98def test_HCI_LE_Channel_Selection_Algorithm_Event():
99    event = HCI_LE_Channel_Selection_Algorithm_Event(
100        connection_handle = 7,
101        channel_selection_algorithm = 1
102    )
103    basic_check(event)
104
105
106# -----------------------------------------------------------------------------
107def test_HCI_Command_Complete_Event():
108    # With a serializable object
109    event = HCI_Command_Complete_Event(
110        num_hci_command_packets = 34,
111        command_opcode = HCI_LE_READ_BUFFER_SIZE_COMMAND,
112        return_parameters = HCI_LE_Read_Buffer_Size_Command.create_return_parameters(
113            status                           = 0,
114            hc_le_acl_data_packet_length     = 1234,
115            hc_total_num_le_acl_data_packets = 56
116        )
117    )
118    basic_check(event)
119
120    # With an arbitrary byte array
121    event = HCI_Command_Complete_Event(
122        num_hci_command_packets = 1,
123        command_opcode = HCI_RESET_COMMAND,
124        return_parameters = bytes([1, 2, 3, 4])
125    )
126    basic_check(event)
127
128    # With a simple status as a 1-byte array
129    event = HCI_Command_Complete_Event(
130        num_hci_command_packets = 1,
131        command_opcode = HCI_RESET_COMMAND,
132        return_parameters = bytes([7])
133    )
134    basic_check(event)
135    event = HCI_Packet.from_bytes(event.to_bytes())
136    assert(event.return_parameters == 7)
137
138    # With a simple status as an integer status
139    event = HCI_Command_Complete_Event(
140        num_hci_command_packets = 1,
141        command_opcode = HCI_RESET_COMMAND,
142        return_parameters = 9
143    )
144    basic_check(event)
145    assert(event.return_parameters == 9)
146
147
148# -----------------------------------------------------------------------------
149def test_HCI_Command_Status_Event():
150    event = HCI_Command_Status_Event(
151        status = 0,
152        num_hci_command_packets = 37,
153        command_opcode = HCI_DISCONNECT_COMMAND
154    )
155    basic_check(event)
156
157
158# -----------------------------------------------------------------------------
159def test_HCI_Number_Of_Completed_Packets_Event():
160    event = HCI_Number_Of_Completed_Packets_Event([
161        (1, 2),
162        (3, 4)
163    ])
164    basic_check(event)
165
166
167# -----------------------------------------------------------------------------
168def test_HCI_Command():
169    command = HCI_Command(0x5566)
170    basic_check(command)
171
172    command = HCI_Command(0x5566, bytes.fromhex('AABBCC'))
173    basic_check(command)
174
175
176# -----------------------------------------------------------------------------
177def test_HCI_Reset_Command():
178    command = HCI_Reset_Command()
179    basic_check(command)
180
181
182# -----------------------------------------------------------------------------
183def test_HCI_Read_Local_Version_Information_Command():
184    command = HCI_Read_Local_Version_Information_Command()
185    basic_check(command)
186
187
188# -----------------------------------------------------------------------------
189def test_HCI_Read_Local_Supported_Commands_Command():
190    command = HCI_Read_Local_Supported_Commands_Command()
191    basic_check(command)
192
193
194# -----------------------------------------------------------------------------
195def test_HCI_Read_Local_Supported_Features_Command():
196    command = HCI_Read_Local_Supported_Features_Command()
197    basic_check(command)
198
199
200# -----------------------------------------------------------------------------
201def test_HCI_Disconnect_Command():
202    command = HCI_Disconnect_Command(
203        connection_handle = 123,
204        reason = 0x11
205    )
206    basic_check(command)
207
208
209# -----------------------------------------------------------------------------
210def test_HCI_Set_Event_Mask_Command():
211    command = HCI_Set_Event_Mask_Command(
212        event_mask = bytes.fromhex('0011223344556677')
213    )
214    basic_check(command)
215
216
217# -----------------------------------------------------------------------------
218def test_HCI_LE_Set_Event_Mask_Command():
219    command = HCI_LE_Set_Event_Mask_Command(
220        le_event_mask = bytes.fromhex('0011223344556677')
221    )
222    basic_check(command)
223
224
225# -----------------------------------------------------------------------------
226def test_HCI_LE_Set_Random_Address_Command():
227    command = HCI_LE_Set_Random_Address_Command(
228        random_address = Address('00:11:22:33:44:55')
229    )
230    basic_check(command)
231
232
233# -----------------------------------------------------------------------------
234def test_HCI_LE_Set_Advertising_Parameters_Command():
235    command = HCI_LE_Set_Advertising_Parameters_Command(
236        advertising_interval_min   = 20,
237        advertising_interval_max   = 30,
238        advertising_type           = HCI_LE_Set_Advertising_Parameters_Command.ADV_NONCONN_IND,
239        own_address_type           = Address.PUBLIC_DEVICE_ADDRESS,
240        peer_address_type          = Address.RANDOM_DEVICE_ADDRESS,
241        peer_address               = Address('00:11:22:33:44:55'),
242        advertising_channel_map    = 0x03,
243        advertising_filter_policy  = 1
244    )
245    basic_check(command)
246
247
248# -----------------------------------------------------------------------------
249def test_HCI_LE_Set_Advertising_Data_Command():
250    command = HCI_LE_Set_Advertising_Data_Command(
251        advertising_data = bytes.fromhex('AABBCC')
252    )
253    basic_check(command)
254
255
256# -----------------------------------------------------------------------------
257def test_HCI_LE_Set_Scan_Parameters_Command():
258    command = HCI_LE_Set_Scan_Parameters_Command(
259        le_scan_type           = 1,
260        le_scan_interval       = 20,
261        le_scan_window         = 10,
262        own_address_type       = 1,
263        scanning_filter_policy = 0
264    )
265    basic_check(command)
266
267
268# -----------------------------------------------------------------------------
269def test_HCI_LE_Set_Scan_Enable_Command():
270    command = HCI_LE_Set_Scan_Enable_Command(
271        le_scan_enable    = 1,
272        filter_duplicates = 0
273    )
274    basic_check(command)
275
276
277# -----------------------------------------------------------------------------
278def test_HCI_LE_Create_Connection_Command():
279    command = HCI_LE_Create_Connection_Command(
280        le_scan_interval        = 4,
281        le_scan_window          = 5,
282        initiator_filter_policy = 1,
283        peer_address_type       = 1,
284        peer_address            = Address('00:11:22:33:44:55'),
285        own_address_type        = 2,
286        conn_interval_min       = 7,
287        conn_interval_max       = 8,
288        conn_latency            = 9,
289        supervision_timeout     = 10,
290        minimum_ce_length       = 11,
291        maximum_ce_length       = 12
292    )
293    basic_check(command)
294
295
296# -----------------------------------------------------------------------------
297def test_HCI_LE_Add_Device_To_White_List_Command():
298    command = HCI_LE_Add_Device_To_White_List_Command(
299        address_type = 1,
300        address      = Address('00:11:22:33:44:55')
301    )
302    basic_check(command)
303
304
305# -----------------------------------------------------------------------------
306def test_HCI_LE_Remove_Device_From_White_List_Command():
307    command = HCI_LE_Remove_Device_From_White_List_Command(
308        address_type = 1,
309        address      = Address('00:11:22:33:44:55')
310    )
311    basic_check(command)
312
313
314# -----------------------------------------------------------------------------
315def test_HCI_LE_Connection_Update_Command():
316    command = HCI_LE_Connection_Update_Command(
317        connection_handle   = 0x0002,
318        conn_interval_min   = 10,
319        conn_interval_max   = 20,
320        conn_latency        = 7,
321        supervision_timeout = 3,
322        minimum_ce_length   = 100,
323        maximum_ce_length   = 200
324    )
325    basic_check(command)
326
327
328# -----------------------------------------------------------------------------
329def test_HCI_LE_Read_Remote_Features_Command():
330    command = HCI_LE_Read_Remote_Features_Command(
331        connection_handle   = 0x0002
332    )
333    basic_check(command)
334
335
336# -----------------------------------------------------------------------------
337def test_HCI_LE_Set_Default_PHY_Command():
338    command = HCI_LE_Set_Default_PHY_Command(
339        all_phys = 0,
340        tx_phys  = 1,
341        rx_phys  = 1
342    )
343    basic_check(command)
344
345
346# -----------------------------------------------------------------------------
347def test_address():
348    a = Address('C4:F2:17:1A:1D:BB')
349    assert(not a.is_public)
350    assert(a.is_random)
351    assert(a.address_type == Address.RANDOM_DEVICE_ADDRESS)
352    assert(not a.is_resolvable)
353    assert(not a.is_resolved)
354    assert(a.is_static)
355
356
357# -----------------------------------------------------------------------------
358def test_custom():
359    data = bytes([0x77, 0x02, 0x01, 0x03])
360    packet = HCI_CustomPacket(data)
361    assert(packet.hci_packet_type == 0x77)
362    assert(packet.payload == data)
363
364
365# -----------------------------------------------------------------------------
366def run_test_events():
367    test_HCI_Event()
368    test_HCI_LE_Connection_Complete_Event()
369    test_HCI_LE_Advertising_Report_Event()
370    test_HCI_LE_Connection_Update_Complete_Event()
371    test_HCI_LE_Read_Remote_Features_Complete_Event()
372    test_HCI_LE_Channel_Selection_Algorithm_Event()
373    test_HCI_Command_Complete_Event()
374    test_HCI_Command_Status_Event()
375    test_HCI_Number_Of_Completed_Packets_Event()
376
377
378# -----------------------------------------------------------------------------
379def run_test_commands():
380    test_HCI_Command()
381    test_HCI_Reset_Command()
382    test_HCI_Read_Local_Version_Information_Command()
383    test_HCI_Read_Local_Supported_Commands_Command()
384    test_HCI_Read_Local_Supported_Features_Command()
385    test_HCI_Disconnect_Command()
386    test_HCI_Set_Event_Mask_Command()
387    test_HCI_LE_Set_Event_Mask_Command()
388    test_HCI_LE_Set_Random_Address_Command()
389    test_HCI_LE_Set_Advertising_Parameters_Command()
390    test_HCI_LE_Set_Advertising_Data_Command()
391    test_HCI_LE_Set_Scan_Parameters_Command()
392    test_HCI_LE_Set_Scan_Enable_Command()
393    test_HCI_LE_Create_Connection_Command()
394    test_HCI_LE_Add_Device_To_White_List_Command()
395    test_HCI_LE_Remove_Device_From_White_List_Command()
396    test_HCI_LE_Connection_Update_Command()
397    test_HCI_LE_Read_Remote_Features_Command()
398    test_HCI_LE_Set_Default_PHY_Command()
399
400
401# -----------------------------------------------------------------------------
402if __name__ == '__main__':
403    run_test_events()
404    run_test_commands()
405    test_address()
406    test_custom()
407