def eddystone_url_adv_data(cls, url): log.info("Encoding URL for Eddystone beacon: '{}'".format(url)) encodedurl = cls.encode_url(url) encodedurlLength = len(encodedurl) if encodedurlLength > 18: raise ValueError( "Encoded url length {} is > 18 maximum length.".format( encodedurlLength)) message = [ 0x02, # Flags length 0x01, # Flags data type value 0x1a, # Flags data 0x03, # Service UUID length 0x03, # Service UUID data type value 0xaa, # 16-bit Eddystone UUID 0xfe, # 16-bit Eddystone UUID 5 + len(encodedurl), # Service Data length 0x16, # Service Data data type value 0xaa, # 16-bit Eddystone UUID 0xfe, # 16-bit Eddystone UUID 0x10, # Eddystone-url frame type 0xed, # txpower ] message += encodedurl return bytearray(message)
def test_eddystone(self): adapter = get_provider().get_adapter() beacon = EddystoneBeacon(adapter, 'https://www.google.com/') beacon.start() log.info("Starting beacon for {} seconds, url={}".format(BEACON_TIME, beacon.url)) sleep(BEACON_TIME) beacon.stop()
def eddystone_type_adv_data(cls, data, frame_type): log.info("Encoding data for Eddystone beacon: '{}'".format( edg_utils.bytes_to_hex(data))) data_len = len(data) print(("data_len:", data_len)) message = [ 0x02, # Flags length 0x01, # Flags data type value 0x1a, # Flags data 0x03, # Service UUID length 0x03, # Service UUID data type value 0xaa, # 16-bit Eddystone UUID 0xfe, # 16-bit Eddystone UUID 5 + len(data), # Service Data length 0x16, # Service Data data type value 0xaa, # 16-bit Eddystone UUID 0xfe, # 16-bit Eddystone UUID frame_type, # Eddystone-url frame type 0x00, # txpower ] message += data return bytearray(message)
def start_scanning(self): log.info("start scanning") if self.on_advertising_data: blesonwin.on_advertisement(self._on_advertising_data) else: log.warning("on_advertising_data is not set") log.info(self.on_advertising_data) blesonwin.start_observer()
def foo_data_adv_data(cls, data): log.info("Encoding data for Foo beacon: '{}'".format(data)) dataLength = len(data) if dataLength > 31: raise ValueError( "Encoded data length {} is > 31 maximum length.".format( dataLength)) return data
def test_advertiser(self): adapter = get_provider().get_adapter() advertisement = Advertisement() advertisement.name = 'bleson' advertiser = Advertiser(adapter) advertiser.advertisement = advertisement advertiser.start() log.info("Starting Advertiser role for {} seconds, advertised name={}". format(ADVERTISE_TIME, advertisement.name)) sleep(ADVERTISE_TIME) advertiser.stop()
def test_observer_advertiser_pair(self): # if not sys.platform.lower().startswith('linux'): # raise unittest.SkipTest("Dual adapter tests only run on Linux") # ---------------------------------------- # Setup the Observer, on adatper 0 observer = Observer(self.adapter0) # The observer callback records the found device BDAddress found_addresses = set() def advertisement_update(advertisement): log.info("Found: {}".format(advertisement)) found_addresses.add( advertisement.address) # instance of 'BDAddress' observer.on_advertising_data = advertisement_update # ---------------------------------------- # Setup the Advertiser, on adapter 1 advertiser = Advertiser(self.adapter1) advertisement = Advertisement() advertisement.name = "bleson" advertiser.advertisement = advertisement # ---------------------------------------- # Start the Observer and the Advertiser. observer.start() advertiser.start() # wait... log.info( "Starting Advertiser & Observer roles for {} seconds, advertised name={}" .format(TEST_DURATION_SECS, advertisement.name)) sleep(TEST_DURATION_SECS) # Stop advertiser.stop() observer.stop() # ---------------------------------------- # Did the left hand find the right hand? log.info("Observer's address: {}".format( self.adapter0.device.address)) log.info("Advertiser's address: {}".format( self.adapter1.device.address)) log.info("Observed BDAddresses: {}".format(found_addresses)) self.assertTrue(self.adapter1.device.address in found_addresses)
def _runloop_thread(self): try: with objc.autorelease_pool(): queue_ptr = objc.objc_object(c_void_p=self._dispatch_queue) self._manager = CoreBluetooth.CBCentralManager.alloc() self._manager.initWithDelegate_queue_options_( self, queue_ptr, None) #self._peripheral_manager = CoreBluetooth.CBPeripheralManager.alloc() #self._peripheral_manager.initWithDelegate_queue_options_(self, queue_ptr, None) self._runloop_started_lock.set() AppHelper.runConsoleEventLoop(installInterrupt=True) except Exception as e: log.exception(e) log.info("Exiting runloop")
def test_all_examples(self): path = os.path.abspath(__file__) dir_path = os.path.dirname(path) examples_path = os.path.join(dir_path, '..', 'examples') examples_glob = os.path.join(examples_path, '*.py') scripts = glob.glob(examples_glob) log.debug(scripts) for script in scripts: log.info("Running {}".format(script)) sys.argv = ['', str(TEST_DURATION)] # if sys.platform.lower().startswith('darwin'): # log.warning("Remove workaround for macOS native teardown issue") # os.system("python3 {} {}".format(script, TEST_DURATION)) # else: # runpy.run_path(script) runpy.run_path(script)
def test_observer(self): found_devices = set() observer = Observer(self.adapter) def advertisement_update(advertisement): if sys.platform.lower().startswith('darwin'): found_devices.add(advertisement.name) else: found_devices.add(advertisement.address) observer.on_advertising_data = advertisement_update observer.start() log.info("Starting Observer role for {} seconds".format(SCANTIME)) sleep(SCANTIME) observer.stop() log.info("Found: {}".format(found_devices)) # TODO: revert this simple test, only in place for infrastructure testing self.assertTrue(len(found_devices) > 0)
def test_observer_beacon_pair(self): # if not sys.platform.lower().startswith('linux'): # raise unittest.SkipTest("Dual adapter tests only run on Linux") observer = Observer(self.adapter0) found_addresses = set() def advertisement_update(advertisement): log.info("Found: {}".format(advertisement)) found_addresses.add( advertisement.address) # instance of 'BDAddress' observer.on_advertising_data = advertisement_update beacon = EddystoneBeacon(self.adapter1) # ---------------------------------------- # Start the Observer and the Advertiser. observer.start() beacon.start() # wait... log.info( "Starting Advertiser & Observer roles for {} seconds, advertised url={}" .format(TEST_DURATION_SECS, beacon.url)) sleep(TEST_DURATION_SECS) # Stop beacon.stop() observer.stop() # ---------------------------------------- # Did the left hand find the right hand? log.info("Observer's address: {}".format(self.adapter0.device.address)) log.info("Beacons's address: {}".format(self.adapter1.device.address)) log.info("Observed BDAddresses: {}".format(found_addresses)) self.assertTrue(self.adapter1.device.address in found_addresses)
def data(self, data): self._data = data if data: self.advertisement.raw_data = self.foo_data_adv_data(data) log.info("Beacon Adv raw data = {}".format( self.advertisement.raw_data))
#!/usr/bin/env python3 import sys from time import sleep from bleson import get_provider, Observer from bleson.logger import log, set_level, DEBUG #set_level(DEBUG) # Get the wait time from the first script argument or default it to 10 seconds WAIT_TIME = int(sys.argv[1]) if len(sys.argv) > 1 else 10 with Observer(get_provider().get_adapter(), lambda device: log.info(device)): sleep(WAIT_TIME)
def stop_scanning(self): log.info("stopping") blesonwin.stop_observer()
def advertisement_update(advertisement): log.info("Found: {}".format(advertisement)) found_addresses.add(advertisement.address) # instance of 'BDAddress'