# BLE iBeaconScanner based on https://github.com/adamf/BLE/blob/master/ble-scanner.py # JCS 06/07/14 DEBUG = False # BLE scanner based on https://github.com/adamf/BLE/blob/master/ble-scanner.py # BLE scanner, based on https://code.google.com/p/pybluez/source/browse/trunk/examples/advanced/inquiry-with-rssi.py # https://github.com/pauloborges/bluez/blob/master/tools/hcitool.c for lescan # https://kernel.googlesource.com/pub/scm/bluetooth/bluez/+/5.6/lib/hci.h for opcodes # https://github.com/pauloborges/bluez/blob/master/lib/hci.c#L2782 for functions used by lescan # performs a simple device inquiry, and returns a list of ble advertizements # discovered device # NOTE: Python's struct.pack() will add padding bytes unless you make the endianness explicit. Little endian # should be used for BLE. Always start a struct.pack() format string with "<" import os import sys import struct import bluetooth._bluetooth as bluez LE_META_EVENT = 0x3e LE_PUBLIC_ADDRESS=0x00 LE_RANDOM_ADDRESS=0x01 LE_SET_SCAN_PARAMETERS_CP_SIZE=7 OGF_LE_CTL=0x08 OCF_LE_SET_SCAN_PARAMETERS=0x000B OCF_LE_SET_SCAN_ENABLE=0x000C OCF_LE_CREATE_CONN=0x000D LE_ROLE_MASTER = 0x00 LE_ROLE_SLAVE = 0x01 # these are actually subevents of LE_META_EVENT EVT_LE_CONN_COMPLETE=0x01 EVT_LE_ADVERTISING_REPORT=0x02 EVT_LE_CONN_UPDATE_COMPLETE=0x03 EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE=0x04 # Advertisment event types ADV_IND=0x00 ADV_DIRECT_IND=0x01 ADV_SCAN_IND=0x02 ADV_NONCONN_IND=0x03 ADV_SCAN_RSP=0x04 def returnnumberpacket(pkt): myInteger = 0 multiple = 256 for c in pkt: myInteger += int(c) * multiple multiple = 1 return myInteger def returnstringpacket(pkt): myString = ""; for c in pkt: myString += "%02x" % (c,) return myString def printpacket(pkt): for c in pkt: sys.stdout.write("%02x " % (c,)) def get_packed_bdaddr(bdaddr_string): packable_addr = [] addr = bdaddr_string.split(':') addr.reverse() for b in addr: packable_addr.append(int(b, 16)) return struct.pack("