コード例 #1
0
def main():

    scanner = Scanner().withDelegate(ScanDelegate())

    device_list = scanner.scan(5)  # scan for 5 seconds
    for device in device_list:
        if (device.addr.lower() == DH_ADDRESS.lower()):
            print("Target device host discovered!")
            # RSSI = Received Signal Strength Indicator
            #print("Device %s (%s), RSSI=%d dB" % (device.addr, device.addrType, device.rssi ))
            scan_data = device.getScanData()
            device_name = scan_data[2][2]
            auth_service_uuid = scan_data[4][2]
            #print(device_name)
            #print(auth_service_uuid)
            #for (adtype,desc,value) in device.getScanData():
            #    print("\t%s = %s" % (desc, value))

    device = Peripheral(DH_ADDRESS)
    device.setMTU(520)
    device.setDelegate(PeripheralDelegate())
    print("Successfully connected to device host")
    auth_service = device.getServiceByUUID(auth_service_uuid)
    auth_char = auth_service.getCharacteristics()[0]
    # read authentication characteristic state

    #print(auth_char.valHandle)
    auth_char_cccd = auth_char.getHandle() + 1
    print("CCCD 0x%X" % auth_char_cccd)

    device.writeCharacteristic(auth_char_cccd, b"\x01\x00")

    #device.withDelegate(PeripheralDelegate())

    auth_char_val = auth_char.read()
    print(auth_char_val)
    #if(auth_char_val == 0):
    ##    print("Zero")

    # wait for server confirmation as a notification message
    while True:
        if (device.waitForNotifications(1.0)):
            print("new notification from server")
            continue
        print("Waiting...")
コード例 #2
0
ファイル: btle.py プロジェクト: DeShrike/experiments
class BtleDevice(DefaultDelegate):
    """Base class for a connection to a Bluetooth Low Energy device.

    Built on bluepy (which is built on bluez), and uses some bluepy classes,
    so this class is just a helper not really a full API.

    See https://ianharvey.github.io/bluepy-doc/index.html

    **** NOTE *****
    As of 2019-12-06, you have to fix a bug in the btle.py library:
    Comment out the _getResp in disconnect() or it can hang on readline
        when a 'stat disc' reply from the helper is overlooked (as in
        during a call to setMTU).
    **** NOTE *****
    """
    # Common Services:
    generic_access_service_uuid = UUID('1800')
    device_info_service_uuid = UUID('180a')

    # Common Descriptors:
    characteristic_description_uuid = UUID('2901')
    characteristic_configure_uuid = UUID('2902')

    # Common Characteristics:
    model_number_uuid = UUID('2a24')  # As string
    serial_number_uuid = UUID('2a25')  # As string
    firmware_revision_uuid = UUID('2a26')  # As string
    hardware_revision_uuid = UUID('2a27')  # As string
    manufacturer_name_uuid = UUID('2a29')  # As string

    def __init__(self, mac_addy, mtu=0xff, max_rate=10):
        """Connect to the device at the specified addy.

        Max_rate is the maximum rate in messages/second at which we will
            send messages to the device.  I imagine this could/should be
            automatically inferred from the Peripheral Preferred Connection
            Parameters, but that's above my pay grade.  All I know is,
            if you don't meter the outgoing messages, some peripherals
            will just start dropping requests, resulting in timeouts
            waiting for the acks.  For an Airthings Wave+, max_rate 10
            works with dumb throttling, or max_rate 5 with smart.  The
            whole issue seems fishy to me -- seems like the lower level
            protocols should handle this better.  But pragmatically, it
            regularly hangs without this.
        """
        DefaultDelegate.__init__(self)
        assert mac_addy

        self.mac_addy = mac_addy
        self.mtu = mtu
        self.min_delay = 1. / max_rate
        self.peripheral = None

        self.cache = None  # Will be dict mapping UUIDs to Characteristics; Created/cleared by connect()
        self.last_notification = None  # This is only used transiently by the default notification handler.  Ignore!

        if smart_throttle:
            self.last_xmt_time = 0  # Used to throttle outgoing messages.  Is the time() of last sent message (or 0)

    #=====
    # If you don't know the MAC address, you'll need to scan, but that requires root...
    #=====

    @staticmethod
    def scan(match=None, duration=5, just_one=False, match_scan_entry=False):
        """This looks through any advertising btle devices for matching ones.

        *** Note you must run this as root ***

        match(scan_data) should return True if scan_data is from the device you're looking for.

            If no match function is provided, it is treated as always returning True (you want
                to see all devices that respond within duration).

            scan_data is a dict mapping description to value, unless match_scan_entry is True
                in which case scan_data is a btle ScanEntry object.

        Duration is how many seconds to scan before returning.

        If just_one is False, scans for the full duration and then
            returns a list of matching ScanEntry objects. (https://ianharvey.github.io/bluepy-doc/scanentry.html)

        If just_one is True, this returns the first match immediately (no list)
            or None after full duration timeout.

        Note (match==None and just_one==True) results in just the first device
            to respond being immediately returned.
        """
        scanner = Scanner().withDelegate(DefaultDelegate())
        scanner.clear()
        scanner.start()
        if not just_one:
            found = []
        try:
            for i in range(max(int(duration * 10),
                               1)):  # Break duration into 10ths
                scanner.process(
                    0.1)  # Handle incoming messages for 1/10th of a second...
                devices = scanner.getDevices()
                for dev in devices:
                    if debug:
                        BtleDevice.dump_scan_entry(dev)
                    if match_scan_entry:
                        params = dev
                    else:
                        params = {
                            name: val
                            for tag, name, val in dev.getScanData()
                        }
                    if match is None or match(params):
                        if just_one:
                            return dev
                        else:
                            found.append(dev)
                scanner.clear()
        finally:
            scanner.stop()

        if just_one:
            return None
        return found

    def disconnect(self):
        """Do call this when you are done!
        (But no sooner.  This will automatically re-connect if you try to do anything after this...)
        """
        if self.peripheral is not None:
            if debug:
                print(
                    "Disconnecting."
                )  # TODO - need to wrap all these debugging messages in a better logger...
            self.throttle()
            self.peripheral.disconnect()
            self.peripheral = None
            self.cache = None
            return True
        return False

    def connect(self):
        """Optional: Connects to the device.

        Returns True if this causes the connection, or False if we were already connected.

        Most of the methods here will call this on-demand, so you only need to call this
            explicitly if you want to access self.peripheral directly straight away.
        """
        if self.peripheral is None:
            if debug:
                print("Connecting to %s." % (self.mac_addy, ))
            self.cache = {}
            self.peripheral = Peripheral(self.mac_addy).withDelegate(self)
            if self.mtu is not None:
                self.throttle()
                self.peripheral.setMTU(
                    self.mtu
                )  # Notification and Indications may not happen if we don't do this.
            return True
        return False

    #=====
    # Most of the good stuff is here -- ways to read and write values:
    #=====

    def __getitem__(self, char):
        """This reads and returns the current value of the given characteristic.
        Char can be a uuid string, UUID object, or Characteristic object.
        """
        self.throttle()
        return self.get_characteristic(char).read()

    def __setitem__(self, char, val):
        """This writes the byte array val to the specified characteristic.
        Char can be a uuid string, UUID object, or Characteristic object.
        """
        self.throttle()
        self.get_characteristic(char).write(val, True)

    def get_handle(self, char):
        """This returns the Handle (small integer) of the specified characteristic.
        Char can be a uuid string, UUID object, or Characteristic object.
        Mainly useful to compare to the handle returned by wait_for_notification().
        """
        return self.get_characteristic(char).getHandle()

    def get_characteristic(self, uuid):
        """If you're just doing basic sets, queries and commands with the high
            level interface you probably don't need to call this directly.

        This accepts strings or UUID objects and returns the associated
            Characteristic object.  (Or the first one if there are multiple
            with the same UUID.  So, this is mainly useful for high level
            variables, not for meta information attributes or such.)
        As a convenience, if you pass a Characteristic, this will return it.
            (Which is useful for functions that want to allow flexible
            identification of the Characteristic.)
        Results are cached for efficiency, so don't be shy about using it.
        Raises KeyError if uuid can't be found.
        """
        self.connect()
        if isinstance(uuid, Characteristic):
            return uuid
        if not isinstance(uuid, UUID):
            uuid = UUID(uuid)
        if uuid not in self.cache:
            self.throttle()
            c = self.peripheral.getCharacteristics(uuid=uuid)
            if c:
                self.cache[uuid] = c[0]
            else:
                self.cache[uuid] = None
        c = self.cache[uuid]
        if c is None:
            raise KeyError("Can't find characteristic %s" % (uuid, ))
        return c

    #=====
    # If you want Notifications or Indications, you need to enable each characteristic accordingly.
    #=====

    def can_notify(self, char):
        """Returns non-zero if this characteristic can generate Notifications or Indications.

        Char can be a uuid string, UUID object, or Characteristic object.

        Technically the return value can be further inspected to discern whether it
            supports Notifications, Indications, or (does this ever happen?) both.
        """
        char = self.get_characteristic(char)
        return char.properties & (char.props['INDICATE']
                                  | char.props['NOTIFY'])

    def enable(self, char):
        """Usually this is the easiest way to enable notifications from a characteristic.

        You have to call this (or one of the more specific ones below) before you will
            get any notifications from a given Characteristic.

        This enables characteristic char for either Indications or Notifications depending
            on which sort it claims to generate.

        Char can be a uuid string, UUID object, or Characteristic object.
        """
        char = self.get_characteristic(char)
        if char.properties & char.props['INDICATE']:
            self.configure_characteristic(char, 2)
        elif char.properties & char.props['NOTIFY']:
            self.configure_characteristic(char, 1)
        else:
            raise Exception(
                "Characteristic does not support any notifications: %s" %
                (char, ))

    def disable(self, char):
        self.configure_characteristic(char, 0)

    def wait_for_notification(self, timeout):
        """This waits for the next notification and then returns it
            as a (handle, data) tuple.

        This only works if you do not override handleNotifications.

        This only handles notifications that come in during this call.
            If you call this successively, you should catch all notifications
            as long as you don't make any other Btle calls in between (since
            those calls could let a notification slip into the gap).

        Returns None on timeout.
        """
        try:
            self.last_notification = False  # False means we're waiting; None means we're not!
            if self.peripheral.waitForNotifications(timeout):
                return self.last_notification  # Python should grab it before the finally clause resets it...
            else:
                return (None, None)
        finally:
            self.last_notification = None  # Make sure handleNotifications alerts us to notifications that come out of band.

    def handleNotification(self, handle, data):
        """Subclass can override this to do whatever it wants with notifications/indications.
        """
        if self.last_notification is None:
            # Don't put this under Debug flag.  This alerts you to Notifications you aren't handling yet...
            print("UNHANDLED NOTIFICATION: handle=%r data=%r" %
                  (handle, data.hex()))
        else:
            self.last_notification = (handle, data)

    #--- Unlikely you need to call any of these directly:

    def enable_notifications(self, char):
        """If you want to get Notifications from a characteristic, you need to call this first.
        Char can be a uuid string, UUID object, or Characteristic object.
        Note this also disables Indications for this characteristic.  Use configure_characteristic to enable both.
        """
        self.configure_characteristic(char, 1)

    def enable_indications(self, char):
        """If you want to get value Indications from a characteristic, you need to call this first.
        Char can be a uuid string, UUID object, or Characteristic object.
        Note this also disables Notifications for this characteristic.  Use configure_characteristic to enable both.
        """
        self.configure_characteristic(char, 2)

    def configure_characteristic(self, char, val):
        """This looks up the handle for the configuration descriptor for this characteristic,
            and then sends val to it.
        Char can be a uuid string, UUID object, or Characteristic object.
        Typically val here is 1 (enable Notifications) or 2 (enable Indications) or 0 (disable).
        """
        char = self.get_characteristic(char)
        if debug:
            print("Finding configuration descriptor for handle 0x%x" %
                  (char.getHandle(), ))
        self.throttle()
        d, = char.getDescriptors(forUUID=self.characteristic_configure_uuid)
        if debug:
            print("Found (handle 0x%x).  Setting to 0x%02x" % (d.handle, val))
        self.throttle()
        d.write(struct.pack('<H', val), True)

    def throttle(self):
        """This internal utility just waits until self.min_delay from the
            last time this method was called.
        """
        if smart_throttle:
            now = time()
            delay = self.last_xmt_time + self.min_delay - now
            if delay > 0:
                sleep(delay)
                now += delay
            self.last_xmt_time = now
        else:
            sleep(self.min_delay)

    #=====
    # Below here are just utilities for displaying the device's data layout,
    # Which also serve as examples of how to access the devices's attributes.
    #=====

    def dump_services(self, read=False, indent=''):
        """This calls dump_service on all services this device provides.
        If read is True, it reads and prints each characteristic's value.

        This is a good way to manually discover the layout of your device.
        """
        self.connect()
        for s in self.peripheral.getServices():
            self.dump_service(s, read, indent)

    def dump_service(self, service, read=False, indent=''):
        """This calls dump_characteristic on all the characteristics in the given service.
        If service is not a Service object, it's assumed to be a UUID and the service
            will be looked up by that.
        """
        self.connect()

        if not isinstance(service, Service):
            try:
                service = self.peripheral.getServiceByUUID(service)
            except BTLEEException:
                print("%sService %r: NOT FOUND" % (indent, service))
                return

        print("%sService %r (%s):" %
              (indent, service.uuid.getCommonName(), service.uuid))
        for c in service.getCharacteristics():
            self.dump_characteristic(c, read, indent + "    ")

    def dump_characteristic(self, c, read=False, indent=''):
        """Dumps whatever we can find out about a characteristic.
        If read is True, also reads and prints its value (when applicable)
        """
        print("%sCharacteristic %r (%s):" %
              (indent, c.uuid.getCommonName(), c.uuid))
        print("%s          Handle: %s (%x)" %
              (indent, c.getHandle(), c.getHandle()))
        print("%s        Readable: %s" % (
            indent,
            c.supportsRead(),
        ))
        print("%s      Properties: %s" % (
            indent,
            c.propertiesToString(),
        ))

        try:
            descriptors = c.getDescriptors()
        except BTLEGattError:
            pass
        else:
            for d in descriptors:
                print("%s      Descriptor: %s (handle 0x%x; uuid %s)" %
                      (indent, d, d.handle, d.uuid))
                if d.uuid == self.characteristic_description_uuid:
                    self.throttle()
                    print("%s          ------> %r" % (indent, d.read()))

        if c.supportsRead():
            try:
                self.throttle()
                val = c.read()
            except:
                print("%s    (Read) Value: [READ FAILED]" % (indent, ))
            else:
                print("%s    (Read) Value: %s (0x%s)" %
                      (indent, val, val.hex()))

    @staticmethod
    def dump_scan_entry(se):
        """Just prints the info that comes back from a Scan response.
        """
        print("Scanned Device:")
        print("              MAC: %s" % (se.addr, ))
        print("        Addr Type: %s" % (se.addrType, ))
        print("  Signal Strength: %s dB" % (se.rssi, ))
        print("      Connectable: %s" % (se.connectable, ))
        print("     Update Count: %s" % (se.updateCount, ))
        for t in se.getScanData():
            print("  %r" % (t, ))
