import os
from common . basedir import BASEDIR
def get_attr_from_cars ( attr , result = dict , combine_brands = True ) :
# read all the folders in selfdrive/car and return a dict where:
# - keys are all the car models
# - values are attr values from all car folders
result = result ( )
for car_folder in [ x [ 0 ] for x in os . walk ( BASEDIR + ' /selfdrive/car ' ) ] :
try :
car_name = car_folder . split ( ' / ' ) [ - 1 ]
values = __import__ ( ' selfdrive.car. %s .values ' % car_name , fromlist = [ attr ] )
if hasattr ( values , attr ) :
attr_values = getattr ( values , attr )
else :
continue
if isinstance ( attr_values , dict ) :
for f , v in attr_values . items ( ) :
if combine_brands :
result [ f ] = v
else :
if car_name not in result :
result [ car_name ] = { }
result [ car_name ] [ f ] = v
elif isinstance ( attr_values , list ) :
result + = attr_values
except ( ImportError , IOError ) :
pass
return result
FW_VERSIONS = get_attr_from_cars ( ' FW_VERSIONS ' )
_FINGERPRINTS = get_attr_from_cars ( ' FINGERPRINTS ' )
_DEBUG_ADDRESS = { 1880 : 8 } # reserved for debug purposes
def is_valid_for_fingerprint ( msg , car_fingerprint ) :
adr = msg . address
# ignore addresses that are more than 11 bits
return ( adr in car_fingerprint and car_fingerprint [ adr ] == len ( msg . dat ) ) or adr > = 0x800
def eliminate_incompatible_cars ( msg , candidate_cars ) :
""" Removes cars that could not have sent msg.
Inputs :
msg : A cereal / log CanData message from the car .
candidate_cars : A list of cars to consider .
Returns :
A list containing the subset of candidate_cars that could have sent msg .
"""
compatible_cars = [ ]
for car_name in candidate_cars :
car_fingerprints = _FINGERPRINTS [ car_name ]
for fingerprint in car_fingerprints :
fingerprint . update ( _DEBUG_ADDRESS ) # add alien debug address
if is_valid_for_fingerprint ( msg , fingerprint ) :
compatible_cars . append ( car_name )
break
return compatible_cars
def all_known_cars ( ) :
""" Returns a list of all known car strings. """
return list ( { * FW_VERSIONS . keys ( ) , * _FINGERPRINTS . keys ( ) } )
def all_legacy_fingerprint_cars ( ) :
""" Returns a list of all known car strings, FPv1 only. """
return list ( _FINGERPRINTS . keys ( ) )