from kivy.logger import Logger
from kivy.event import EventDispatcher
from jnius import autoclass, PythonJavaClass, java_method

BLE = autoclass('org.kivy.ble.BLE')

class BluetoothEventsListener(PythonJavaClass):
    __javainterfaces__ = ['org.kivy.ble.PythonBluetooth']
    __javacontext__ = 'app'

    def __init__(self):
        super(BluetoothEventsListener, self).__init__()

    @java_method('(Landroid/bluetooth/BluetoothDevice;I[B)V')
    def on_device(self, device, rssi, record):
        Logger.debug("on_device name: {}, signal: {}".format(device.getName(), rssi))

    @java_method('()V')
    def on_scan_completed(self):
        Logger.debug("on_scan_completed")

class BluetoothLowEnergy(EventDispatcher):

    enable_bluetooth_code = 1024

    def __init__(self):
        self._listener = BluetoothEventsListener()
        self._ble = BLE(self._listener)

    def start_scan(self, period):
        return self._ble.startScan(period, self.enable_bluetooth_code)


@@ -1,16 +1,51 @@
+from collections import namedtuple%0A
 from kivy.logger
@@ -156,17 +156,79 @@
 _method%0A
-%0A
+from kivy.utils import platform%0A%0Aif platform == 'android':%0A    
 BLE = au
@@ -1068,8 +1068,1197 @@
 _code)%0A%0A
+class Advertisement(object):%0A    %22%22%22Advertisement data record parser%0A%0A    %3E%3E%3E for ad in Advertisement(%5B2, 1, 0x6, 6, 255, 82, 83, 95, 82, 48%5D):%0A    ...     ad%0A    AD(ad_type=1, data=bytearray(b'%5C%5Cx06'))%0A    AD(ad_type=255, data=bytearray(b'RS_R0'))%0A    %3E%3E%3E Advertisement.ad_types.flags%0A    1%0A    %22%22%22%0A%0A    AD = namedtuple(%22AD%22, %5B'ad_type', 'data'%5D)%0A%0A    class ad_types:%0A        # https://www.bluetooth.org/en-us/specification/assigned-numbers/generic-access-profile%0A        flags = 0x01%0A        complete_local_name = 0x09%0A        manufacturer_specific_data = 0xff%0A%0A    def __init__(self, data):%0A        self.data = data%0A%0A    def __iter__(self):%0A        return Advertisement.parse(self.data)%0A%0A    @classmethod%0A    def parse(cls, data):%0A        pos = 0%0A        while pos %3C len(data):%0A            length = data%5Bpos%5D%0A            if length %3C 2:%0A                return%0A            try:%0A                ad_type = data%5Bpos + 1%5D%0A            except IndexError:%0A                return%0A            next_pos = pos + length + 1%0A            if ad_type:%0A                segment = slice(pos + 2, next_pos)%0A                yield Advertisement.AD(ad_type, bytearray(data%5Bsegment%5D))%0A            pos = next_pos%0A

add Advertisement data record parser