text: import os
  import time
  from common.basedir import BASEDIR
  from common.realtime import sec_since_boot
  from common.fingerprints import eliminate_incompatible_cars, all_known_cars
  from selfdrive.swaglog import cloudlog
  import selfdrive.messaging as messaging
  
  def load_interfaces(x):
    ret = {}
    for interface in x:
      try:
        imp = __import__('selfdrive.car.%s.interface' % interface, fromlist=['CarInterface']).CarInterface
      except ImportError:
        imp = None
      for car in x[interface]:
        ret[car] = imp
    return ret
  
  
  def _get_interface_names():
    # read all the folders in selfdrive/car and return a dict where:
    # - keys are all the car names that which we have an interface for
    # - values are lists of spefic car models for a given car
    interface_names = {}
    for car_folder in [x[0] for x in os.walk(BASEDIR + '/selfdrive/car')]:
      try:
        car_name = car_folder.split('/')[-1]
        model_names = __import__('selfdrive.car.%s.values' % car_name, fromlist=['CAR']).CAR
        model_names = [getattr(model_names, c) for c in model_names.__dict__.keys() if not c.startswith("__")]
        interface_names[car_name] = model_names
      except (ImportError, IOError):
        pass
  
    return interface_names
  
  
  # imports from directory selfdrive/car/<name>/
  interfaces = load_interfaces(_get_interface_names())
  
  
  # BOUNTY: every added fingerprint in selfdrive/car/*/values.py is a $100 coupon code on shop.comma.ai
  # **** for use live only ****
  def fingerprint(logcan, timeout):
    if os.getenv("SIMULATOR2") is not None:
      return ("simulator2", None)
    elif os.getenv("SIMULATOR") is not None:
      return ("simulator", None)
  
    cloudlog.warning("waiting for fingerprint...")
    candidate_cars = all_known_cars()
    finger = {}
    st = None
    st_passive = sec_since_boot()  # only relevant when passive
    can_seen = False
    while 1:
      for a in messaging.drain_sock(logcan):
        for can in a.can:
          can_seen = True
          # ignore everything not on bus 0 and with more than 11 bits,
          # which are ussually sporadic and hard to include in fingerprints
          if can.src == 0 and can.address < 0x800:
            finger[can.address] = len(can.dat)
            candidate_cars = eliminate_incompatible_cars(can, candidate_cars)
  
      if st is None and can_seen:
        st = sec_since_boot()          # start time
      ts = sec_since_boot()
      # if we only have one car choice and the time_fingerprint since we got our first
      # message has elapsed, exit. Toyota needs higher time_fingerprint, since DSU does not
      # broadcast immediately
      if len(candidate_cars) == 1 and st is not None:
        # TODO: better way to decide to wait more if Toyota
        time_fingerprint = 1.0 if ("TOYOTA" in candidate_cars[0] or "LEXUS" in candidate_cars[0]) else 0.1
        if (ts-st) > time_fingerprint:
          break
  
      # bail if no cars left or we've been waiting too long
      elif len(candidate_cars) == 0 or (timeout and (ts - st_passive) > timeout):
        return None, finger
  
      time.sleep(0.01)
  
    cloudlog.warning("fingerprinted %s", candidate_cars[0])
    return (candidate_cars[0], finger)
  
  
  def get_car(logcan, sendcan=None, passive=True):
    # TODO: timeout only useful for replays so controlsd can start before unlogger
    timeout = 2. if passive else None
    candidate, fingerprints = fingerprint(logcan, timeout)
  
    candidate = "CHRYSLER PACIFICA HYBRID 2018"
    fingerprints={68: 8, 257: 5, 258: 8, 264: 8, 268: 8, 270: 8, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 291: 8, 292: 8, 294: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 368: 8, 376: 3, 384: 8, 388: 4, 448: 6, 456: 4, 464: 8, 469: 8, 480: 8, 500: 8, 501: 8, 512: 8, 514: 8, 520: 8, 528: 8, 532: 8, 544: 8, 557: 8, 559: 8, 560: 4, 564: 8, 571: 3, 579: 8, 584: 8, 608: 8, 624: 8, 625: 8, 632: 8, 639: 8, 653: 8, 654: 8, 655: 8, 660: 8, 669: 3, 671: 8, 672: 8, 680: 8, 701: 8, 704: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 736: 8, 737: 8, 746: 5, 760: 8, 764: 8, 766: 8, 770: 8, 773: 8, 779: 8, 782: 8, 784: 8, 792: 8, 799: 8, 800: 8, 804: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 832: 8, 838: 2, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 878: 8, 882: 8, 897: 8, 908: 8, 924: 8, 926: 3, 929: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 958: 8, 959: 8, 969: 4, 974: 5, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1082: 8, 1083: 8, 1098: 8, 1100: 8}
  
  
    if candidate is None:
      cloudlog.warning("car doesn't match any fingerprints: %r", fingerprints)
      if passive:
        candidate = "mock"
      else:
        return None, None
  
    interface_cls = interfaces[candidate]
  
    if interface_cls is None:
      cloudlog.warning("car matched %s, but interface wasn't available or failed to import" % candidate)
      return None, None
  
    params = interface_cls.get_params(candidate, fingerprints)
  
    return interface_cls(params, sendcan), params
  