Ejemplo n.º 1
0
 def displayCapabilities(self):
     capabilitiesList = []
     for capability in self.capabilities:
         capabilitiesList.append([
             capability,
             (io.colorize("yes", "green")
              if self.emitter.hasCapabilities(capability) else io.colorize(
                  "no", "red"))
         ])
     io.chart(["Capability", "Available"], capabilitiesList)
Ejemplo n.º 2
0
 def updatePrompt(self, address=""):
     if address is None:
         address = ""
     self.prompt = io.colorize(
         "[PRX|" + (" " + str(self.currentChannel) if len(
             str(self.currentChannel)) != 2 else str(self.currentChannel)) +
         ("|" + address if address != "" else "") + "]: ", "cyan")
Ejemplo n.º 3
0
	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")
			)
Ejemplo n.º 4
0
	def __init__(self,prompt=io.colorize(" ~~> ", "cyan")):
		''' 
		This constructor initializes the interpreter instance.
		:param prompt: string used to generate the prompt
		:type prompt: str	
		'''
		self.prompt = prompt
		self.running = True
		self.availableCommands = ["exit"]
Ejemplo n.º 5
0
	def connections(self):
		counter = 1
		connectionsList = []
		for connection in self.emitter.getConnections():
			connectionsList.append([str(counter),connection["address"], connection["handle"]])
			counter += 1
		if connectionsList == []:
			io.fail("No active connections !")
		else:
			io.chart(["Identifier", "Address", "Handle"],connectionsList,io.colorize("Active connections","yellow"))
Ejemplo n.º 6
0
	def showargs(self):
		'''
		This method displays a chart describing the available input parameters for the loaded module.
		'''
		for module in self.modules:
			currentArgs = []
			for argument in module["module"].args:
				argName = (module["name"]+"."+argument) if len(self.modules)>1 else argument
				argValue = module["module"].args[argument]
				currentArgs.append([argName, argValue])
			io.chart(["Name","Value"],currentArgs,io.colorize(module["name"],"yellow"))
Ejemplo n.º 7
0
	def showargs(self):
		'''
		This method displays a chart describing the available input parameters for the loaded module.
		'''
		for module in self.modules:
			currentArgs = []
			if "shortcut" not in module:
				for argument in module["module"].args:
					argName = (module["name"]+"."+argument) if len(self.modules)>1 else argument
					argValue = module["module"].args[argument]
					currentArgs.append([argName, argValue])
				io.chart(["Name","Value"],currentArgs,io.colorize(module["name"],"yellow"))
			else:
				for argument in module["mapping"]:
					argName = (module["name"]+"."+argument) if len(self.modules)>1 else argument
					if module["mapping"][argument]["value"] is not None:
						argValue =  module["mapping"][argument]["value"]
					else:
						argValue = "<auto>"
					currentArgs.append([argName, argValue])
				io.chart(["Name", "Value"], currentArgs,io.colorize(module["name"],"green"))
Ejemplo n.º 8
0
 def printServices(self, services, title="Services"):
     formattedServices = []
     for service in services:
         startHandle = "0x{:04x}".format(service["startHandle"])
         endHandle = "0x{:04x}".format(service["endHandle"])
         uuid16 = (hex(service["uuid"].UUID16)
                   if service["uuid"].UUID16 is not None else "")
         uuid128 = (service["uuid"].UUID128.hex()
                    if service["uuid"].UUID128 is not None else "")
         name = (service["uuid"].name
                 if service["uuid"].name is not None else "")
         formattedServices.append(
             [startHandle, endHandle, uuid16, uuid128, name])
     io.chart(["Start Handle", "End Handle", "UUID16", "UUID128", "Name"],
              formattedServices, io.colorize(title, "yellow"))
Ejemplo n.º 9
0
    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"))
Ejemplo n.º 10
0
    def load(self, moduleName: "!method:_autocompleteModules"):
        '''
		This method allows to load a module according to its name.
		It allows to load a sequence of modules by using the pipe (``|``) symbol.
		
		:param moduleName: name of the module (or sequence of modules) to load
		:type moduleName: str

		:Example:

		>>> app.load('ble_info')
		>>> app.load('ble_connect|ble_discover')

		'''
        modules = moduleName.split("|") if "|" in moduleName else [moduleName]
        tmpModules = []
        counter = 1
        noError = True
        for m in modules:
            output = self.loader.load(m)
            if output is not None:
                io.info("Module " + m + " loaded !")
                tmpModules.append({
                    "name":
                    m + str(counter) if len(modules) > 1 else m,
                    "module":
                    output
                })
                counter += 1

                for argument in output.args:
                    if self.config.dataExists(m, argument):
                        output.args[argument] = self.config.getData(
                            m, argument)

            else:
                io.fail("Unknown module " + m + " !")
                noError = False
                break
        if noError:
            self.modules = tmpModules
            self.prompt = io.colorize(" << " + moduleName + " >>~~> ", "cyan")
