Example #1
0
    def _recvThreadFunc(self):

        log.debug("Receive Thread started.")

        while not self.exit_requested:
            # Little bit ugly: need to re-apply changes to the global context to the thread-copy
            context.log_level = self.log_level

            # read record data
            try:
                data, addr = self.s_snoop.recvfrom(1024)
                record_data = data
            except socket.timeout:
                continue # this is ok. just try again without error

            if not self.exit_requested:
                # Put all relevant infos into a tuple. The HCI packet is parsed with the help of hci.py.
                record = (hci.parse_hci_packet(record_data), 0, 0, 0, 0, 0) #TODO not sure if this causes trouble?
                log.debug("Recv: " + str(record[0]))
                log.info(binascii.hexlify(record_data))

                # Put the record into all queues of registeredHciRecvQueues if their
                # filter function matches.
                for queue, filter_function in self.registeredHciRecvQueues: # TODO filter_function not working with bluez modifications
                    try:
                        queue.put(record, block=False)
                    except Queue.Full:
                        log.warn("recvThreadFunc: A recv queue is full. dropping packets..>" + record_data)

                # Call all callback functions inside registeredHciCallbacks and pass the
                # record as argument.
                for callback in self.registeredHciCallbacks:
                    callback(record)

        log.debug("Receive Thread terminated.")
Example #2
0
    def _recvThreadFunc(self):

        log.debug("Receive Thread started.")

        if self.write_btsnooplog:
            log.warn("Writing btsnooplog is not supported with iOS.")

        while not self.exit_requested:
            # Little bit ugly: need to re-apply changes to the global context to the thread-copy
            context.log_level = self.log_level

            # read record data
            try:
                received_data = self.s_snoop.recv(1024)
            except socket.timeout:
                continue  # this is ok. just try again without error

            # because the iOS socket is rather unreliable (blame the iOS proxy developer) we
            # need to do some length checks and get the H4/HCI data in the right format
            #log.info("H4 Data received")
            #log.info(received_data.encode('hex'))

            (record_data,
             is_more) = self._getLatestH4Blob(new_data=received_data)
            while record_data is not None:
                # Put all relevant infos into a tuple. The HCI packet is parsed with the help of hci.py.
                record = (hci.parse_hci_packet(record_data), 0, 0, 0, 0, 0)

                log.debug("Recv: " + str(record[0]))

                # Put the record into all queues of registeredHciRecvQueues if their
                # filter function matches.
                for queue, filter_function in self.registeredHciRecvQueues:  # TODO filter_function not working with bluez modifications
                    try:
                        queue.put(record, block=False)
                    except Queue.Full:
                        log.warn(
                            "recvThreadFunc: A recv queue is full. dropping packets.."
                        )

                # Call all callback functions inside registeredHciCallbacks and pass the
                # record as argument.
                for callback in self.registeredHciCallbacks:
                    callback(record)

                # Check if the stackDumpReceiver has noticed that the chip crashed.
                if self.stackDumpReceiver.stack_dump_has_happend:
                    # A stack dump has happend!
                    log.warn(
                        "recvThreadFunc: The controller send a stack dump. stopping.."
                    )
                    self.exit_requested = True

                (record_data, is_more) = self._getLatestH4Blob()
                if not is_more:
                    break

        log.debug("Receive Thread terminated.")
Example #3
0
    def _recvThreadFunc(self):
        """
        This is the run-function of the recvThread. It receives HCI events from the
        s_snoop socket. The HCI packets are encapsulated in btsnoop records (see RFC 1761).
        Received HCI packets are being put into the queues inside registeredHciRecvQueues and
        passed to the callback functions inside registeredHciCallbacks.
        The thread stops when exit_requested is set to True. It will do that on its own
        if it encounters a fatal error or the stackDumpReceiver reports that the chip crashed.
        """

        log.debug("Receive Thread started.")

        if (self.write_btsnooplog):
            log.warn("Writing btsnooplog is not supported with bluez.")

        while not self.exit_requested:
            # Little bit ugly: need to re-apply changes to the global context to the thread-copy
            context.log_level = self.log_level

            # Read the record data
            try:
                record_data = self.s_snoop.recv(1024)
            except socket.timeout:
                continue  # this is ok. just try again without error

            # Put all relevant infos into a tuple. The HCI packet is parsed with the help of hci.py.
            record = (hci.parse_hci_packet(record_data), 0, 0, 0, 0, 0
                      )  #TODO not sure if this causes trouble?

            log.debug("Recv: " + str(record[0]))

            # Put the record into all queues of registeredHciRecvQueues if their
            # filter function matches.
            for queue, filter_function in self.registeredHciRecvQueues:  # TODO filter_function not working with bluez modifications
                try:
                    queue.put(record, block=False)
                except Queue.Full:
                    log.warn(
                        "recvThreadFunc: A recv queue is full. dropping packets.."
                    )

            # Call all callback functions inside registeredHciCallbacks and pass the
            # record as argument.
            for callback in self.registeredHciCallbacks:
                callback(record)

            # Check if the stackDumpReceiver has noticed that the chip crashed.
            if self.stackDumpReceiver.stack_dump_has_happend:
                # A stack dump has happend!
                log.warn(
                    "recvThreadFunc: The controller send a stack dump. stopping.."
                )
                self.exit_requested = True

        log.debug("Receive Thread terminated.")
