Example #1
0
 def getRaw(self):
     return (
         super(HCI_Cmd, self).getRaw()
         + p16(self.opcode)
         + p8(self.length)
         + self.data
     )
Example #2
0
 def recvPacket(self, record):
     hcipkt = record[0]
     if not issubclass(hcipkt.__class__, HCI_Event):
         return
     if hcipkt.event_code != 0xFF:
         return
     # TODO Android 8 introduced special handling for 0x57 HCI_VSE_SUBCODE_DEBUG_INFO_SUB_EVT,
     # stackdumps might no longer work
     if hcipkt.data[0] == 0x57:
         self.handleNexus6pStackDump(hcipkt)
     if hcipkt.data[0:4] == p32(0x039200F7):
         self.handleNexus5StackDump(hcipkt)
     # same header for S10 and evaluation board...
     if hcipkt.data[0:2] == p16(
         0x031B
     ):  # generated by bthci_event_vs_initializeCoredumpHdr()
         self.handleEvalStackDump(hcipkt)
         self.handleS10StackDump(hcipkt)
Example #3
0
 def work(self, args):
     """Debugs which key length is currently active within a connection handle."""
     internalblue.sendHciCommand(hci.HCI_COMND.Encryption_Key_Size,
                                 p16(args.hnd))
     return True
Example #4
0
    def _hciEventHandler(self, h4_record):
        event = h4_record.event_code
        hci_data = h4_record.data
        status = hci_data[0]

        # connection complete event
        if event == 3:
            # connection complete - sucess
            if status == 0:
                handle = struct.unpack_from("h", hci_data[1:])[0]
                self.handle = handle
                log.info("Connection to %s complete",
                         binascii.hexlify(self.remote_addr).decode("utf-8"))
                self.keepalive_active = True
                self._keepaliveTimer()
            # connection complete - page timeout
            elif status == 4:
                log.info("Page timeout while connecting to %s",
                         binascii.hexlify(self.remote_addr).decode("utf-8"))
        # disconnection complete event
        elif event == 5:
            self.handle = None
            log.info("Disconnected from " +
                     binascii.hexlify(self.remote_addr).decode("utf-8"))
            if self.reconnect_counter < self.reconnect:
                log.info("Trying to reconnect (attempt %d of %d)",
                         self.reconnect_counter, self.reconnect)
                # wait a second, otherwise we sometimes don't get the connection complete event...
                time.sleep(1)
                self.connect()
                self.reconnect_counter += 1
        # authentication complete
        elif event == 6:
            # workaround as there is apparently a bug in pythons struct
            (status, ) = struct.unpack_from("b", hci_data)
            (handle, ) = struct.unpack_from("h", hci_data[1:])

            log.info("got Authentication Complete from handle %s, status: %d",
                     hex(handle), status)
            if status == 0:
                # authentication was successful, now set connection encryption
                self.core.sendHciCommand(0x0413, p16(handle) + "\x01")
                self.encrypted = True
                if self.encryption_callback:
                    self.encryption_callback()
                pass
            else:
                handle = 0
        # encryption change complete
        elif event == 8:
            (handle, encrypt) = struct.unpack_from("hb", hci_data)
            log.info(
                "Got Encryption Change Complete from handle %s, encrypt: %d",
                hex(handle), encrypt)
        # pin code request
        elif event == 0x16:
            (bd_addr, ) = struct.unpack_from("6s", hci_data)
            log.info("Got Pin Code Request for %s",
                     binascii.hexlify(bd_addr).decode("utf-8"))
            self.core.sendHciCommand(0x040d, bd_addr + "\x00" + "\x41" * 0x10)
        # link key request
        elif event == 0x17:
            (bd_addr, ) = struct.unpack_from("6s", hci_data)
            log.info("Got Link Key request from %s",
                     binascii.hexlify(bd_addr).decode("utf-8"))
            # link keys are not really implemented yet, just return a random link key
            self.core.sendHciCommand(
                0x040b,
                bd_addr + bytes.fromhex("0d2017c7f90a78cefeeed32210e6519a"))
            return

            if bd_addr in self.link_keys:
                # we have a link key for this device, set it
                lkey_buf = self.link_keys[bd_addr][::-1]
                self.core.sendHciCommand(0x040b, bd_addr + lkey_buf)
            else:
                # send negative link key reply, we don't have a key
                self.core.sendHciCommand(0x040c, bd_addr)

        # link key notification
        elif event == 0x18:
            (bd_addr, link_key) = struct.unpack_from("6s16s", hci_data)
            log.info("Got Link Key notification from %s, key: %s", bd_addr,
                     binascii.hexlify(link_key).decode("utf-8"))
            self.link_keys[bd_addr] = link_key
        # io capability request
        elif event == 0x31:
            (bd_addr, ) = struct.unpack_from("6s", hci_data)
            log.info("Got IO capability request from %s",
                     binascii.hexlify(bd_addr).decode("utf-8"))
            # pretend to not have a display or oob data present
            # no display: 0x03, no oob: 0x00, auth requirements: 0x02
            self.core.sendHciCommand(0x042b, bd_addr + "\x03\x00\x02")
        # user confirmation request
        elif event == 0x33:
            (bd_addr, ) = struct.unpack_from("6s", hci_data)
            log.info("Got user confirmation request from %s",
                     binascii.hexlify(bd_addr).decode("utf-8"))
            # we just accept any confirmation requests
            self.core.sendHciCommand(0x42c, bd_addr)
        # simple pairing complete
        elif event == 0x36:
            (bd_addr, ) = struct.unpack_from("6s", hci_data)
            log.info("Got simple pairing complete from %s",
                     binascii.hexlify(bd_addr).decode("utf-8"))
        # le event
        # everything from le lands here...
        elif event == 0x3e:
            le_event_type = hci_data[0]
            le_handle = struct.unpack_from("h", hci_data[2:4])[0]
            # enhanced connection complete
            if le_event_type == 0x0a:
                log.info(
                    "Got le enhanced connection complete, removing device from whitelist"
                )
                self.core.sendHciCommand(
                    0x2012,
                    bytes.fromhex("00") + self.remote_addr[::-1])
            elif le_event_type == 0x01:
                # sometimes we get connection complete events from previous sessions
                log.info("got le connection complete with handle %d",
                         le_handle)
                if self.started_connection:
                    self.handle = le_handle
                else:
                    log.info(
                        "but ignoring it as we did not initiate this connection"
                    )