コード例 #3
0
def scan_and_connect( is_first = True ):
    global SCAN_TIME
    global TARGET_MANUFA_UUID
    global TARGET_DEVICE_NAME
    global gTargetDevice
    #
    # scanning for a while
    #
    scanner = Scanner().withDelegate(ScanDelegate())
    if is_first:
        print ("+--- BLE Device scan started..." )
    else:
        print ("+--- BLE Device scan restarted..." )    
    devices = scanner.scan(SCAN_TIME)
    print ("\n+--- BLE Device scan completed... [%d] devices are scanned" % gScannedCount)
    #
    # check to match BOSCH SCD device identifiers
    #
    for dev in devices:
        matching_count = 0
        for (adtype, desc, value) in dev.getScanData():
            if adtype == 255 and TARGET_MANUFA_UUID in value:
                matching_count += 1
                print("\tfound target (AD Type=%d) '%s' is '%s'" % (adtype, desc, value))            
            if adtype == 9 and TARGET_DEVICE_NAME in value:
                matching_count += 1
                print("\tfound target (AD Type=%d) '%s' is '%s'" % (adtype, desc, value))            
            if matching_count >= 2:
                print("+--- Device address [%s], type=[%s], RSSI=[%d]dB" % (dev.addr, dev.addrType, dev.rssi))
                print("\tfound BOSCH SCD device!")
                gTargetDevice = dev
                break
        if gTargetDevice != None:
            break
    #
    # if none found then exiting    
    #
    if gTargetDevice == None:
        print("No matching device found... Exiting...")
        sys.exit(1)
    #
    # connect
    #
    print("+--- Connecting [%s], type=[%s]" % (gTargetDevice.addr, gTargetDevice.addrType))
    p = None
    retry = 0
    while p == None:
        try:
            p = Peripheral(gTargetDevice.addr, gTargetDevice.addrType)
        except:
            print("BLE Device connection error occured... Retry after 3 sec...")
            retry += 1
            if retry > 3:
                print("BLE Device connection error occured... Exiting...")
                sys.exit(-1)
            time.sleep(3)    
    #
    # should increase MTU
    #           
    p.setMTU(SCD_MAX_MTU)
    return p
コード例 #4
0
def SCD_scan_and_connect( is_first = True ):
    global gTargetDevice
    #
    # scanning for a while
    #
    print ("SCD> BLE device scan %sstarted..." % ('re' if not is_first else ''), flush=True)

    tm = tm_s = time.time()
    while tm_s - tm < RESCAN_PERIOD:
        scanner = Scanner().withDelegate(ScanDelegate())
        devices = scanner.scan(SCAN_TIME)
        print ("\nSCD> BLE device scan completed... [%d] devices are scanned" % gScannedCount, flush=True)
        #
        # check to match BOSCH SCD device identifiers
        #
        for dev in devices:
            matching_count = 0
            for (adtype, desc, value) in dev.getScanData():
                if adtype == 255 and TARGET_MANUFA_UUID in value:
                    matching_count += 1
                    print("SCD> => found target (AD Type=%d) '%s' is '%s'" % (adtype, desc, value), flush=True)            
                if adtype == 9 and TARGET_DEVICE_NAME in value:
                    matching_count += 1
                    print("SCD> => found target (AD Type=%d) '%s' is '%s'" % (adtype, desc, value), flush=True)            
                if matching_count >= 2:
                    print("SCD> => found BOSCH SCD device!")
                    print("SCD> device address [%s], type=[%s], RSSI=[%d]dB" % (dev.addr, dev.addrType, dev.rssi), flush=True)
                    gTargetDevice = dev
                    break
            if gTargetDevice != None:
                break
        #
        # if none found then exiting    
        #
        if gTargetDevice == None:
            tm = time.time()
            print("SCD> no matching device found at [%s]... retry after %d sec..." \
                  % (datetime.datetime.fromtimestamp(tm).strftime('%Y-%m-%d %H:%M:%S'), RESCAN_INTERVAL), flush=True )
            if tm_s - tm >= RESCAN_PERIOD:
                print("SCD> no matching device found... exiting...", flush=True)
                sys.exit(-1)
            time.sleep(RESCAN_INTERVAL)
        else:
            break        
    #
    # connect
    #
    print("SCD> connecting [%s], type=[%s]" % (gTargetDevice.addr, gTargetDevice.addrType), flush=True)
    p = None
    retry = 0
    while p == None:
        try:
            p = Peripheral(gTargetDevice.addr, gTargetDevice.addrType)
        except:
            retry += 1
            print("SCD> => BLE device connection error occured [%d] time(s)... retry after 10 sec..." % retry, flush=True)
            if retry > 30:
                print("SCD> => BLE device connection error occured... exiting...", flush=True)
                sys.exit(-1)
            time.sleep(10)    
    #
    # should increase MTU##
    #           
    p.setMTU(SCD_MAX_MTU)
    #
    return p