Ejemplo n.º 11
0
	def showServices(self):
		'''
		This method displays the GATT services described as attributes included in the Database.
		'''
		formattedServices = []
		for att in self.attributes:
			if att is not None and (att.type == UUID(name="Primary Service") or att.type == UUID(name="Secondary Service")):
				startHandle = "0x{:04x}".format(att.handle)
				service = Service(data=att.value[::-1])
				serviceName = service.UUID.name if service.UUID.name is not None else ""
				serviceUUID16 = "0x{:04x}".format(service.UUID.UUID16) if service.UUID.UUID16 is not None else ""
				serviceUUID128 = service.UUID.UUID128.hex() if service.UUID.UUID128 is not None else ""
				if len(formattedServices) > 0:
					formattedServices[-1][1] = "0x{:04x}".format(att.handle - 1)
				formattedServices.append([startHandle,"0x{:04x}".format(0xFFFF),serviceUUID16, serviceUUID128,serviceName])
		io.chart(["Start Handle","End Handle", "UUID16", "UUID128", "Name"],
			 formattedServices,
			 io.colorize("Services", "yellow")
			)
		return formattedServices
Ejemplo n.º 12
0
    def __init__(self,
                 prompt=io.colorize(" ~~> ", "cyan"),
                 autocompletion=True,
                 suggestion=True):
        ''' 
		This constructor initializes the interpreter instance.
		:param prompt: string used to generate the prompt
		:type prompt: str
		:param autocompletion: boolean indicating if the autocompletion mode is enabled
		:type autocompletion: bool
		:param suggestion: boolean indicating if the suggestion mode is enabled
		:type suggestion: bool
		'''
        self.prompt = prompt
        self.running = True
        self.autocompletionMode = autocompletion
        self.suggestionMode = suggestion
        self.suggestion = ""
        self.usage = ""
        self.cursorOffset = 0
        self.availableCommands = ["exit"]
Ejemplo n.º 13
0
	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")
			)
Ejemplo n.º 14
0
 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"))
Ejemplo n.º 15
0
 def updatePrompt(self, address=""):
     self.prompt = io.colorize(
         "[SLAVE" + ("|" + address if address != "" else "") + "]: ",
         "cyan")
Ejemplo n.º 16
0
	def load(self,moduleName:"!method:_autocompleteModules"):
		'''
		This method allows to load a module according to its name.
		It allows to load a sequence of modules by using the pipe (``|``) symbol.

		:param moduleName: name of the module (or sequence of modules) to load
		:type moduleName: str

		:Example:

		>>> app.load('ble_info')
		>>> app.load('ble_connect|ble_discover')

		'''
		modules = moduleName.split("|") if "|" in moduleName else [moduleName]
		tmpModules = []
		counter = 1
		noError = True
		for m in modules:
			output = self.loader.load(m)
			if output is not None:
				io.info("Module "+m+" loaded !")
				tmpModules.append({"name":m+str(counter) if len(modules) > 1 else m,"module":output})
				counter+=1

				for argument in output.args:
					if self.config.dataExists(m,argument):
						output.args[argument] = self.config.getData(m,argument)

			elif m in self.loadedShortcuts:
				io.info("Shortcut "+m+" loaded !")
				shortcutModules = []
				shortcutClasses = []
				shortcutCounter = 1
				shortcutModulesList = self.loadedShortcuts[m]["modules"].split("|")
				for n in shortcutModulesList:
					output = self.loader.load(n)
					shortcutModules.append({
						"name":n+str(shortcutCounter) if len(shortcutModulesList) > 1 else n,
						"module":output
					})
					for argument in self.loadedShortcuts[m]["mapping"]:
						mapping = self.loadedShortcuts[m]["mapping"][argument]
						if mapping["value"] is not None:
							self._set(argument,mapping["value"],[shortcutModules[-1]])

					shortcutCounter+=1

				tmpModules.append({
						"name":m+str(counter) if len(modules) > 1 else m,
						"shortcut":shortcutModules,
						"mapping":self.loadedShortcuts[m]["mapping"]
						})
				counter+=1
			else:
				io.fail("Unknown module "+m+" !")
				noError = False
				break
		if noError:
			self.modules = tmpModules
			self.prompt = io.colorize(" << "+moduleName+" >>~~> ","cyan")