def canonicalise_uuid(uuid): import re uuid = str(uuid) _uuid_re = re.compile(r'^[0-9A-Fa-f]{8}-(?:[0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$') _hex_re = re.compile(r'^[0-9A-Fa-f]{32}$') if _uuid_re.match(uuid): return uuid.upper() if _hex_re.match(uuid): return '-'.join([uuid[0:8], uuid[8:12], uuid[12:16], uuid[16:20], uuid[20:]]).upper() return None
def main(argv): #uuid = "E2 0A 39 F4 73 F5 4B C4 A1 2F 17 D1 AD 07 A9 61" uuid = get_random_uuid() major = randint(0, 65535) minor = randint(0, 65535) power = randint(150, 255) device = "hci0" if len(sys.argv) == 5: try: if str(sys.argv[1]): uuid = str(sys.argv[1]) if str(sys.argv[2]): major = str(sys.argv[2]) if major < 0 or major > 65535: print "Error: major id is out of bounds (0-65535)" sys.exit() if str(sys.argv[3]): minor = str(sys.argv[3]) if minor < 0 or minor > 65535: print "Error: minor id is out of bounds (0-65535)" sys.exit() if str(sys.argv[4]): power = str(sys.argv[4]) if power < 0 or power > 255: print "Error: power id is out of bounds (0-255)" sys.exit() except: usage() elif len(sys.argv) > 1: usage() uuid = hexsplit(uuid.upper()) major = hexify(major, 4) minor = hexify(minor, 4) major = hexsplit(major) minor = hexsplit(minor) power = hexify(power, 2) #uuid = "E2 0A 39 F4 73 F5 4B C4 A1 2F 17 D1 AD 07 A9 61" print uuid, major, minor, power executeComand("hciconfig %s up" % device) executeComand("hciconfig %s leadv" % device) executeComand("hciconfig %s noscan" % device) executeComand( "hcitool -i %s cmd 0x08 0x0008 1E 02 01 1A 1A FF 4C 00 02 15 %s %s %s %s 00 >/dev/null" % (device, uuid, major, minor, power))
def get_short(self, uuid: str) -> str: """ Returns the short type for a given UUID. That means that "0000006D-0000-1000-8000-0026BB765291" and "6D" both translates to "position.current" (after looking up "public.hap.characteristic.position.current"). if item in self._characteristics: return self._characteristics[item].split('.', 3)[3] :param uuid: the UUID in long form or the shortened version as defined in chapter 5.6.1 page 72. :return: the textual representation """ orig_item = uuid uuid = uuid.upper() if uuid.endswith(self.baseUUID): uuid = uuid.split("-", 1)[0] uuid = uuid.lstrip("0") if uuid in self._characteristics: return self._characteristics[uuid].split(".", maxsplit=3)[3] return "Unknown Characteristic {i}".format(i=orig_item)
def id_externo(self): uuid = str(self.uuid) return uuid.upper()[:5]
def main(argv=None): # option flags global verbose global simulate # default uuid is the Digital2Go Media Networks UUID # can be overriden with environment variable uuid = os.getenv("IBEACON_UUID", "8D847D200116435F9A212FA79A706D9E") # major and minor ids, can be overriden with environment variable major = int(os.getenv("IBEACON_MAJOR", "0")) minor = int(os.getenv("IBEACON_MINOR", "0")) # default to the first available bluetooth device device = "hci0" # default minimum advertising interval (in milliseconds) min_adv = int(os.getenv("MIN_ADV_INTERVAL", "350")) # default maximum advertising interval (in milliseconds) max_adv = int(os.getenv("MAX_ADV_INTERVAL", "400")) # default power level power = int(os.getenv("IBEACON_POWER", "200")) # regexp to test for a valid UUID # here the - separators are optional valid_uuid_match = re.compile('^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}$', re.I) # grab command line arguments if argv is None: argv = sys.argv # parse command line options try: try: opts, args = getopt.getopt(argv[1:], "hu:M:m:a:A:p:vd:nz", ["help", "uuid=", "major=", "minor=", "min_adv=","max_adv=","power=", "verbose", "device=", "simulate", "down"]) except getopt.error, msg: raise Usage(msg) for o, a in opts: if o in ("-h", "--help"): print __doc__ return 0 elif o in ("-n", "--simulate"): simulate = True verbose = True elif o in ("-u", "--uuid"): uuid = a if uuid == "random": uuid = get_random_uuid() elif o in ("-M", "--major"): major = int(a) elif o in ("-m", "--minor"): minor = int(a) elif o in ("-a", "--minadv"): min_adv = int(a) elif o in ("-A", "--maxadv"): max_adv = int(a) elif o in ("-p", "--power"): power = int(a) elif o in ("-v", "--verbose"): verbose = True elif o in ( "-d", "--device"): temp_device = str(a) # devices can be specified as "X" or "hciX" if not temp_device.startswith("hci"): device = "hci%s" % temp_device else: device = temp_device elif o in ( "-z", "--down"): if check_for_sudo(): if is_valid_device(device): print "Downing iBeacon on %s" % device process_command("hciconfig %s noleadv" % device) process_command("hciconfig %s piscan" % device) process_command("hciconfig %s down" % device) return 0 else: print "Error: no such device: %s (try `hciconfig list')" % device return 1 else: return 1 # test for valid UUID if not valid_uuid_match.match(uuid): print "Error: `%s' is an invalid UUID." % uuid return 1 # strip out - symbols from uuid and turn it into uppercase uuid = uuid.replace("-","") uuid = uuid.upper() # bounds check major/minor ids if major < 0 or major > 65535: print "Error: major id is out of bounds (0-65535)" return 1 if minor < 0 or minor > 65535: print "Error: minor id is out of bounds (0-65535)" return 1 # Bound the advertising intervals to 100ms - 3000ms # Also make sure that the max > min if min_adv < 100 or min_adv > 3000: print "Error: min_adv is out of bounds (100-3000)" return 1 if max_adv < 100 or max_adv > 3000: print "Error: max_adv is out of bounds (100-3000)" return 1 if min_adv > max_adv: print "Error: min_adv > max_adv" return 1 # bail if we're not running as superuser (don't care if we are simulating) if not simulate and not check_for_sudo(): return 1 # split the uuid into 8 bit (=2 hex digit) chunks split_uuid = hexsplit(uuid) # convert major/minor id into hex major_hex = hexify(major, 4) minor_hex = hexify(minor, 4) # convert min_adv/max_adv into hex min_adv_hex = hexify(int(min_adv/0.625), 4) max_adv_hex = hexify(int(max_adv/0.625), 4) # create split versions of these (for the hcitool command) split_major_hex = hexsplit(major_hex) split_minor_hex = hexsplit(minor_hex) # create split versions with endian swap for advertising intervals split_min_adv_hex = hexsplit(endian_swap(min_adv_hex)) split_max_adv_hex = hexsplit(endian_swap(max_adv_hex)) print "split min/max %s/%s" % (split_min_adv_hex, split_max_adv_hex) # convert power into hex power_hex = hexify(power, 2) # make sure we are using a valid hci device if not simulate and not is_valid_device(device): print "Error: no such device: %s (try `hciconfig list')" % device return 1 # print status info print "Advertising on %s with:" % device print " uuid: 0x%s" % uuid print "major/minor: %d/%d (0x%s/0x%s)" % (major, minor, major_hex, minor_hex) print " power: %d (0x%s)" % (power, power_hex) print "min/max adv: %d/%d (0x%s/0x%s)" % (min_adv, max_adv, min_adv_hex, max_adv_hex) # first bring up bluetooth process_command("hciconfig %s up" % device) # now turn on LE advertising #process_command("hciconfig %s leadv" % device) # now turn off scanning process_command("hciconfig %s noscan" % device) # set up the beacon # pipe stdout to /dev/null to get rid of the ugly "here's what I did" # message from hcitool process_command("hcitool -i hci0 cmd 0x08 0x0008 1E 02 01 1A 1A FF 4C 00 02 15 %s %s %s %s 00 >/dev/null" % (split_uuid, split_major_hex, split_minor_hex, power_hex)) process_command("hcitool -i hci0 cmd 0x08 0x0006 %s %s 03 00 00 00 00 00 00 00 00 07 00" % (split_min_adv_hex, split_max_adv_hex)) process_command("hcitool -i hci0 cmd 0x08 0x000a 01")
def main(argv=None): # option flags global verbose global simulate # default uuid, this is the uuid that the "Beacon Toolkit" iOS app uses # https://itunes.apple.com/us/app/beacon-toolkit/id728479775 # can be overriden with environment variable uuid = os.getenv("IBEACON_UUID", "E20A39F473F54BC4A12F17D1AD07A961") # major and minor ids, can be overriden with environment variable major = int(os.getenv("IBEACON_MAJOR", "0")) minor = int(os.getenv("IBEACON_MINOR", "0")) # default to the first available bluetooth device device = "hci0" # default power level power = int(os.getenv("IBEACON_POWER", "200")) # regexp to test for a valid UUID # here the - separators are optional valid_uuid_match = re.compile('^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}$', re.I) # grab command line arguments if argv is None: argv = sys.argv # parse command line options try: try: opts, args = getopt.getopt(argv[1:], "hu:M:m:p:vd:nz", ["help", "uuid=", "major=", "minor=", "power=", "verbose", "device=", "simulate", "down"]) except getopt.error, msg: raise Usage(msg) for o, a in opts: if o in ("-h", "--help"): print __doc__ return 0 elif o in ("-n", "--simulate"): simulate = True verbose = True elif o in ("-u", "--uuid"): uuid = a if uuid == "random": uuid = get_random_uuid() elif o in ("-M", "--major"): major = int(a) elif o in ("-m", "--minor"): minor = int(a) elif o in ("-p", "--power"): power = int(a) elif o in ("-v", "--verbose"): verbose = True elif o in ( "-d", "--device"): temp_device = str(a) # devices can be specified as "X" or "hciX" if not temp_device.startswith("hci"): device = "hci%s" % temp_device else: device = temp_device elif o in ( "-z", "--down"): if check_for_sudo(): if is_valid_device(device): print "Downing iBeacon on %s" % device process_command("hciconfig %s noleadv" % device) process_command("hciconfig %s piscan" % device) process_command("hciconfig %s down" % device) return 0 else: print "Error: no such device: %s (try `hciconfig list')" % device return 1 else: return 1 # test for valid UUID if not valid_uuid_match.match(uuid): print "Error: `%s' is an invalid UUID." % uuid return 1 # strip out - symbols from uuid and turn it into uppercase uuid = uuid.replace("-","") uuid = uuid.upper() # bounds check major/minor ids if major < 0 or major > 65535: print "Error: major id is out of bounds (0-65535)" return 1 if minor < 0 or minor > 65535: print "Error: minor id is out of bounds (0-65535)" return 1 # bail if we're not running as superuser (don't care if we are simulating) if not simulate and not check_for_sudo(): return 1 # split the uuid into 8 bit (=2 hex digit) chunks split_uuid = hexsplit(uuid) # convert major/minor id into hex major_hex = hexify(major, 4) minor_hex = hexify(minor, 4) # create split versions of these (for the hcitool command) split_major_hex = hexsplit(major_hex) split_minor_hex = hexsplit(minor_hex) # convert power into hex power_hex = hexify(power, 2) # make sure we are using a valid hci device if not simulate and not is_valid_device(device): print "Error: no such device: %s (try `hciconfig list')" % device return 1 # print status info print "Advertising on %s with:" % device print " uuid: 0x%s" % uuid print "major/minor: %d/%d (0x%s/0x%s)" % (major, minor, major_hex, minor_hex) print " power: %d (0x%s)" % (power, power_hex) # first bring up bluetooth process_command("hciconfig %s up" % device) # now turn on LE advertising process_command("hciconfig %s leadv" % device) # now turn off scanning process_command("hciconfig %s noscan" % device) # set up the beacon # pipe stdout to /dev/null to get rid of the ugly "here's what I did" # message from hcitool process_command("hcitool -i hci0 cmd 0x08 0x0008 1E 02 01 1A 1A FF 4C 00 02 15 %s %s %s %s 00 >/dev/null" % (split_uuid, split_major_hex, split_minor_hex, power_hex))
def main(argv=None): # option flags global verbose global simulate # default uuid, this is the uuid that the "Beacon Toolkit" iOS app uses # https://itunes.apple.com/us/app/beacon-toolkit/id728479775 # can be overriden with environment variable uuid = os.getenv("IBEACON_UUID", "E20A39F473F54BC4A12F17D1AD07A961") # major and minor ids, can be overriden with environment variable major = int(os.getenv("IBEACON_MAJOR", "0")) minor = int(os.getenv("IBEACON_MINOR", "0")) # default to the first available bluetooth device device = "hci0" # default power level power = int(os.getenv("IBEACON_POWER", "200")) # regexp to test for a valid UUID # here the - separators are optional valid_uuid_match = re.compile( '^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}$', re.I) # grab command line arguments if argv is None: argv = sys.argv # parse command line options try: try: opts, args = getopt.getopt(argv[1:], "hu:M:m:p:vd:nz", [ "help", "uuid=", "major=", "minor=", "power=", "verbose", "device=", "simulate", "down" ]) except getopt.error, msg: raise Usage(msg) for o, a in opts: if o in ("-h", "--help"): print __doc__ return 0 elif o in ("-n", "--simulate"): simulate = True verbose = True elif o in ("-u", "--uuid"): uuid = a if uuid == "random": uuid = get_random_uuid() elif o in ("-M", "--major"): major = int(a) elif o in ("-m", "--minor"): minor = int(a) elif o in ("-p", "--power"): power = int(a) elif o in ("-v", "--verbose"): verbose = True elif o in ("-d", "--device"): temp_device = str(a) # devices can be specified as "X" or "hciX" if not temp_device.startswith("hci"): device = "hci%s" % temp_device else: device = temp_device elif o in ("-z", "--down"): if check_for_sudo(): if is_valid_device(device): print "Downing iBeacon on %s" % device process_command("hciconfig %s noleadv" % device) # process_command("hciconfig %s piscan" % device) process_command("hciconfig %s down" % device) return 0 else: print "Error: no such device: %s (try `hciconfig list')" % device return 1 else: return 1 # test for valid UUID if not valid_uuid_match.match(uuid): print "Error: `%s' is an invalid UUID." % uuid return 1 # strip out - symbols from uuid and turn it into uppercase uuid = uuid.replace("-", "") uuid = uuid.upper() # bounds check major/minor ids if major < 0 or major > 65535: print "Error: major id is out of bounds (0-65535)" return 1 if minor < 0 or minor > 65535: print "Error: minor id is out of bounds (0-65535)" return 1 # bail if we're not running as superuser (don't care if we are simulating) if not simulate and not check_for_sudo(): return 1 # split the uuid into 8 bit (=2 hex digit) chunks split_uuid = hexsplit(uuid) # convert major/minor id into hex major_hex = hexify(major, 4) minor_hex = hexify(minor, 4) # create split versions of these (for the hcitool command) split_major_hex = hexsplit(major_hex) split_minor_hex = hexsplit(minor_hex) # convert power into hex power_hex = hexify(power, 2) # make sure we are using a valid hci device if not simulate and not is_valid_device(device): print "Error: no such device: %s (try `hciconfig list')" % device return 1 # print status info print "Advertising on %s with:" % device print " uuid: 0x%s" % uuid print "major/minor: %d/%d (0x%s/0x%s)" % (major, minor, major_hex, minor_hex) print " power: %d (0x%s)" % (power, power_hex) # first bring up bluetooth process_command("hciconfig %s up" % device) # now turn on LE advertising (3 => non-connectable advertisement) # now turn off scanning process_command("hciconfig %s noscan" % device) # set up the beacon # 1E Number of bytes that follow in the advertisement # 02 Number of bytes that follow in first AD structure # 01 Flags AD type # 1A Flags value 0x1A = 000011010 # bit 0 (OFF) LE Limited Discoverable Mode # bit 1 (ON) LE General Discoverable Mode # bit 2 (OFF) BR/EDR Not Supported # bit 3 (ON) Simultaneous LE and BR/EDR to Same Device Capable (controller) # bit 4 (ON) Simultaneous LE and BR/EDR to Same Device Capable (Host) # 1A Number of bytes that follow in second (and last) AD structure # FF Manufacturer specific data AD type # 4C Company identifier code LSB # 00 Company identifier code MSB (0x004C == Apple) # 02 Byte 0 of iBeacon advertisement indicator # 15 Byte 1 of iBeacon advertisement indicator process_command( "hcitool -i %s cmd 0x08 0x0008 1E 02 01 1A 1A FF 4C 00 02 15 %s %s %s %s 00 >/dev/null" % (device, split_uuid, split_major_hex, split_minor_hex, power_hex)) # https://esf.eurotech.com/docs/how-to-user-bluetooth-le-beacons # http://stackoverflow.com/questions/21124993/is-there-a-way-to-increase-ble-advertisement-frequency-in-bluez # 0-3 A0 00 min interval - A0 00 => 100ms => (100ms = 0x0A * 0.625ms), 40 06 => (1000ms = 0x0640 * 0.625ms) # 4-7 A0 00 max interval - A0 00 => 100ms => (100ms = 0x0A * 0.625ms), 40 06 => (1000ms = 0x0640 * 0.625ms) # 8-11 03 00 leadv 3 # 0 4 8 12 16 20 24 process_command( "hcitool -i %s cmd 0x08 0x0006 A0 00 A0 00 03 00 00 00 00 00 00 00 00 07 00" % device) # (0x08 0x000a) is "LE Set Advertise Enable" process_command("hcitool -i %s cmd 0x08 0x000a 01" % device)