コード例 #5
0
ファイル: gforce.py プロジェクト: lyfhouyi/gForceSDKPython
class GForceProfile():
    def __init__(self):
        self.device = Peripheral()
        self.state = BluetoothDeviceState.disconnected
        self.cmdCharacteristic = None
        self.notifyCharacteristic = None
        self.timer = None
        self.cmdMap = {}
        self.mtu = None
        self.cmdForTimeout = -1
        self.incompleteCmdRespPacket = []
        self.lastIncompleteCmdRespPacketId = 0
        self.incompleteNotifPacket = []
        self.lastIncompleteNotifPacketId = 0
        self.onData = None
        self.lock = threading.Lock()
        self.send_queue = queue.Queue(maxsize=20)

    def getCharacteristic(self, device, uuid):
        ches = device.getCharacteristics()
        for ch in ches:
            if uuid == str(ch.uuid):
                return ch
            else:
                continue

    # Establishes a connection to the Bluetooth Device.
    def connect(self, addr):
        self.device.connect(addr)
        print('connection succeeded')

        # set mtu
        MTU = self.device.setMTU(200)
        self.mtu = MTU['mtu'][0]
        # self.device.setMTU(self.mtu)
        # print('mtu:{}'.format(self.mtu))

        self.state = BluetoothDeviceState.connected

        self.cmdCharacteristic = self.getCharacteristic(self.device, CMD_NOTIFY_CHAR_UUID)
        self.notifyCharacteristic = self.getCharacteristic(
            self.device, DATA_NOTIFY_CHAR_UUID)

        # Listen cmd
        self.setNotify(self.cmdCharacteristic, True)

        # Open the listening thread
        self.device.setDelegate(MyDelegate(self))

    # Connect the bracelet with the strongest signal

    def connectByRssi(self):
        scanner = Scanner()
        devices = scanner.scan(10.0)
        rssi_devices = {}

        for dev in devices:
            print("Device %s (%s), RSSI=%d dB" %
                  (dev.addr, dev.addrType, dev.rssi))
            for (_, desc, value) in dev.getScanData():
                print("  %s = %s" % (desc, value))
                if (value == SERVICE_GUID):
                    rssi_devices[dev.rssi] = dev.addr

        rssi = rssi_devices.keys()
        dev_addr = rssi_devices[max(rssi)]

        # connect the bracelet
        self.device.connect(dev_addr)
        print('connection succeeded')

        # set mtu
        MTU = self.device.setMTU(2000)
        self.mtu = MTU['mtu'][0]
        # self.device.setMTU(self.mtu)
        # print('mtu:{}'.format(self.mtu))

        self.state = BluetoothDeviceState.connected

        self.cmdCharacteristic = self.getCharacteristic(self.device, CMD_NOTIFY_CHAR_UUID)
        self.notifyCharacteristic = self.getCharacteristic(
            self.device, DATA_NOTIFY_CHAR_UUID)

        # Listen cmd
        self.setNotify(self.cmdCharacteristic, True)

        # Open the listening thread
        self.device.setDelegate(MyDelegate(self))

    # Enable a characteristic's notification
    def setNotify(self, Chara, swich):
        if swich:
            setup_data = b"\x01\x00"
        else:
            setup_data = b"\x00\x00"

        setup_handle = Chara.getHandle() + 1
        self.device.writeCharacteristic(
            setup_handle, setup_data, withResponse=False)

    def scan(self, timeout):
        scanner = Scanner()
        devices = scanner.scan(timeout)

        gforce_scan = []
        i = 1
        for dev in devices:
            for (_, _, value) in dev.getScanData():
                if (value == SERVICE_GUID):
                    gforce_scan.append([i, dev.getValueText(
                        9), dev.addr, dev.rssi, str(dev.connectable)])
                    i += 1
        return gforce_scan

    # Disconnect from device
    def disconnect(self):

        if self.timer != None:
            self.timer.cancel()
        self.timer = None
        # Close the listenThread

        if self.state == BluetoothDeviceState.disconnected:
            return True
        else:
            self.device.disconnect()
            self.state == BluetoothDeviceState.disconnected

    # Set data notification flag
    def setDataNotifSwitch(self, flags, cb, timeout):

        # Pack data
        data = []
        data.append(CommandType['CMD_SET_DATA_NOTIF_SWITCH'])
        data.append(0xFF & (flags))
        data.append(0xFF & (flags >> 8))
        data.append(0xFF & (flags >> 16))
        data.append(0xFF & (flags >> 24))
        data = bytes(data)

        def temp(resp, respData):
            if cb != None:
                cb(resp)

        # Send data
        return self.sendCommand(ProfileCharType.PROF_DATA_CMD, data, True, temp, timeout)

    # def switchToOAD(self,cb,timeout):
    #     # Pack data
    #     data = []
    #     data.append(CommandType['CMD_SWITCH_TO_OAD'])
    #     data = bytes(data)
    #     def temp(resp,respData):
    #         if cb != None:
    #             cb(resp,None)

    #     # Send data
    #     return self.sendCommand(ProfileCharType.PROF_DATA_CMD,data,True,temp,timeout)

    def powerOff(self, timeout):
        # Pack data
        data = []
        data.append(CommandType['CMD_POWEROFF'])
        data = bytes(data)

        def temp(resp, respData):
            pass

        # Send data
        return self.sendCommand(ProfileCharType.PROF_DATA_CMD, data, True, temp, timeout)

    def systemReset(self, timeout):
        # Pack data
        data = []
        data.append(CommandType['CMD_SYSTEM_RESET'])
        data = bytes(data)

        def temp(resp, respData):
            pass

        # Send data
        return self.sendCommand(ProfileCharType.PROF_DATA_CMD, data, True, temp, timeout)

    def setMotor(self, switchStatus, cb, timeout):
        data = []
        data.append(CommandType['CMD_MOTOR_CONTROL'])

        tem = 0x01 if switchStatus else 0x00
        data.append(tem)
        data = bytes(data)

        def temp(resp, respData):
            if cb != None:
                cb(resp)

        # send data
        return self.sendCommand(ProfileCharType.PROF_DATA_CMD, data, True, temp, timeout)

    def setLED(self, switchStatus, cb, timeout):
        data = []
        data.append(CommandType['CMD_LED_CONTROL_TEST'])

        tem = 0x01 if switchStatus else 0x00
        data.append(tem)
        data = bytes(data)

        def temp(resp, respData):
            if cb != None:
                cb(resp)

        # send data
        return self.sendCommand(ProfileCharType.PROF_DATA_CMD, data, True, temp, timeout)

    # Get controller firmware version
    def setLogLevel(self, logLevel, cb, timeout):
        # Pack data
        data = []
        data.append(CommandType['CMD_SET_LOG_LEVEL'])
        data.append(0xFF & logLevel)
        data = bytes(data)

        def temp(resp, respData):
            if cb != None:
                cb(resp)

        # Send data
        return self.sendCommand(ProfileCharType.PROF_DATA_CMD, data, True, temp, timeout)

    # Set Emg Raw Data Config
    def setEmgRawDataConfig(self, sampRate, channelMask, dataLen, resolution, cb, timeout):
       # Pack data
        data = b''
        data += struct.pack('<H', sampRate)
        data += struct.pack('<H', channelMask)
        data += struct.pack('<B', dataLen)
        data += struct.pack('<B', resolution)

        data += struct.pack('<B', CommandType['CMD_SET_EMG_RAWDATA_CONFIG'])

        def temp(resp, raspData):
            if cb != None:
                cb(resp)

        # Send data
        return self.sendCommand(ProfileCharType.PROF_DATA_CMD, data, True, temp, timeout)

    # Get Emg Raw Data Config
    def getEmgRawDataConfig(self, cb, timeout):
        # Pack data
        data = []
        data.append(CommandType['CMD_GET_EMG_RAWDATA_CONFIG'])
        data = bytes(data)

        def temp(resp, respData):
            if cb != None:
                if resp != ResponseResult['RSP_CODE_SUCCESS']:
                    cb(resp, None, None, None, None)
                elif len(respData) == 6:
                    sampRate, channelMask, dataLen, resolution = struct.unpack_from(
                        '@HHBB', respData)
                cb(resp, sampRate, channelMask, dataLen, resolution)

        return self.sendCommand(ProfileCharType.PROF_DATA_CMD, data, True, temp, timeout)

    def getFeatureMap(self, cb, timeout):
        # Pack data
        data = []
        data.append(CommandType['CMD_GET_FEATURE_MAP'])
        data = bytes(data)

        def temp(resp, respData):
            if cb != None:
                if resp != ResponseResult['RSP_CODE_SUCCESS']:
                    cb(resp)
                elif len(respData) == 4:
                    featureMap = struct.unpack('@I', respData)[0]
                    cb(resp, featureMap)
        return self.sendCommand(ProfileCharType.PROF_DATA_CMD, data, True, temp, timeout)

    # Get controller firmware version
    def getControllerFirmwareVersion(self, cb, timeout):
        # Pack data
        data = []
        data.append(CommandType['CMD_GET_FW_REVISION'])
        data = bytes(data)

        def temp(resp, respData):
            if cb != None:
                if resp != ResponseResult['RSP_CODE_SUCCESS']:
                    cb(resp)
                else:
                    if len(respData) > 4:
                        firmwareVersion = respData.decode('ascii')
                    else:
                        firmwareVersion = ''
                        for i in respData:
                            firmwareVersion += str(i)+'.'
                        firmwareVersion = firmwareVersion[0:len(
                            firmwareVersion)]
                    cb(resp, firmwareVersion)
        return self.sendCommand(ProfileCharType.PROF_DATA_CMD, data, True, temp, timeout)

    def sendCommand(self, type, data, hasResponse, cb, timeout):
        if hasResponse and cb != None:
            cmd = data[0]

            self.lock.acquire()

            if cmd in self.cmdMap.keys():
                self.lock.release()
                return GF_RET_CODE.GF_ERROR_DEVICE_BUSY
            self.cmdMap[cmd] = CommandCallbackTableEntry(
                cmd, datetime.now()+timedelta(milliseconds=timeout), cb)
            self._refreshTimer()
            self.lock.release()

        if type == ProfileCharType.PROF_DATA_CMD:
            if self.cmdCharacteristic == None:
                return GF_RET_CODE.GF_ERROR_BAD_STATE
            else:
                if len(data) > self.mtu:
                    contentLen = self.mtu - 2
                    packetCount = (len(data)+contentLen-1)//contentLen
                    startIndex = 0
                    buf = []

                    for i in range(packetCount-1, 0, -1):
                        buf.append(CommandType['CMD_PARTIAL_DATA'])
                        buf.append(i)
                        buf += data[startIndex:startIndex+contentLen]
                        startIndex += contentLen
                        self.send_queue.put_nowait(buf)
                        buf.clear()
                    # Packet end
                    buf.append(CommandType['CMD_PARTIAL_DATA'])
                    buf.append(0)
                    buf += data[startIndex:]
                    self.send_queue.put_nowait(buf)
                else:
                    self.send_queue.put_nowait(data)

                return GF_RET_CODE.GF_SUCCESS
        else:
            return GF_RET_CODE.GF_ERROR_BAD_PARAM

    # Refresh time,need external self.lock
    def _refreshTimer(self):
        def cmp_time(cb):
            return cb._timeoutTime

        if self.timer != None:
            self.timer.cancel()

        self.timer = None
        cmdlist = self.cmdMap.values()

        if len(cmdlist) > 0:
            cmdlist = sorted(cmdlist, key=cmp_time)

        # Process timeout entries
        timeoutTime = None
        listlen = len(cmdlist)

        for i in range(listlen):
            timeoutTime = cmdlist[0]._timeoutTime
            print('_'*40)
            print('系统时间:', datetime.now())
            print('超时时间:', timeoutTime)
            print('\ncmd: {0}, timeout: {1}'.format(
                hex(cmdlist[0]._cmd), timeoutTime < datetime.now()))
            print('_'*40)

            if timeoutTime > datetime.now():
                self.cmdForTimeout = cmdlist[0]._cmd
                ms = int((timeoutTime.timestamp() -
                          datetime.now().timestamp())*1000)

                if ms <= 0:
                    ms = 1
                self.timer = threading.Timer(ms/1000, self._onTimeOut)
                self.timer.start()

                break

            cmd = cmdlist.pop(0)

            if cmd._cb != None:
                cmd._cb(ResponseResult['RSP_CODE_TIMEOUT'], None)

    def startDataNotification(self, onData):

        self.onData = onData

        try:
            self.setNotify(self.notifyCharacteristic, True)
            success = True
        except:
            success = False

        if success:
            return GF_RET_CODE.GF_SUCCESS
        else:
            return GF_RET_CODE.GF_ERROR_BAD_STATE

    def stopDataNotification(self):
        try:
            self.setNotify(self.notifyCharacteristic, False)
            success = True
        except:
            success = False

        if success:
            return GF_RET_CODE.GF_SUCCESS
        else:
            return GF_RET_CODE.GF_ERROR_BAD_STATE

    def handleDataNotification(self, data, onData):
        fullPacket = []

        if len(data) >= 2:
            if data[0] == NotifDataType['NTF_PARTIAL_DATA']:
                if self.lastIncompleteNotifPacketId != 0 and self.lastIncompleteNotifPacketId != data[1]+1:
                    print('Error:lastIncompleteNotifPacketId:{0},current packet id:{1}'.format(
                        self.lastIncompleteNotifPacketId, data[1]))
                    # How to do with packet loss?
                    # Must validate packet len in onData callback!

                if self.lastIncompleteNotifPacketId == 0 or self.lastIncompleteNotifPacketId > data[1]:
                    # Only accept packet with smaller packet num
                    self.lastIncompleteNotifPacketId = data[1]
                    self.incompleteNotifPacket += data[2:]

                    if self.lastIncompleteNotifPacketId == 0:
                        fullPacket = self.incompleteNotifPacket
                        self.incompleteNotifPacket = []

            else:
                fullPacket = data

        if len(fullPacket) > 0:
            onData(fullPacket)

    # Command notification callback
    def _onResponse(self, data):
        print('_onResponse: data=', data)

        fullPacket = []

        if len(data) >= 2:
            if data[0] == ResponseResult['RSP_CODE_PARTIAL_PACKET']:
                if self.lastIncompleteCmdRespPacketId != 0 and self.lastIncompleteCmdRespPacketId != data[1] + 1:
                    print('Error: _lastIncompletePacketId:{0}, current packet id:{1}'
                          .format(self.lastIncompleteCmdRespPacketId, data[1]))

                if (self.lastIncompleteCmdRespPacketId == 0 or self.lastIncompleteCmdRespPacketId > data[1]):
                    self.lastIncompleteCmdRespPacketId = data[1]
                    self.incompleteCmdRespPacket += data[2:]
                    print('_incompleteCmdRespPacket 等于 ',
                          self.incompleteCmdRespPacket)

                    if self.lastIncompleteCmdRespPacketId == 0:
                        fullPacket = self.incompleteCmdRespPacket
                        self.incompleteCmdRespPacket = []
            else:
                fullPacket = data

        if fullPacket != None and len(fullPacket) >= 2:
            resp = fullPacket[0]
            cmd = fullPacket[1]

            # Delete command callback table entry & refresh timer's timeout

            self.lock.acquire()

            if cmd > 0 and self.cmdMap.__contains__(cmd):
                cb = self.cmdMap[cmd]._cb

                del self.cmdMap[cmd]

                self._refreshTimer()

                if cb != None:
                    cb(resp, fullPacket[2:])

            self.lock.release()

    # Timeout callback function
    def _onTimeOut(self):
        print('_onTimeOut: _cmdForTimeout={0}, time={1}'.format(
            self.cmdForTimeout, datetime.now()))

        # Delete command callback table entry & refresh timer's timeout

        cb = None
        self.lock.acquire()

        if self.cmdForTimeout > 0 and self.cmdMap.__contains__(self.cmdForTimeout):
            cb = self.cmdMap[self.cmdForTimeout]._cb
            del self.cmdMap[self.cmdForTimeout]

        self._refreshTimer()

        self.lock.release()

        if cb != None:
            cb(ResponseResult['RSP_CODE_TIMEOUT'], None)