Example #4
0
    def _recvThreadFunc(self):

        log.debug("Receive Thread started.")

        if self.write_btsnooplog:
            log.warn("Writing btsnooplog is not supported with iOS.")

        while not self.exit_requested:
            # Little bit ugly: need to re-apply changes to the global context to the thread-copy
            context.log_level = self.log_level

            # read record data
            try:
                record_data = self.s_snoop.recv(1024)
            except socket.timeout:
                continue  # this is ok. just try again without error

            #log.info(record_data.encode('hex'))
            # TODO issue here is that sometimes, one event is cut into two and then cannot be interpreted any more
            # Bugfix: do some checks on what we got

            if len(record_data) < 8 or record_data[0] != '\x04':
                log.warn("Invalid event returned")
                continue

            # Put all relevant infos into a tuple. The HCI packet is parsed with the help of hci.py.
            record = (hci.parse_hci_packet(record_data), 0, 0, 0, 0, 0
                      )  #TODO not sure if this causes trouble?

            log.debug("Recv: " + str(record[0]))

            # Put the record into all queues of registeredHciRecvQueues if their
            # filter function matches.
            for queue, filter_function in self.registeredHciRecvQueues:  # TODO filter_function not working with bluez modifications
                try:
                    queue.put(record, block=False)
                except Queue.Full:
                    log.warn(
                        "recvThreadFunc: A recv queue is full. dropping packets.."
                    )

            # Call all callback functions inside registeredHciCallbacks and pass the
            # record as argument.
            for callback in self.registeredHciCallbacks:
                callback(record)

            # Check if the stackDumpReceiver has noticed that the chip crashed.
            if self.stackDumpReceiver.stack_dump_has_happend:
                # A stack dump has happend!
                log.warn(
                    "recvThreadFunc: The controller send a stack dump. stopping.."
                )
                self.exit_requested = True

        log.debug("Receive Thread terminated.")
Example #5
0
    def _recvThreadFunc(self):
        """
        This is the run-function of the recvThread. It receives HCI events from the
        s_snoop socket. The HCI packets are encapsulated in btsnoop records (see RFC 1761).
        Received HCI packets are being put into the queues inside registeredHciRecvQueues and
        passed to the callback functions inside registeredHciCallbacks.
        The thread stops when exit_requested is set to True. It will do that on its own
        if it encounters a fatal error or the stackDumpReceiver reports that the chip crashed.
        """

        log.debug("Receive Thread started.")

        while not self.exit_requested:
            # Little bit ugly: need to re-apply changes to the global context to the thread-copy
            context.log_level = self.log_level

            # Read the record header
            record_hdr = b''
            while(not self.exit_requested and len(record_hdr) < 24):
                try:
                    recv_data = self.s_snoop.recv(24 - len(record_hdr))
                    log.debug("recvThreadFunc: received bt_snoop data " + recv_data.encode('hex'))
                    if len(recv_data) == 0:
                        log.info("recvThreadFunc: bt_snoop socket was closed by remote site. stopping recv thread...")
                        self.exit_requested = True
                        break
                    record_hdr += recv_data
                except socket.timeout:
                    pass # this is ok. just try again without error

            if not record_hdr or len(record_hdr) != 24:
                if not self.exit_requested:
                    log.warn("recvThreadFunc: Cannot recv record_hdr. stopping.")
                    self.exit_requested = True
                break

            if self.write_btsnooplog:
                self.btsnooplog_file.write(record_hdr)
                self.btsnooplog_file.flush()

            orig_len, inc_len, flags, drops, time64 = struct.unpack( ">IIIIq", record_hdr)

            # Read the record data
            record_data = b''
            while(not self.exit_requested and len(record_data) < inc_len):
                try:
                    recv_data = self.s_snoop.recv(inc_len - len(record_data))
                    if len(recv_data) == 0:
                        log.info("recvThreadFunc: bt_snoop socket was closed by remote site. stopping..")
                        self.exit_requested = True
                        break
                    record_data += recv_data
                except socket.timeout:
                    pass # this is ok. just try again without error

            if not record_data or len(record_data) != inc_len:
                if not self.exit_requested:
                    log.warn("recvThreadFunc: Cannot recv data. stopping.")
                    self.exit_requested = True
                break
            
            if self.write_btsnooplog:
                self.btsnooplog_file.write(record_data)
                self.btsnooplog_file.flush()

            try:
                parsed_time = self._parse_time(time64)
            except OverflowError:
                parsed_time = None

            # Put all relevant infos into a tuple. The HCI packet is parsed with the help of hci.py.
            record = (hci.parse_hci_packet(record_data), orig_len, inc_len, flags, drops, parsed_time)

            log.debug("_recvThreadFunc Recv: [" + str(parsed_time) + "] " + str(record[0]))

            # Put the record into all queues of registeredHciRecvQueues if their
            # filter function matches.
            for queue, filter_function in self.registeredHciRecvQueues:
                if filter_function == None or filter_function(record):
                    try:
                        queue.put(record, block=False)
                    except Queue.Full:
                        log.warn("recvThreadFunc: A recv queue is full. dropping packets..")

            # Call all callback functions inside registeredHciCallbacks and pass the
            # record as argument.
            for callback in self.registeredHciCallbacks:
                callback(record)

            # Check if the stackDumpReceiver has noticed that the chip crashed.
            if self.stackDumpReceiver.stack_dump_has_happend:
                # A stack dump has happend!
                log.warn("recvThreadFunc: The controller send a stack dump. stopping..")
                self.exit_requested = True

        log.debug("Receive Thread terminated.")
