@@ -116,31 +116,24 @@ class AdvertisingFlags(AdvertisingDataField):
116116 def __init__ (self , advertisement , advertising_data_type ):
117117 self ._advertisement = advertisement
118118 self ._adt = advertising_data_type
119- self .flags = None
119+ self .flags = 0
120120 if self ._adt in self ._advertisement .data_dict :
121121 self .flags = self ._advertisement .data_dict [self ._adt ][0 ]
122- elif self ._advertisement .mutable :
123- self .flags = 0b110 # Default to General discovery and LE Only
124- else :
125- self .flags = 0
126122
127123 def __len__ (self ):
128124 return 1
129125
130126 def __bytes__ (self ):
131- encoded = bytearray (1 )
132- encoded [0 ] = self .flags
133- return encoded
127+ return bytes ([self .flags ])
134128
135129 def __str__ (self ):
136- parts = ["<AdvertisingFlags" ]
130+ parts = []
137131 for attr in dir (self .__class__ ):
138132 attribute_instance = getattr (self .__class__ , attr )
139133 if issubclass (attribute_instance .__class__ , AdvertisingFlag ):
140134 if getattr (self , attr ):
141135 parts .append (attr )
142- parts .append (">" )
143- return " " .join (parts )
136+ return "<AdvertisingFlags {} >" .format (" " .join (parts ))
144137
145138class String (AdvertisingDataField ):
146139 """UTF-8 encoded string in an Advertisement.
@@ -172,7 +165,7 @@ def __set__(self, obj, value):
172165 obj .data_dict [self ._adt ] = struct .pack (self ._format , value )
173166
174167
175- class LazyField (AdvertisingDataField ):
168+ class LazyObjectField (AdvertisingDataField ):
176169 """Non-data descriptor useful for lazily binding a complex object to an advertisement object."""
177170 def __init__ (self , cls , attribute_name , * , advertising_data_type , ** kwargs ):
178171 self ._cls = cls
@@ -184,18 +177,24 @@ def __get__(self, obj, cls):
184177 # Return None if our object is immutable and the data is not present.
185178 if not obj .mutable and self ._adt not in obj .data_dict :
186179 return None
187- bound_class = self ._cls (obj , advertising_data_type = self ._adt , ** self ._kwargs )
188- setattr (obj , self ._attribute_name , bound_class )
189- obj .data_dict [self ._adt ] = bound_class
190- return bound_class
180+ # Instantiate the object.
181+ bound_obj = self ._cls (obj , advertising_data_type = self ._adt , ** self ._kwargs )
182+ setattr (obj , self ._attribute_name , bound_obj )
183+ obj .data_dict [self ._adt ] = bound_obj
184+ return bound_obj
185+
186+ @property
187+ def advertising_data_type (self ):
188+ """Return the data type value used to indicate this field."""
189+ return self ._adt
191190
192191 # TODO: Add __set_name__ support to CircuitPython so that we automatically tell the descriptor
193192 # instance the attribute name it has and the class it is on.
194193
195194class Advertisement :
196195 """Core Advertisement type"""
197196 prefix = b"\x00 " # This is an empty prefix and will match everything.
198- flags = LazyField (AdvertisingFlags , "flags" , advertising_data_type = 0x01 )
197+ flags = LazyObjectField (AdvertisingFlags , "flags" , advertising_data_type = 0x01 )
199198 short_name = String (advertising_data_type = 0x08 )
200199 """Short local device name (shortened to fit)."""
201200 complete_name = String (advertising_data_type = 0x09 )
@@ -263,15 +262,19 @@ def __bytes__(self):
263262 return encode_data (self .data_dict )
264263
265264 def __str__ (self ):
266- parts = ["<" + self . __class__ . __name__ ]
265+ parts = []
267266 for attr in dir (self .__class__ ):
268267 attribute_instance = getattr (self .__class__ , attr )
269268 if issubclass (attribute_instance .__class__ , AdvertisingDataField ):
269+ if (issubclass (attribute_instance .__class__ , LazyObjectField ) and
270+ not attribute_instance .advertising_data_type in self .data_dict ):
271+ # Skip uninstantiated lazy objects; if we get
272+ # their value, they will be be instantiated.
273+ continue
270274 value = getattr (self , attr )
271275 if value is not None :
272- parts .append (attr + "=" + str (value ))
273- parts .append (">" )
274- return " " .join (parts )
276+ parts .append ("{}={}" .format (attr , str (value )))
277+ return "<{} {} >" .format (self .__class__ .__name__ , " " .join (parts ))
275278
276279 def __len__ (self ):
277280 return compute_length (self .data_dict )
0 commit comments