コード例 #6
0
mac = '00:a0:50:9e:2b:a7'


class delega(DefaultDelegate):
    def __init__(self):
        DefaultDelegate.__init__(self)

    def handleNotification(self, cHandle, data):
        print(data)


crtS = None
crtL = None

dev = Peripheral(mac)
dev.setMTU(1000)

dlg = delega()
dev.withDelegate(dlg)

srvz = dev.getServices()
for srv in srvz:
    crt = srv.getCharacteristics()
    for c in crt:
        cuuid = c.uuid.getCommonName()
        pts = c.propertiesToString()
        print(cuuid + ' : ' + pts)
        # if c.supportsRead():
        #     r = c.read()
        #     print(str(r))
        if str(c.uuid) == cuuid:
コード例 #7
0
def scanForNistSensors():

    scanner = Scanner().withDelegate(ScanDelegate())
    scanner.scan(.1)

    if foundNistSensor == 0:
        print "Didn't find any nist sensors..."
        return False

    p = Peripheral(esp32Address)
    p.setMTU(500)

    #svcList = p.getServices()
    #print "Handle   UUID                                Properties"
    #print "-------------------------------------------------------"
    #for svc in svcList:
    #      print (str(svc.uuid))
    
    #chList = p.getCharacteristics()
    #print "Handle   UUID                                Properties"
    #print "-------------------------------------------------------"
    #for ch in chList:
    #         print ("  0x"+ format(ch.getHandle(),'02X')  +"   "+str(ch.uuid) +" " + ch.propertiesToString())

    nist_service_uuid = UUID("0000ffe0-0000-1000-8000-00805f9b34fb")
    nist_characteristic_uuid = UUID("beb5483e-36e1-4688-b7f5-ea07361b26a8")

    nistService = p.getServiceByUUID(nist_service_uuid)
    #nistCharacteristic = p.getCharacteristics(nist_characteristic_uuid)[0]
    nistCharacteristic = nistService.getCharacteristics("beb5483e-36e1-4688-b7f5-ea07361b26a8")[0]

    #readBytes = bytes(p.readCharacteristic(0x2A))
    #readBytes = bytes(nistCharacteristic.read())

    #print binascii.hexlify(readBytes)

    #with open('/home/pi/Desktop/esp32-ndn-ble/src/readBytes.txt', 'a') as the_file:
    #      the_file.seek(0)
    #      the_file.truncate()
    #      the_file.write(binascii.hexlify(readBytes))

    #TlvData = Blob(readBytes)

    #data = Data()
    #data.wireDecode(TlvData)

    # Use a hard-wired secret for testing. In a real application the signer
    # ensures that the verifier knows the shared key and its keyName.
    key = Blob(bytearray([
       0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
      16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
    ]))

    #if KeyChain.verifyDataWithHmacWithSha256(data, key):
    #  dump("Hard-coded data signature verification: VERIFIED")
    #else:
    #  dump("Hard-coded data signature verification: FAILED")

    freshData = Data(Name("/netInfo"))
    signature = HmacWithSha256Signature()
    signature.getKeyLocator().setType(KeyLocatorType.KEYNAME)
    signature.getKeyLocator().setKeyName(Name("key1"))
    freshData.setSignature(signature)
    freshData.setContent("EdwardPi\n11111111\n192.168.4.1\n")
    dump("Signing fresh data packet", freshData.getName().toUri())
    KeyChain.signWithHmacWithSha256(freshData, key)

    if KeyChain.verifyDataWithHmacWithSha256(freshData, key):
      dump("Freshly-signed data signature verification: VERIFIED")
    else:
      dump("Freshly-signed data signature verification: FAILED")

    bytesSend = freshData.wireEncode()

    print binascii.hexlify(bytes(bytesSend))

    try:
        nistCharacteristic.write(bytes(bytesSend), True)
    except:
        print "Exception when trying to write to BLE characteristic."
