docs: def process_packet(self, pkt):
          """Parse the packet and call callback if one of the filters matches."""
  
          # check if this could be a valid packet before parsing
          # this reduces the CPU load significantly
          if not ( \
              ((self.mode & ScannerMode.MODE_IBEACON) and (pkt[19:23] == b"\x4c\x00\x02\x15")) or \
              ((self.mode & ScannerMode.MODE_EDDYSTONE) and (pkt[19:21] == b"\xaa\xfe")) or \
              ((self.mode & ScannerMode.MODE_ESTIMOTE) and (pkt[19:21] == b"\x9a\xfe"))):
              return
  
          bt_addr = bt_addr_to_string(pkt[7:13])
          rssi = bin_to_int(pkt[-1])
          # strip bluetooth address and parse packet
          packet = parse_packet(pkt[14:-1])
  
          # return if packet was not an beacon advertisement
          if not packet:
              return
  
          # we need to remeber which eddystone beacon has which bt address
          # because the TLM and URL frames do not contain the namespace and instance
          self.save_bt_addr(packet, bt_addr)
          # properties holds the identifying information for a beacon
          # e.g. instance and namespace for eddystone; uuid, major, minor for iBeacon
          properties = self.get_properties(packet, bt_addr)
  
          if self.device_filter is None and self.packet_filter is None:
              # no filters selected
              self.callback(bt_addr, rssi, packet, properties)
  
          elif self.device_filter is None:
              # filter by packet type
              if is_one_of(packet, self.packet_filter):
                  self.callback(bt_addr, rssi, packet, properties)
          else:
              # filter by device and packet type
              if self.packet_filter and not is_one_of(packet, self.packet_filter):
                  # return if packet filter does not match
                  return
  
              # iterate over filters and call .matches() on each
              for filtr in self.device_filter:
                  if isinstance(filtr, BtAddrFilter):
                      if filtr.matches({'bt_addr':bt_addr}):
                          self.callback(bt_addr, rssi, packet, properties)
                          return
  
                  elif filtr.matches(properties):
                      self.callback(bt_addr, rssi, packet, properties)
                      return