Example #5
0
 def sendACL(self, data):
     data_len = p16(len(data))
     handle = p16(self.handle | 0x2000)
     log.debug("Sent acl data: %s", binascii.hexlify(data).decode("utf-8"))
     self.core.sendH4(0x02, handle + data_len + data)
Example #6
0
 def getRaw(self):
     raw = bits(p16(self.handle))[4:]
     raw.extend(bits(p8(self.ps))[6:])
     raw.extend(bits(p8(0))[6:])
     raw.extend(bits(p8(self.length)))
     return super(HCI_Sco, self).getRaw() + unbits(raw) + self.data
Example #7
0
 def do_knob(self, args):
     """Introduce a new CLI command to make KNOB debugging easier..."""
     internalblue.sendHciCommand(hci.HCI_COMND.Encryption_Key_Size,
                                 p16(args.hnd))
     return None
Example #8
0
 def sendCFrame(self, code, identifier, data):
     data_len = len(data) / 2
     self.sendCFrameRaw(code, identifier, p16(data_len), data)
Example #9
0
 def sendData(self, data, cid):
     data_len = len(data)
     # if data_len > mtu
     log.debug("Sent L2CAP data to channel: %d, data: %s", cid,
               binascii.hexlify(data))
     self.connection.sendACL(p16(data_len) + p16(cid) + data)