コード例 #8
0
     # sys.exit()
 print(
     "line 58--waiting device to ble mode , just open blue light or ctrl+c "
 )
 try:
     p = Peripheral(roehladdress, "public")
 except Exception:
     print("--Peripheral-reset--or ctrl+c")
     scanner = None
     p = None
     ch_name = None
     ch_result = None
     ch_write = None
     continue
 print("line 60-- going ")
 p.setMTU(100)
 # ch = p.getCharacteristics(uuid=temp_uuid)[0]
 print("-----")
 # print(ch.read())
 try:
     service = p.getServiceByUUID(service_uuid)
 except Exception:
     print("------")
     print("--getServiceByUUID reset---or ctrl+c ")
     p.disconnect()
     scanner = None
     p = None
     ch_name = None
     ch_result = None
     ch_write = None
     continue
コード例 #9
0
class blePeripheral(object):
    def __init__(self, addr, mtu):
        self.peripheral = Peripheral(addr, "public")
        self.mtu = mtu
        self.peripheral.setMTU(self.mtu)
        self.dt = None
        self.setDateTime(datetime.datetime.now())
        self.data = ""

    def getAddress(self):
        return self.peripheral.addr

    def disconnect(self):
        try:
            self.peripheral.disconnect()
        except Exception as e:
            raise (e)
        else:
            print("Peripheral disconnected!")
            return

    def acquireService(self, uuid=None):
        if not uuid:
            return self.peripheral.getServices()
        else:
            return self.peripheral.getServiceByUUID(uuid)

    def getCharacteristics(self, uuid=None, sFlag=True):
        if sFlag:
            services = self.acquireService(uuid)

            if uuid:
                return services.getCharacteristics()
            else:
                characteristics = dict()

                for service in services:
                    characteristics[
                        service.uuid] = service.getCharacteristics()

                return characteristics

        else:
            if uuid:
                return self.peripheral.getCharacteristics(uuid=uuid)
            else:
                return self.peripheral.getCharacteristics()

    def enableNotify(self, uuid):
        if not uuid:
            print("Needs a valid UUID to enable notifications.")
            return
        else:
            setup_data = b'\x01\x00'
            char = self.getCharacteristics(uuid=uuid)[0]
            notifyHandle = char.getHandle() + 1
            self.peripheral.writeCharacteristic(notifyHandle,
                                                setup_data,
                                                withResponse=True)

    def setData(self, data):
        self.data = data

    def getData(self):
        return self.data

    def setDateTime(self, dt):
        self.dt = datetime.datetime.strftime(dt, "%d-%m-%Y %H:%M:%S")

    def getDateTime(self):
        return self.dt

    def writeData(self, uuid=None, data=None):
        try:
            self.getCharacteristics(uuid=uuid, sFlag=False)[0].write(data)
        except Exception as e:
            raise (e)
        else:
            print("successfully written data!")
コード例 #10
0
class BTConnectedDevice(object):
    """Handles connecting and commands for bluetooth devices"""
    peripheral = None
    console_write_characteristic = None
    auth_characteristic = None
    console_enable_char = None
    batt_char = None
    delegate = None

    def connect(self, addr):
        """Connect to the device with the given address"""
        self.peripheral = Peripheral(str(addr), "random")
        self.peripheral.setMTU(272)  # 256 16 for control or headers etc.
        self.delegate = BLEConsoleDelegate()
        self.peripheral.withDelegate(self.delegate)
        self.print_chars_and_handles()
        #self.auth_characteristic = self.get_char("6E400005-B5A3-F393-E0A9-E50E24DCCA9E")
        #self.auth_characteristic.write(struct.pack("16s", "iwanttobeajiobit"), False)
        self.console_enable_char = self.get_char(
            "6E400004-B5A3-F393-E0A9-E50E24DCCA9E")
        self.console_enable_char.write(struct.pack('16s', "iwanttobeajiobit"),
                                       False)

        self.console_write_characteristic = self.get_char(
            "6E400002-B5A3-F393-E0A9-E50E24DCCA9E")
        self.peripheral.waitForNotifications(1)

    def disconnect(self):
        """Disconnect from the bluetooth device"""
        self.peripheral.disconnect()

    def connect_strongest_mfg(self):
        """Connect to the strongest mfg signal"""
        returned_devices = self.scan_for_bt_devices(BTDeviceTypes.MFG)
        strongest_rssi_dev = returned_devices[0]
        self.connect(strongest_rssi_dev.addr)

    def connect_strongest_app(self):
        """Connect to the stronest app signal"""
        returned_devices = self.scan_for_bt_devices(BTDeviceTypes.ANY)
        strongest_rssi_dev = returned_devices[0]
        sleep(1)
        self.connect(strongest_rssi_dev.addr)

    def connect_advertised_name(self, ad_name):
        """Connect to the strongest signal with a given advertised name"""
        returned_devices = self.scan_for_bt_devices(BTDeviceTypes.ANY)
        for device in returned_devices:
            device_name = self.get_device_name(device)
            if device_name == ad_name:
                sleep(1)
                self.connect(device.addr)
                return True
        bt_info_print(
            "could not find advertising name {} in scan".format(ad_name))
        return False

    def scan_for_bt_devices(self, device_type):
        """Scan for Bluetooth devices"""
        scanner = Scanner()

        devices = scanner.scan()

        # keep only desired kind of bt device names
        correct_type_devices = self.get_devices_typed(devices, device_type)

        #sort list by RSSI
        correct_type_devices.sort(key=lambda x: x.rssi, reverse=True)

        for count, entry in enumerate(correct_type_devices):
            bt_info_print(
                "{index}:RSSI - {rssi}, Device Name - {devicename}, Address - {address}"
                .format(index=(count + 1),
                        rssi=entry.rssi,
                        devicename=self.get_device_name(entry),
                        address=entry.addr))

        return correct_type_devices

    def get_devices_typed(self, devlist, device_type):
        """Filter a list of devices using a given device type"""
        desired_devices = list()
        for entry in devlist:
            device_name = self.get_device_name(entry)
            if (device_name != None):
                if ((device_type == BTDeviceTypes.ANY)
                        or (device_type == BTDeviceTypes.MFG
                            and len(device_name) == 12)
                        or (device_type == BTDeviceTypes.APP
                            and device_name == "Jiobit")):
                    desired_devices.append(entry)
        return desired_devices

    def get_device_name(self, dev):
        """Return the name of the given device"""
        devname = None
        try:
            for (sdid, _, val) in dev.getScanData():
                if (sdid == 9):
                    devname = val
        except:
            return None
        return devname

    def send_console_cmd(self, command_str):
        """Send a bluetooth console command"""
        command_str = command_str + "\r\n"
        self.console_write_characteristic.write(command_str)
        #self.peripheral.waitForNotifications(1)

    def send_cmd_wait_resp_time(self, command_str, wait_sec):
        """Send a bluetooth console command and wait for a response"""
        command_str = command_str + "\r\n"
        self.console_write_characteristic.write(command_str)
        #sleep(wait_sec)
        for _ in range(0, wait_sec):
            self.peripheral.waitForNotifications(1)
        return_str = self.delegate.print_clear_console()
        return return_str

    def get_char(self, uuid):
        """Get the characteristic object associated with the given UUID"""
        characteristic = self.peripheral.getCharacteristics(uuid=uuid)[0]
        return characteristic

    def print_chars_and_handles(self):
        """
        Print all characteristics and handles for the connected device

        Also, populate some members of the delegate
        """
        characteristics = self.peripheral.getCharacteristics()
        for characteristic in characteristics:
            uuid = str(characteristic.uuid)
            handle = characteristic.getHandle()
            hex_handle = hex(handle)
            bt_info_print("characteristic " + uuid + " handle: " + hex_handle)
            if (uuid == CONSOLE_BIT_TX_UUID):
                self.delegate.console_bit_tx_handle = int(handle)
            if (uuid == MSGPACK_APPEND_UUID):
                self.delegate.msgpack_append_handle = int(handle)
            if (uuid == MSGPACK_DONE_UUID):
                self.delegate.msgpack_append_handle = int(handle)

    def read_batt_char(self):
        """Read the connected device's battery characteristic"""
        if (self.batt_char is None):
            self.batt_char = self.get_char(
                "00002A19-0000-1000-8000-00805F9B34FB")
        if (self.batt_char.supportsRead()):
            return str(self.batt_char.read())
        else:
            bt_info_print("does not support read")
            return None
