def initializeBatteryService(self): self.server.addPrimaryService(ble.UUID(name="Battery Service").data) self.server.addCharacteristic( ble.UUID(name="Battery Level").data, b"0000000000") self.server.addDescriptor( ble.UUID(name="Client Characteristic Configuration").data, b"\x01\x00") self.server.addDescriptor( ble.UUID(name="Characteristic Presentation Format").data, b"\x04\x00\xad\x27\x01\x00\x00")
def initializeHIDService(self): self.server.addPrimaryService( ble.UUID(name="Human Interface Device").data) self.server.addCharacteristic(ble.UUID(name="Report").data, b"\x00\x00\x00\x00\x00\x00\x00\x00", permissions=["Read", "Write", "Notify"]) self.server.addDescriptor( ble.UUID(name="Client Characteristic Configuration").data, b"\x00", permissions=["Read", "Write", "Notify"]) self.server.addDescriptor( ble.UUID(name="Report Reference").data, b"\x01\x01", permissions=["Read", "Write", "Notify" ]) # report ID 0x00, report type (0x01 = input) self.server.addCharacteristic( ble.UUID(name="Report Map").data, REPORT_MAP) self.server.addCharacteristic( ble.UUID(name="HID Information").data, bytes.fromhex("00010002") ) # version=0x0100 countrycode=0x00 flags=0x02(normally connectable) self.server.addCharacteristic(ble.UUID(name="HID Control Point").data, b"\x00", permissions=['Write Without Response']) self.server.addCharacteristic( ble.UUID(name="Protocol Mode").data, b"\x01", permissions=['Write Without Response', 'Read', 'Notify'])
def parseFilterType(self): filterType = self.args["FILTER"] if filterType == "": return None if utils.isNumber(filterType): return ble.UUID(UUID16=int(filterType)).data elif utils.isHexadecimal(filterType) and len(filterType) <= 6: return ble.UUID(UUID16=int(filterType, 16)).data elif utils.isHexadecimal(filterType) and len(filterType) > 6: uuid = ble.UUID(UUID128=bytes.fromhex(filterType)).data if uuid is None: return bytes.fromhex(filterType) else: return uuid else: return ble.UUID(name=filterType).data
def addPrimaryService(self): # Tx Power Level primary service self.module.server.addPrimaryService(ble.UUID(name="Tx Power").data) # Tx Power Level characteristic self.module.server.addCharacteristic(bytes.fromhex('2A07'), self.txPwLvl, permissions=["Read", "Notify"]) # 20 dbm
def characteristicsDiscovery(self, startHandle=0x0001, endHandle=0xFFFF): characteristicDeclarationUUID = ble.UUID( name="Characteristic Declaration").UUID16 start, end, continuer = startHandle, endHandle, True characteristics = [] while continuer: request = ble.BLEReadByTypeRequest( startHandle=start, endHandle=end, uuid=characteristicDeclarationUUID) self.emitter.sendp(request) p = self.receive([ble.BLEReadByTypeResponse, ble.BLEErrorResponse], retry=request) if isinstance(p, ble.BLEReadByTypeResponse): for i in p.attributes: characteristicDeclaration = ble.CharacteristicDeclaration( data=i['value'][::-1]) characteristic = { "declarationHandle": i["attributeHandle"], "valueHandle": characteristicDeclaration.valueHandle, "uuid": characteristicDeclaration.UUID, "permissionsFlag": characteristicDeclaration.permissionsFlag, "value": b"" } if "Read" in characteristicDeclaration.permissionsFlag: request = ble.BLEReadRequest( handle=characteristicDeclaration.valueHandle) self.emitter.sendp(request) p = self.receive( [ble.BLEReadResponse, ble.BLEErrorResponse], retry=request) if isinstance(p, ble.BLEReadResponse): characteristic["value"] = p.value characteristics.append(characteristic) start = i["attributeHandle"] start = start + 1 continuer = (start <= 0xFFFF) elif isinstance(p, ble.BLEErrorResponse): continuer = False else: pass return characteristics
def enableAdvertising(self): advertisementServices = ( ble.UUID(UUID16=0x180F).data[::-1] + # Battery Service ble.UUID(UUID16=0x180A).data[::-1] + # Device Information Service ble.UUID(UUID16=0x1812).data[::-1] # BLE HID Service ) data = bytes([ # Length 2, # Flags data type value. 0x01, # BLE general discoverable, without BR/EDR support. 0x01 | 0x04, # Length. 1 + len(advertisementServices), # Complete list of 16-bit Service UUIDs data type value. 0x03, ]) + advertisementServices self.emitter.setAdvertisingParameters(data=data) self.emitter.setScanningParameters( data=bytes.fromhex("0d094576696c4b6579626f617264") + data) self.emitter.setAdvertising(enable=True)
def printAttributes(self, attributes): formattedAttributes = [] for attribute in attributes: aType = ble.UUID(data=attribute["type"]) if aType.name is not None: attributeType = aType.name elif aType.UUID16 is not None: attributeType = hex(aType.UUID16) else: attributeType = aType.UUID128.hex() attributeValue = attribute["value"].replace( b"\x00", b"").decode("ascii") if utils.isPrintable( attribute["value"]) else attribute["value"].hex() attributeHandle = "0x{:04x}".format(attribute["handle"]) formattedAttributes.append( [attributeHandle, attributeType, attributeValue]) io.chart(["Attribute Handle", "Attribute Type", "Attribute Value"], formattedAttributes, io.colorize("Attributes", "yellow"))
def startAdv(self): # Advertisement data sent with ADV_IND advServices = (ble.UUID(name="Tx Power").data[::-1]) advData = bytes([ # Length 2, # Flags data type value. 0x01, # BLE general discoverable, without BR/EDR support. 0x01 | 0x04, # Length 2, # Tx Power Level data type value 0x0A, # Tx Power Level ]) + self.txPwLvl + bytes([ # Length 1 + len(self.shortName), # Local short name 0x08, # short name ]) + str.encode(self.shortName) + bytes([ # Length 1 + len(advServices), # Complete list of 16-bit Service UUIDs data type value. 0x03, # services ]) + advServices self.module.emitter.setAdvertisingParameters(type='ADV_IND', data=advData) self.module.emitter.setAdvertising(enable=True) io.info('Currently advertising ' + advData.hex() + ' using ' + self.args['INTERFACE'])
def initializeDeviceInformationService(self): self.server.addPrimaryService(ble.UUID(name="Device Information").data) self.server.addCharacteristic( ble.UUID(name="Manufacturer Name String").data, b"EvilKeyboard") self.server.addCharacteristic( ble.UUID(name="PnP ID").data, bytes.fromhex("014700ffffffff"))
def secondaryServicesDiscovery(self, startHandle=0x0001, endHandle=0xffff): uuid = ble.UUID(name="Secondary Service").UUID16 return self.servicesDiscovery(uuid, startHandle=startHandle, endHandle=endHandle)