Example #6
0
    def _recvThreadFunc(self):
        """
        This is the run-function of the recvThread. It receives HCI events from the
        s_snoop socket. The HCI packets are encapsulated in btsnoop records (see RFC 1761).
        Received HCI packets are being put into the queues inside registeredHciRecvQueues and
        passed to the callback functions inside registeredHciCallbacks.
        The thread stops when exit_requested is set to True. It will do that on its own
        if it encounters a fatal error or the stackDumpReceiver reports that the chip crashed.
        """

        log.debug("Receive Thread started.")

        while not self.exit_requested:
            # Little bit ugly: need to re-apply changes to the global context to the thread-copy
            context.log_level = self.log_level

            # Read the record data
            try:
                record_data = self.s_snoop.recv(1024)
            except socket.timeout:
                continue  # this is ok. just try again without error
            except Exception:
                log.critical(
                    "Lost device interface, terminating receive thread...")
                self.exit_requested = True
                continue

            # btsnoop record header data:
            btsnoop_orig_len = len(record_data)
            btsnoop_inc_len = len(record_data)
            btsnoop_flags = 0
            btsnoop_drops = 0
            btsnoop_time = datetime.datetime.now()

            # Put all relevant infos into a tuple. The HCI packet is parsed with the help of hci.py.
            record = (hci.parse_hci_packet(record_data), btsnoop_orig_len,
                      btsnoop_inc_len, btsnoop_flags, btsnoop_drops,
                      btsnoop_time)

            log.debug("_recvThreadFunc Recv: [" + str(btsnoop_time) + "] " +
                      str(record[0]))

            # Write to btsnoop file:
            if self.write_btsnooplog:
                btsnoop_record_hdr = struct.pack(
                    ">IIIIq", btsnoop_orig_len, btsnoop_inc_len, btsnoop_flags,
                    btsnoop_drops, self._btsnoop_pack_time(btsnoop_time))
                with self.btsnooplog_file_lock:
                    self.btsnooplog_file.write(btsnoop_record_hdr)
                    self.btsnooplog_file.write(record_data)
                    self.btsnooplog_file.flush()

            # Put the record into all queues of registeredHciRecvQueues if their
            # filter function matches.
            for queue, filter_function in self.registeredHciRecvQueues:
                if filter_function == None or filter_function(record):
                    try:
                        queue.put(record, block=False)
                    except Queue.Full:
                        log.warn(
                            "recvThreadFunc: A recv queue is full. dropping packets.."
                        )

            # Call all callback functions inside registeredHciCallbacks and pass the
            # record as argument.
            for callback in self.registeredHciCallbacks:
                callback(record)

            # Check if the stackDumpReceiver has noticed that the chip crashed.
            # if self.stackDumpReceiver.stack_dump_has_happend:
            # A stack dump has happend!
            # log.warn("recvThreadFunc: The controller send a stack dump.")
            # self.exit_requested = True

        log.debug("Receive Thread terminated.")