コード例 #11
0
devices = scanner.scan(5.0)
wallet_address = 0
for dev in devices:
    print ("Device %s (%s), RSSI=%d dB" % (dev.addr, dev.addrType, dev.rssi) )
    for (adtype, desc, value) in dev.getScanData():
        print ("  %s = %s" % (desc, value))
        if dev.rssi >  -65 :
                print("Get Wallet address:%s!" % dev.addr)
                wallet_address = dev.addr

if wallet_address == 0:
        print ("No wallet found")
        exit()

p = Peripheral(wallet_address,btle.ADDR_TYPE_PUBLIC)
print(p.setMTU(144+3)) #not actually changing MTU



Address = input_str.split("&")[1].split("=")[1]
AES_Key = input_str.split("&")[2].split("=")[1]
Service_UUID = input_str.split("&")[3].split("=")[1]
TotalChar_UUID = [input_str.split("&")[4].split("=")[1][i:i+8] for i in range(0, len(input_str.split("&")[4].split("=")[1]), 8)]


print ("Wallet Address:",Address)

Characteristics = ["Transaction_UUID","Txn_UUID","AddERC20_UUID","Balance_UUID","General_CMD_UUID","General_Data_UUID"]
MainCharacteristics_head = {"Transaction_UUID":TotalChar_UUID[0],"Txn_UUID":TotalChar_UUID[1],"AddERC20_UUID":TotalChar_UUID[2],"Balance_UUID":TotalChar_UUID[3],"General_CMD_UUID":TotalChar_UUID[4],"General_Data_UUID":TotalChar_UUID[5]}
MainCharacteristics = {"Transaction_UUID":"","Txn_UUID":"","AddERC20_UUID":"","Balance_UUID":"","General_CMD_UUID":"","General_Data_UUID":""}
コード例 #12
0
ファイル: tx.py プロジェクト: newdominic/HITCON-Badge-2018
devices = scanner.scan(5.0)
wallet_address = 0
for dev in devices:
    print("Device %s (%s), RSSI=%d dB" % (dev.addr, dev.addrType, dev.rssi))
    for (adtype, desc, value) in dev.getScanData():
        print("  %s = %s" % (desc, value))
        if desc == "Complete 128b Services" and value == "7419975eb7b9ac9895ddebbb2bd27f1f":
            print("Get Wallet address:%s!" % dev.addr)
            wallet_address = dev.addr

if wallet_address == 0:
    print("No wallet found")
    exit()

p = Peripheral(wallet_address, btle.ADDR_TYPE_PUBLIC)
print(p.setMTU(144 + 3))  #not actually changing MTU

Address = input_str.split("&")[1].split("=")[1]
AES_Key = input_str.split("&")[2].split("=")[1]
Service_UUID = input_str.split("&")[3].split("=")[1]
TotalChar_UUID = [
    input_str.split("&")[4].split("=")[1][i:i + 8]
    for i in range(0, len(input_str.split("&")[4].split("=")[1]), 8)
]

print("Wallet Address:", Address)

Characteristics = [
    "Transaction_UUID", "Txn_UUID", "AddERC20_UUID", "Balance_UUID",
    "General_CMD_UUID", "General_Data_UUID"
]
コード例 #13
0
def main():

    scanner = Scanner().withDelegate(ScanDelegate())

    device_list = scanner.scan(5)  # scan for 5 seconds
    for device in device_list:
        if (device.addr.lower() == DH_ADDRESS.lower()):
            print("Target device host discovered!")
            # RSSI = Received Signal Strength Indicator
            print("Device %s (%s), RSSI=%d dB" %
                  (device.addr, device.addrType, device.rssi))
            scan_data = device.getScanData()
            device_name = scan_data[2][2]
            auth_service_uuid = scan_data[4][2]
            print(device_name)
            print(auth_service_uuid)
            #for (adtype,desc,value) in device.getScanData():
            #    print("\t%s = %s" % (desc, value))

    try:
        device = Peripheral(DH_ADDRESS)
        device.setMTU(520)
        device.setDelegate(PeripheralDelegate())
        print("Successfully connected to device host")
        auth_service = device.getServiceByUUID(auth_service_uuid)
        auth_char = auth_service.getCharacteristics()[0]

        # read authentication characteristic state
        auth_char_val = auth_char.read()
        #print(auth_char_val)
        if (auth_char_val.decode() == '0x15'):  # BLE_CHAR_AUTH_REQ
            print("# Device host ready to receive authentication ticket")
        #auth_ticket = { 'sercret':1, 'public':2 ,'signature':3}
        #auth_ticket = "{'secret': qqqqqqqqqqqqqqaaaaaaaaaaaaaaaaaaaaaaaaaassssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss, 'public': {'dh_id' : uuid, 'dh_addr' : addr, 'owner_id' : gw_id, 'access_rights' : 'Rx', 'ticket_lifetime': 3600},'signature': sig}"
        s_auth_ticket = str(auth_ticket).replace("b\'", "")
        print(s_auth_ticket)

        msg_header = "0x50"
        #msg_payload = str(auth_ticket).encode()
        #msg = msg_header.encode() + msg_payload
        #msg = msg[0:100]
        if ((len(s_auth_ticket) + HEADER_SIZE) > MAX_MSG_SIZE):
            print("Message size exceeds maximum capacity. Fragmenting data...")

            fragments = dataFragment(s_auth_ticket)
            for frag in fragments:
                msg = msg_header.encode() + frag.encode()
                print(msg)
                #print(len(msg))
                auth_char.write(msg)
                time.sleep(0.5)
        else:
            print("Packet does not exceed maximum capacity")
        #auth_char.write(msg)
        #else:
        # catch other responses here
        # such as if device not ready, wait and do authentication later
        # < TODO >
        #    print("# Something went wrong...")
        """
        while True:
            if p.waitForNotifications(1.0):
                # handleNotification() was called
                continue
             print "Waiting..."
            # Perhaps do something else here
        """

    finally:
        device.disconnect()
コード例 #14
0
class BleCam(object):
    locked = True

    def __init__(self, address, pincode):
        print("Connecting to %s..." % address)
        self.pincode = pincode
        self.periph = Peripheral(address)
        self.periph.setMTU(256)
        self._ipcamservice()
        #self.name = self.periph.getCharacteristics(uuid=0xa200)[0].read().decode() # wellknown name characteristic
        #self.idstring = self.periph.getCharacteristics(uuid=0xa200)[0]
        #self.idstate = kv2dict(self.idstring.read().decode())
        #self.name = self.idstate["N"] + "-" + self.idstate["M"][8:]
        # CHANGE #### to the last two mac octets in hex when using on a factory reset DCS-8600LH
        self.name = "DCS-8600LH-####"
        print("Connected to '%s'" % self.name)

    def _ipcamservice(self):
        try:
            print("Verifying IPCam service")
            self.service = self.periph.getServiceByUUID(0xd001)
            self.handles = self.service.getCharacteristics()
            #print("self.service = '%s'" % self.service)
            #print("self.handles = '%s'" % '\n'.join(map(str,self.handles)))
        except BTLEEException:
            print("no IPCam service found for %s" % periph.address)

    def dumpchars(self):
        print("%s supports these characteristics:" % self.name)
        for h in self.handles:
            print("%s - Handle=%#06x (%s)" %
                  (h.uuid, h.getHandle(), h.propertiesToString()))

    def unlock(self):
        if not self.locked:
            return True
        auth = self.service.getCharacteristics(0xa001)[0]
        state = kv2dict(auth.read().decode())
        #print("auth = '%s'" % auth)
        #print("state = '%s'" % state)

        # already unlocked?
        if state["M"] == 0:
            self.locked = False
            return True

        self.challenge = state["C"]
        #print("self.challenge = '%s'" % self.challenge)
        hashit = self.name + self.pincode + self.challenge
        #print("hashit = '%s'" % hashit)
        self.key = base64.b64encode(hashlib.md5(hashit.encode()).digest())[:16]
        #print("self.key = '%s'" % self.key)
        try:
            auth.write("M=0;K=".encode() + self.key, True)
            self.locked = False
        except:
            print("ERROR: failed to unlock %s - wrong pincode?" % self.name)
        return not self.locked

    def get_ipconfig(self):
        if not self.unlock(): return
        return kv2dict(
            self.service.getCharacteristics(0xa104)[0].read().decode())

    def get_wificonfig(self):
        if not self.unlock(): return
        return kv2dict(
            self.service.getCharacteristics(0xa101)[0].read().decode())

    def wifilink(self):
        if not self.unlock(): return
        r = kv2dict(self.service.getCharacteristics(0xa103)[0].read().decode())
        return r["S"] == "1"

    def sysinfo(self):
        if not self.unlock(): return
        return kv2dict(
            self.service.getCharacteristics(0xa200)[0].read().decode())

    def setup_wifi(self, essid, passwd):
        for net in self.wifi_scan():
            if net["I"] == essid:
                cfg = "M=" + net["M"] + ";I=" + essid + ";S=" + net[
                    "S"] + ";E=" + net["E"] + ";K=" + passwd
                print("Will configure: %s" % cfg)
                self.service.getCharacteristics(0xa101)[0].write(
                    cfg.encode(), True)
                self.service.getCharacteristics(0xa102)[0].write(
                    "C=1".encode(), True)
                return True
        print("%s cannot see the '%s' network" % (self.name, essid))
        return False

    def wifi_scan(self):
        def _wifi2dict(wifistr):
            return kv2dict(wifistr[2:], ",")

        if not self.unlock(): return
        print("%s is scanning for WiFi networks..." % self.name)
        scan = self.service.getCharacteristics(0xa100)[0]
        p = -1
        n = 0
        result = ""
        while p < n:
            t = scan.read().decode().split(";", 3)
            result = result + t[2]
            if not t[0].startswith("N=") or not t[1].startswith("P="):
                return
            n = int(t[0].split("=", 2)[1])
            p = int(t[1].split("=", 2)[1])
            # print("read page %d of %d" % (p, n))
        return map(_wifi2dict, result.split("&", 50))

    def run_command(self, command):
        if not self.unlock(): return

        #run = "P=" + self.pincode + ";N=" + self.pincode + "\"&&(" + command + ")&\""
        runa = "P=" + self.pincode + ";N="
        runb = self.pincode + "\"&&(" + command + ")&\""
        run = runa + runb
        #run = "P=;N=" + self.pincode
        # sprintf(cmd,"/usr/bin/mdb set admin_passwd \"%s\"",newpass);
        #print("COMMAND: /usr/bin/mdb set admin_passwd \"%s\"" % runb)

        #print("run = '%s'" % run)
        #return
        if len(run) > 128:
            print("ERROR: command is too long")
            return
        print(
            "Attempting to run '%s' on %s by abusing the 'set admin password' request"
            % (command, self.name))
        try:
            self.service.getCharacteristics(0xa201)[0].write(
                run.encode(), True)
        except:
            print("Failed - trying again with blank password")
            # try repeating with an empty password, which seems to be the initial state after factory reset
            #run = "P=;N=" + self.pincode + "&&(" + command + ")&"
            run = "P=;N=" + runb + "\"&&(" + command + ")&\""
            try:
                self.service.getCharacteristics(0xa201)[0].write(
                    run.encode(), True)
            except:
                print(
                    "ERROR: Failed - is the admin password different from the pincode?"
                )
