2
2
3
3
import logging
4
4
import time
5
+ import re
5
6
from core .test_harness import TestHarness
6
7
7
8
@@ -10,10 +11,31 @@ class BleAdvertisingScanningTest(TestHarness):
10
11
Multi-board test:
11
12
- Board 0: ble_advertising
12
13
- Board 1: ble_passive_scanning
14
+
13
15
We confirm that the advertiser prints "Now advertising..."
14
- and that the scanner prints a discovered advertisement.
16
+ and that the scanner detects the specific advertisement from our advertiser.
17
+
18
+ The test validates:
19
+ 1. The advertiser successfully advertises with the expected device name
20
+ 2. The scanner detects the advertiser's specific advertisement
21
+ 3. The advertisement contains the expected data payload
15
22
"""
16
23
24
+ # Configuration constants for test validation
25
+ EXPECTED_DEVICE_NAME = "TockOS"
26
+ EXPECTED_PDU_TYPE = "NON_CONNECT_IND"
27
+ EXPECTED_MANUFACTURER_DATA = (
28
+ "13 37" # From the advertiser's manufacturer_data[] = {0x13, 0x37}
29
+ )
30
+
31
+ # Pattern to extract BLE address from log output
32
+ ADDR_PATTERN = r"Address: ([0-9a-fA-F]{2} [0-9a-fA-F]{2} [0-9a-fA-F]{2} [0-9a-fA-F]{2} [0-9a-fA-F]{2} [0-9a-fA-F]{2})"
33
+
34
+ # Pattern to extract device name from advertisement data
35
+ DEVICE_NAME_PATTERN = (
36
+ r"TockOS" # Simplified pattern - could be enhanced to extract from actual data
37
+ )
38
+
17
39
def test (self , boards ):
18
40
if len (boards ) < 2 :
19
41
raise ValueError (
@@ -50,8 +72,6 @@ def test(self, boards):
50
72
scanner .flash_kernel ()
51
73
52
74
# Flash user apps:
53
- # "ble_advertising" is the path to your ble_advertising directory in libtock-c
54
- # "ble_passive_scanning" is the path to your ble_passive_scanning directory
55
75
advertiser .flash_app ("ble_advertising" )
56
76
scanner .flash_app ("ble_passive_scanning" )
57
77
@@ -64,11 +84,11 @@ def test(self, boards):
64
84
# We'll store flags once we've seen the key lines.
65
85
66
86
adv_done = False # Did we see the "Now advertising every..."
67
- scan_done = False # Did we see scanner output a discovered advertisement?
87
+ scan_done = False # Did we see scanner output for our specific advertisement?
68
88
69
- # Optional: look for [Tutorial] lines as well
70
- adv_tutorial_line = False
71
- scan_tutorial_line = False
89
+ # To store information for validation and error reporting
90
+ advertiser_addr = None # Will store the advertiser's BLE address if found
91
+ received_advertisements = [] # Will store all advertisements found by scanner
72
92
73
93
start_time = time .time ()
74
94
TIMEOUT = 30 # total seconds to wait
@@ -84,42 +104,74 @@ def test(self, boards):
84
104
if line_adv :
85
105
text_adv = line_adv .decode ("utf-8" , errors = "replace" ).strip ()
86
106
logging .debug (f"[Advertiser] { text_adv } " )
87
- if "[Tutorial] BLE Advertising" in text_adv :
88
- adv_tutorial_line = True
89
- if "Now advertising every" in text_adv :
107
+
108
+ # Detect when advertising starts
109
+ if (
110
+ "Now advertising every" in text_adv
111
+ and self .EXPECTED_DEVICE_NAME in text_adv
112
+ ):
90
113
adv_done = True
114
+ logging .info (
115
+ f"Advertiser started advertising as '{ self .EXPECTED_DEVICE_NAME } '"
116
+ )
91
117
92
118
# Read from scanner's console if any new line is present
93
119
line_scan = scanner .serial .expect (".+\r ?\n " , timeout = 1 , timeout_error = False )
94
120
if line_scan :
95
121
text_scan = line_scan .decode ("utf-8" , errors = "replace" ).strip ()
96
122
logging .debug (f"[Scanner] { text_scan } " )
97
- if "[Tutorial] BLE Passive Scanner" in text_scan :
98
- scan_tutorial_line = True
99
- if (
100
- "--------------------------LIST-------------------------"
101
- in text_scan
102
- ):
103
- # The next few lines might contain "PDU Type: 2 NON_CONNECT_IND"
104
- # We'll see if that appears eventually
105
- pass
106
- if "NON_CONNECT_IND" in text_scan :
107
- scan_done = True
123
+
124
+ # Store any discovered advertisement for later analysis
125
+ if self .EXPECTED_PDU_TYPE in text_scan :
126
+ received_advertisements .append (text_scan )
127
+
128
+ # See if this advertisement has our expected characteristics
129
+ adv_matches = (
130
+ # Check for the expected PDU type
131
+ self .EXPECTED_PDU_TYPE in text_scan
132
+ and
133
+ # Check for the manufacturer data
134
+ self .EXPECTED_MANUFACTURER_DATA in text_scan
135
+ )
136
+
137
+ if adv_matches :
138
+ logging .info ("Scanner detected our expected advertisement" )
139
+ scan_done = True
108
140
109
141
if adv_done and scan_done :
110
142
# We have everything we need
111
143
break
112
144
113
- # Check if both boards printed the expected lines
145
+ # Generate detailed error messages if needed
146
+ error_messages = []
147
+
114
148
if not adv_done :
115
- raise Exception (
116
- "Advertiser board never printed \" Now advertising every ... ms as 'TockOS '\" !"
149
+ error_messages . append (
150
+ f "Advertiser board never printed \" Now advertising every ... ms as '{ self . EXPECTED_DEVICE_NAME } '\" !"
117
151
)
152
+
118
153
if not scan_done :
119
- raise Exception (
120
- "Scanner board never saw a NON_CONNECT_IND advertisement in its list output!"
154
+ # Build a more detailed error message
155
+ error_detail = (
156
+ f"Scanner board never detected the expected advertisement.\n "
157
+ f"Expected: PDU Type: { self .EXPECTED_PDU_TYPE } , "
158
+ f"Manufacturer data: { self .EXPECTED_MANUFACTURER_DATA } \n "
121
159
)
122
160
161
+ if received_advertisements :
162
+ error_detail += "\n Received advertisements:\n "
163
+ for i , adv in enumerate (received_advertisements , 1 ):
164
+ # Extract and display just the relevant parts of the advertisement
165
+ error_detail += f"- Adv #{ i } : { adv [:200 ]} ...\n "
166
+ else :
167
+ error_detail += "No advertisements were detected by the scanner!"
168
+
169
+ error_messages .append (error_detail )
170
+
171
+ # Raise an exception with all error details if there were any failures
172
+ if error_messages :
173
+ raise Exception ("\n " .join (error_messages ))
174
+
123
175
logging .info ("BLE advertising + scanning test passed successfully!" )
124
176
125
177
0 commit comments