def showCharacteristics(self,startHandle,endHandle,title="Characteristics"): ''' This method displays the GATT characteristics described as attributes included in the Database and provide a mechanism to only select the characteristics between two handles (it is mainly used in order to print the characteristics included in a Service). :param startHandle: first ATT handle :type startHandle: int :param endHandle: last ATT handle :type endHandle: int :param title: Title of the chart :type title: str ''' formattedCharacteristics = [] for i in range(startHandle,endHandle): if i < len(self.attributes): att = self.attributes[i] if att.type == UUID(name="Characteristic Declaration"): declarationHandle = "0x{:04x}".format(att.handle) characteristic = CharacteristicDeclaration(data=att.value[::-1]) uuid16 = ("0x{:04x}".format(characteristic.UUID.UUID16) if characteristic.UUID.UUID16 is not None else "" ) uuid128 = (characteristic.UUID.UUID128.hex() if characteristic.UUID.UUID128 is not None else "" ) name = (characteristic.UUID.name if characteristic.UUID.name is not None else "" ) valueHandle = "0x{:04x}".format(characteristic.valueHandle) value = self.attributes[characteristic.valueHandle].value value = (value.replace(b"\x00",b"").decode("ascii") if utils.isPrintable(value) else value.hex() ) permissions = ",".join(characteristic.permissionsFlag.permissions) startDescriptor = characteristic.valueHandle + 1 descriptors = "" while (startDescriptor < len(self.attributes) and self.attributes[startDescriptor] is not None and (self.attributes[startDescriptor].type != UUID(name="Characteristic Declaration") and self.attributes[startDescriptor].type != UUID(name="Primary Service") and self.attributes[startDescriptor].type != UUID(name="Secondary Service"))): descriptor = self.attributes[startDescriptor] namedesc = CharacteristicDescriptor(UUID=descriptor.type).UUID.name valuedesc = (descriptor.value.replace(b"\x00",b"").decode("ascii") if utils.isPrintable(descriptor.value) else descriptor.value.hex() ) startSymbol = "" if descriptors == "" else "\n" descriptors += startSymbol + namedesc +" : "+ valuedesc startDescriptor += 1 formattedCharacteristics.append([declarationHandle, valueHandle, uuid16, uuid128, name,permissions,value,descriptors]) io.chart(["Declaration Handle","Value Handle","UUID16","UUID128","Name","Permissions", "Value","Descriptors"] ,formattedCharacteristics, io.colorize(title, "yellow") )
def toString(self): return "<< " + self.name + " | srcAddr = " + helpers.addressToString( self.srcAddr) + " | destAddr = " + helpers.addressToString( self.destAddr) + " | destPanID = " + hex( self.destPanID) + " | counter = " + str( self.counter) + " | unknown = " + str( self.unknown) + " | data = " + self.data.hex() + ( " ('" + self.data.decode('utf-8').replace( "\r\n", "\\r\\n") + "')" if utils.isPrintable(self.data) else "") + " >>"
def printCharacteristics(self, characteristics, title="Characteristics"): formattedCharacteristics = [] for characteristic in characteristics: declarationHandle = "0x{:04x}".format( characteristic["declarationHandle"]) valueHandle = "0x{:04x}".format(characteristic["valueHandle"]) permissionsFlag = ",".join(characteristic["permissionsFlag"]) uuid16 = (hex(characteristic["uuid"].UUID16) if characteristic["uuid"].UUID16 is not None else "") uuid128 = (characteristic["uuid"].UUID128.hex() if characteristic["uuid"].UUID128 is not None else "") name = (characteristic["uuid"].name if characteristic["uuid"].name is not None else "") value = (characteristic["value"].replace(b"\x00", b"").decode("ascii") if utils.isPrintable(characteristic["value"]) else characteristic["value"].hex()) descriptors = "" if "descriptors" in characteristic: for desc in characteristic["descriptors"]: namedesc = ble.CharacteristicDescriptor( data=desc["type"]).UUID.name valuedesc = ( desc["value"].replace(b"\x00", b"").decode("ascii") if utils.isPrintable(desc["value"]) and len(desc["value"]) > 0 else desc["value"].hex()) endSymbol = "\n" if characteristic["descriptors"][ -1] != desc else "" descriptors += namedesc + " : " + valuedesc + endSymbol formattedCharacteristics.append([ declarationHandle, valueHandle, uuid16, uuid128, name, permissionsFlag, value, descriptors ]) io.chart([ "Declaration Handle", "Value Handle", "UUID16", "UUID128", "Name", "Permissions", "Value", "Descriptors" ], formattedCharacteristics, io.colorize(title, "yellow"))
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 show(self): ''' This method displays a chart to present the ATT level vision of the attributes included in the Database. ''' formattedAttributes = [] for att in self.attributes: if att is not None: aType = att.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 = att.value.replace(b"\x00",b"").decode("ascii") if utils.isPrintable(att.value) else att.value.hex() attributeHandle = "0x{:04x}".format(att.handle) formattedAttributes.append([attributeHandle, attributeType,attributeValue]) io.chart(["Attribute Handle", "Attribute Type", "Attribute Value"], formattedAttributes, io.colorize("Attributes","yellow") )