コード例 #15
0
class BleDevice:
    def __init__(self, addr, thing_id):
        self.addr = addr
        self.thing_id = thing_id

    def connect(self):
        print("--Connect")
        print(" -Connecting to Peripheral:", self.addr)
        self.per = Peripheral(self.addr)
        print(" -Connected to Peripheral:", self.addr)
        print()

    def disconnect(self):
        print("--Disconnect")
        print(" -Disconnecting from Peripheral:", self.addr)
        self.per.disconnect()
        print(" -Disconnected from Peripheral:", self.addr)

    def setup(self):
        print("--Setup")

        self.per.setMTU(112)
        print(" -MTU set to 112 bytes (109+3 bytes)")

        self.svc = self.per.getServiceByUUID(
            "2ea78970-7d44-44bb-b097-26183f402400")

        self.data_ch = self.svc.getCharacteristics(
            "2ea78970-7d44-44bb-b097-26183f402410")[0]
        self.data_ch_hnd = self.data_ch.getHandle()
        self.per.writeCharacteristic(self.data_ch_hnd + 1, b"\x01\00", True)
        print(" -Enabled notifications on characteristic 0x2410")

        self.ctrl_ch = self.svc.getCharacteristics(
            "2ea78970-7d44-44bb-b097-26183f402409")[0]
        self.ctrl_ch_hnd = self.ctrl_ch.getHandle()
        self.ctrl_ch.write(b"\x01", True)
        print(" -Wrote 0x01 to characteristic 0x2409")

        self.per.withDelegate(MyDelegate(self))
        print()

    def set_handler(self, handler):
        self.handler = handler

    def print_svc_char(self):
        print("--Services and Characteristics")
        services = self.per.getServices()
        for svc in services:
            print(svc)
            print(svc.uuid)
            print()
            characteristics = svc.getCharacteristics()
            for char in characteristics:
                print("\t", char)
                print("\t", char.uuid)
                print("\t Handle:", char.getHandle())
                print("\t", char.propertiesToString())
                print()

    def get_data(self, mins):
        print("--Reports")
        t_end = time.time() + 60 * mins
        while time.time() < t_end:
            if self.per.waitForNotifications(1.0):
                continue
            print(" -Waiting...")
        print()
コード例 #16
0
    def run(self):
        while True:
            logger.info("Starting session with DH " + self.device.addr)
            #dh_ble_addr = self.auth_ticket['public']['dh_addr']

            # connect to DH view BLE

            # fetch public authentication characteristic

            # if characteristic read value indicates DH is ready to start a session
            # then send the DHM received authentication ticket + nonce1
            # Receive session confirmation from DH
            # Additionally the DH also sends nonce2 + nonce1 encrypted with derived session key

            # Validate encrypted nonce and send nonce2 encrypted with derived session key

            scan_data = self.device.getScanData()
            device_name = scan_data[2][2]
            auth_service_uuid = scan_data[4][2]
            #print(device_name)
            #print(auth_service_uuid)
            #for (adtype,desc,value) in device.getScanData():
            #    print("\t%s = %s" % (desc, value))

            try:
                device = Peripheral(self.device.addr)
                device.setMTU(
                    520)  # max value is 520 bytes per BLE transference
                device.setDelegate(PeripheralDelegate())
                #print("Successfully connected to device host " + self.device.addr)
                logger.info("Successfully connected to DH " + self.device.addr)
                auth_service = device.getServiceByUUID(auth_service_uuid)
                auth_char = auth_service.getCharacteristics(
                )[0]  # authentication service has a single characteristic to perform read/write transfers

                # set characteristic CCCD descriptor to 0x01 x00
                # needed to receive notifications from DH
                # as specified in bluetooth RFC
                auth_char_cccd = auth_char.getHandle() + 1
                device.writeCharacteristic(auth_char_cccd, b"\x01\x00")

                #read authentication characteristic state
                auth_char_val = auth_char.read()
                if (auth_char_val.decode() == '0x15'):  # BLE_CHAR_AUTH_REQ
                    #print("# Device host ready to receive authentication ticket")
                    logger.info("DH " + self.device.addr +
                                "ready to receive authetication ticket")

                    s_auth_ticket = serializeData(self.auth_ticket,
                                                  "auth_ticket", self.nonce)
                    #print(s_auth_ticket.hex())

                    #for byte in s_auth_ticket:
                    #    print(int(byte))

                    #for b in self.auth_ticket['secret']:
                    #    print(int(b))

                    #s_auth_ticket = str(self.auth_ticket).replace("b\'","")
                    #print(s_auth_ticket)
                    #msg_header = "0x50" # authentication signalling header

                    #if((len(s_auth_ticket)+HEADER_SIZE) > MAX_MSG_SIZE ):
                    if (len(s_auth_ticket) + 2 > MAX_MSG_SIZE):
                        #print("Message size exceeds maximum capacity. Fragmenting data...")
                        logger.info(
                            "Authentication ticket message exceeds link maximum capacity ("
                            + str(MAX_MSG_SIZE) + ") Data will be fragmented")
                        #fragments = dataFragment(s_auth_ticket)
                        fragments = dataFragment1(s_auth_ticket)
                        #print(fragments)
                        for idx in range(0, len(fragments)):
                            if (idx == len(fragments) - 1):
                                ending_flag = 1
                            else:
                                ending_flag = 0
                            sequence_no = idx + 1
                            msg = bytes([sequence_no]) + bytes(
                                [ending_flag]) + fragments[idx]
                            #print(msg)
                            #print(bytes([sequence_no]))

                            #msg = msg_header.encode() + frag.encode()
                            #print(msg)
                            #print(len(msg))
                            auth_char.write(msg)
                            time.sleep(
                                0.5
                            )  # interval between writes in order to avoid unexpected delays

                        #print("Authentication ticket sent to target DH successfully!")
                        logger.info(
                            "Authentication ticket message sent to target DH "
                            + self.device.addr + " successfully")
                        # wait for DH response notification
                        #print("Waiting for DH response...")
                        logger.info("Waiting for DH " + self.device.addr +
                                    " response notification")
                        while True:
                            if (device.waitForNotifications(1.0)):
                                #print(notification_buffer)
                                response = ble_message_pb2.BLEmessage()
                                response.ParseFromString(notification_buffer)
                                #print(response.ListFields())
                                #print(response.header.msg_type)
                                global notification_buffer
                                notification_buffer = b''

                                # process response
                                if (response.header.msg_type == ble_message_pb2
                                        .Header.MessageType.NonceExchange):
                                    #print("Nonce exchange msg received!")
                                    logger.info(
                                        "Nonce exchange message received")
                                    encrypted_nonce1 = response.payload.nonce_exc_msg.enc_nonce
                                    clear_nonce2 = response.payload.nonce_exc_msg.clear_nonce

                                    # generate derived session key using received nonce2
                                    derived_session_key = digestMultipleSHA256(
                                        [
                                            self.nonce, clear_nonce2,
                                            self.session_key
                                        ])
                                    #print("Derived session key K'")
                                    #for b in derived_session_key:
                                    #    print(int(b))

                                    iv = encrypted_nonce1[0:16]
                                    enc_nonce1 = encrypted_nonce1[
                                        16:len(encrypted_nonce1)]

                                    #print("Init Vector")
                                    #for b in iv:
                                    #    print(int(b))
                                    #print("ENC NONCE1")
                                    #for b in enc_nonce1:
                                    #    print(int(b))
                                    #print("TOTAL")
                                    #for b in encrypted_nonce1:
                                    #    print(int(b))

                                    # decrypt nonce1
                                    decrypted_nonce1 = decryptAES_CBC(
                                        enc_nonce1, derived_session_key, iv)

                                    #print("DECRYPTED NONCE1")
                                    #for b in decrypted_nonce1:
                                    #    print(int(b))
                                    #print("CLEAR NONCE1")
                                    #for b in self.nonce:
                                    #    print(int(b))
                                    # check if it matches session nonce (self.nonce)
                                    if (decrypted_nonce1 != self.nonce):
                                        print(
                                            "# Error: Received nonce does not match session nonce. Could be due to faulty encryption or decryption.\n## Restarting session setup..."
                                        )
                                        # < TODO > Handle session restart
                                    else:
                                        logger.info(
                                            "Received decrypted nonce matches session nonce"
                                        )
                                        #print("Decrypted nonce matches session nonce!")
                                        # encrypt received nonce2 and send it to finalize the nonce exchange and session setup protocol
                                        enc_nonce2, iv = encryptAES_CBC(
                                            clear_nonce2, derived_session_key)
                                        # join ciphertext and iv in the same buffer and serialize to be ready for transmission
                                        #print("clear nonce2")
                                        #for b in clear_nonce2:
                                        #    print(int(b))
                                        #print("enc nonce2")
                                        #for b in enc_nonce2:
                                        #    print(int(b))
                                        #print("I V")
                                        #for b in iv:
                                        #    print(int(b))

                                        enc_nonce2_iv = iv + enc_nonce2

                                        reply = ble_message_pb2.BLEmessage()

                                        header = reply.header
                                        payload = reply.payload

                                        header.msg_type = header.NonceExchange
                                        reply.header.CopyFrom(header)

                                        nonce_exc = payload.nonce_exc_msg
                                        nonce_exc.enc_nonce = enc_nonce2_iv

                                        reply.payload.CopyFrom(payload)

                                        s_reply = reply.SerializeToString()

                                        #for b in s_reply:
                                        #    print(int(b))

                                        auth_char.write(
                                            bytes([0, 1]) + s_reply)

                                        logging.info(
                                            "Session with DH " +
                                            self.device.addr +
                                            " established succsessfully")

                                        ## Session setup is now complete!
                                        # (does the DH reports a response to this last message ?)

                                        logging.info(
                                            "Waiting for DH " +
                                            self.device.addr +
                                            " installed drivers information..."
                                        )

                                        while (stream_ready == False):
                                            device.waitForNotifications(10)

                                        dds_info = ble_message_pb2.BLEmessage()
                                        dds_info.ParseFromString(
                                            notification_buffer)
                                        notification_buffer = b''
                                        #print(dds_info.ListFields())

                                        if (dds_info.header.msg_type ==
                                                ble_message_pb2.Header.
                                                MessageType.DriversInfo):
                                            logging.info(
                                                "Received DDs info from DH " +
                                                self.device.addr)

                                            # add info do dds list
                                            #print(dds_info.payload.drivers_info_msg.driver_info)
                                            global dd_list
                                            dd_list[self.dh_id] = {}
                                            for dd in dds_info.payload.drivers_info_msg.driver_info:
                                                dd_id = digestMD5(
                                                    dd.public_key).hex()
                                                dd_dict = {}
                                                dd_dict[
                                                    'pub_key'] = dd.public_key
                                                dd_dict[
                                                    'api'] = dd.api_description
                                                dd_dict[
                                                    'a3c_uuid'] = dd.a3c_dd_uuid

                                                dd_list[self.dh_id].update(
                                                    {dd_id: dd_dict})

                                            global configured_devices
                                            configured_devices.append(
                                                self.device.addr)

                                            #print(dd_list)

                                            #self.handler.write("DH "+ self.dh_id +" (address " + self.device.addr+") successfully configured")
                                            msg = {
                                                'dh_uuid': self.dh_id,
                                                'status': 'OK'
                                            }

                                            #print(self.handler.request.protocol+"://"+self.handler.request.remote_ip+":7777"+"/dhSessionConfirm/")

                                            req = request.Request(
                                                self.handler.request.protocol +
                                                "://" +
                                                self.handler.request.remote_ip
                                                + ":7777" +
                                                "/dhSessionConfirm/",
                                                parse.urlencode(msg).encode())

                                            request.urlopen(req)
                                            #process attributes and build MQTT topics!
                                        elif (dds_info.header.msg_type ==
                                              ble_message_pb2.Header.
                                              MessageType.ErrorMessage):
                                            print("Error!")
                                        else:
                                            print("Unknown message received")

                                #elif(response.header.msg_type == ble_message_pb2.Header.MessageType.ErrorMessage):
                                # < TODO > Handle error & session restart
                                else:
                                    print(
                                        "# Error: Unknown message header received!\n # Restarting session setup..."
                                    )
                                    # < TODO > Handle error & session restart
                                    return

                            break

                    else:
                        print("Packet does not exceed maximum capacity")
                        sequence_no = '0'
                        ending_flag = '1'
                    #auth_char.write(msg)
                #else:
                # catch other responses here
                # such as if device n

                while (True):
                    logging.info("Waiting for further instructions...")
                    (instruction,
                     data) = self.q.get()  # wait for further instructions
                    #process received instruction after unblocking
                    if (instruction == "clientSessionRequest"):
                        logging.info("Client session request received")

                        # retrieve and encode data

                        decoded_data = literal_eval(
                            base64.b64decode(data).decode())

                        ticket = decoded_data['ticket']
                        a3c_dd_public_key = decoded_data["public_key"]
                        nonce1 = decoded_data['nonce']

                        # serialize message
                        data_serial = serializeData(ticket,
                                                    "driver_auth_ticket",
                                                    nonce1)

                        if (len(data_serial) + 2 > MAX_MSG_SIZE):
                            #print("Message size exceeds maximum capacity. Fragmenting data...")
                            logger.info(
                                "Driver authentication ticket message exceeds link maximum capacity ("
                                + str(MAX_MSG_SIZE) +
                                "). Data will be fragmented...")
                            frags = dataFragment1(data_serial)

                            for idx in range(0, len(frags)):
                                if (idx == len(frags) - 1):
                                    ending_flag = 1
                                else:
                                    ending_flag = 0
                                sequence_no = idx + 1
                                msg = bytes([sequence_no]) + bytes(
                                    [ending_flag]) + frags[idx]

                                print(msg)
                                #print(len(msg))
                                auth_char.write(msg)
                                time.sleep(
                                    0.5
                                )  # interval between writes in order to avoid unexpected delays

                            #print("Authentication ticket sent to target DH successfully!")
                            logger.info(
                                "Client authentication ticket sent to target DH "
                                + self.device.addr + " successfully")
                            # wait for DH response notification
                            #print("Waiting for DH response...")
                        else:
                            print(
                                "Message does not exceed maximum link capacity"
                            )
                            # Handle message sending here
                            # < TODO >

                        # wait for notification from DH
                        logger.info("Waiting for DH notification...")
                        if (device.waitForNotifications(1.0)):
                            reponse = ble_message_pb2.BLEmessage()
                            response.ParseFromString(notification_buffer)
                            notification_buffer = b''

                            # process response
                            if (response.header.msg_type == ble_message_pb2.
                                    Header.MessageType.NonceExchange):
                                #print("Nonce exchange msg received!")
                                logger.info("Nonce exchange message received")
                                encrypted_nonce1 = response.payload.nonce_exc_msg.enc_nonce
                                clear_nonce2 = response.payload.nonce_exc_msg.clear_nonce

                                # < TODO >

                                msg = {
                                    "enc_nonce1": encrypted_nonce1,
                                    "clear_nonce2": clear_nonce2
                                }
                                self.q_out.put(msg)

                            elif (response.header.msg_type == ble_message_pb2.
                                  Header.MessageType.ErrorMesssage):
                                print("Error!")
                            else:
                                print("Unknown message received!")

                        # send reply back to respective client!

                    if (instruction == "clientRequestSubscribe"):
                        logger.info("Subscribe client request received")

                        target_dd = data["target_dd"]
                        dd_action = data["dd_action"]
                        duration = data["duration"]
                        delta = data["delta"]

                        # serialize request
                        serial_data = serializeData(
                            {
                                "target_dd": target_dd,
                                "dd_action": dd_action,
                                "delta": delta
                            }, "access_request")
                        # write to dh characteristic
                        auth_char.write(bytes([0]) + bytes([1]) + serial_data)
                        # process notification stream and publish data to corresponding topic
                        timeout = time.time() + int(duration)

                        logger.info("Waiting for DH response...")
                        if (device.waitForNotifications(2.0)):
                            print("AAAAA")
                            response = ble_message_pb2.BLEmessage()
                            response.ParseFromString(notification_buffer)
                            notification_buffer = b''
                            print(response)
                            client.publish(
                                "/ble/" + target_dd + "/" + dd_action,
                                ord(response.payload.response.response))
                        """
                        while time.time < timeout:
                            if(device.waitForNotifications(1.0)):
                                reponse = ble_message_pb2.BLEmessage()
                                response.ParseFromString(notification_buffer)
                                notification_buffer = b''

                                client.publish("ble/"+target_dd+"/"+dd_action,response.value)
                        """

            except Exception as exc:
                print(exc)

            finally:
                print("finally")
                #device.disconnect()

            return
コード例 #17
0
    def handleNotification(self, cHandle, data):
        s = list(data)
        print(":".join("{:02x}".format(c) for c in s))


sr_service_uuid = UUID(0xFDEE)
sr_auth_char_uuid = UUID(0xFD03)
sr_tx_uuid = UUID(0xFD05)

print('target addr ' + 'ba:03:4c:3a:c3:70')

p = Peripheral('ba:03:4c:3a:c3:70', "public")
p.setDelegate(MyDelegate(p))

sr_service = p.getServiceByUUID(sr_service_uuid)
p.setMTU(36)

sr_tx_char = sr_service.getCharacteristics(sr_tx_uuid)[0]
sr_tx_char_value_handle = sr_tx_char.getHandle()

for desriptor in p.getDescriptors(sr_tx_char_value_handle, 0xFF):
    if (desriptor.uuid == 0x2902):
        print("SR_TX CCCD found at handle 0x" +
              format(desriptor.handle, "02X"))
        sr_tx_value_cccd_handle = desriptor.handle

p.writeCharacteristic(sr_tx_value_cccd_handle, struct.pack('<bb', 0x02, 0x00))
print("Indication is turned on for TX")

sr_auth_char = sr_service.getCharacteristics(sr_auth_char_uuid)[0]
sr_auth_char_value_handle = sr_auth_char.getHandle()