@ -3,7 +3,8 @@ import unittest 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					from  cereal  import  car  
					 
					 
					 
					from  cereal  import  car  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					from  selfdrive . car . hyundai . values  import  CAMERA_SCC_CAR ,  CANFD_CAR ,  CAN_GEARS ,  CAR ,  CHECKSUM ,  FW_QUERY_CONFIG ,  \ 
					 
					 
					 
					from  selfdrive . car . hyundai . values  import  CAMERA_SCC_CAR ,  CANFD_CAR ,  CAN_GEARS ,  CAR ,  CHECKSUM ,  FW_QUERY_CONFIG ,  \ 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					                                         FW_VERSIONS ,  LEGACY_SAFETY_MODE_CAR ,  PART_NUMBER_FW_PATTERN   
					 
					 
					 
					                                         FW_VERSIONS ,  LEGACY_SAFETY_MODE_CAR ,  PART_NUMBER_FW_PATTERN ,  PLATFORM_CODE_ECUS ,  \  
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					                                         get_platform_codes   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					Ecu  =  car . CarParams . Ecu  
					 
					 
					 
					Ecu  =  car . CarParams . Ecu  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					ECU_NAME  =  { v :  k  for  k ,  v  in  Ecu . schema . enumerants . items ( ) }  
					 
					 
					 
					ECU_NAME  =  { v :  k  for  k ,  v  in  Ecu . schema . enumerants . items ( ) }  
				
			 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
							 
						
					 
					 
					@ -25,21 +26,24 @@ class TestHyundaiFingerprint(unittest.TestCase): 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					      ecu_strings  =  " ,  " . join ( [ f ' Ecu. { ECU_NAME [ ecu ] } '  for  ecu  in  ecus_not_in_whitelist ] )   
					 
					 
					 
					      ecu_strings  =  " ,  " . join ( [ f ' Ecu. { ECU_NAME [ ecu ] } '  for  ecu  in  ecus_not_in_whitelist ] )   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					      self . assertEqual ( len ( ecus_not_in_whitelist ) ,  0 ,  f ' { car_model } : Car model has ECUs not in auxiliary request whitelists:  { ecu_strings } ' )   
					 
					 
					 
					      self . assertEqual ( len ( ecus_not_in_whitelist ) ,  0 ,  f ' { car_model } : Car model has ECUs not in auxiliary request whitelists:  { ecu_strings } ' )   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  # Tests for platform codes, part numbers, and FW dates which Hyundai will use to fuzzy   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  # fingerprint in the absence of full FW matches:   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  def  test_platform_code_ecus_available ( self ) :   
					 
					 
					 
					  def  test_platform_code_ecus_available ( self ) :   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					    # TODO: add queries for these non-CAN FD cars to get EPS   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    no_eps_platforms  =  CANFD_CAR  |  { CAR . KIA_SORENTO ,  CAR . KIA_OPTIMA_G4 ,  CAR . KIA_OPTIMA_G4_FL ,   
					 
					 
					 
					    no_eps_platforms  =  CANFD_CAR  |  { CAR . KIA_SORENTO ,  CAR . KIA_OPTIMA_G4 ,  CAR . KIA_OPTIMA_G4_FL ,   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					                                    CAR . SONATA_LF ,  CAR . TUCSON ,  CAR . GENESIS_G90 ,  CAR . GENESIS_G80 }   
					 
					 
					 
					                                    CAR . SONATA_LF ,  CAR . TUCSON ,  CAR . GENESIS_G90 ,  CAR . GENESIS_G80 }   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    # Asserts ECU keys essential for fuzzy fingerprinting are available on all platforms   
					 
					 
					 
					    # Asserts ECU keys essential for fuzzy fingerprinting are available on all platforms   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    for  car_model ,  ecus  in  FW_VERSIONS . items ( ) :   
					 
					 
					 
					    for  car_model ,  ecus  in  FW_VERSIONS . items ( ) :   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					      with  self . subTest ( car_model = car_model ) :   
					 
					 
					 
					      with  self . subTest ( car_model = car_model ) :   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					        for  fuzzy_ecu  in  FW_QUERY_CONFIG . platform_code_ecus :   
					 
					 
					 
					        for  platform_code_ecu  in  PLATFORM_CODE_ECUS :   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					          if  fuzzy _ecu  in  ( Ecu . fwdRadar ,  Ecu . eps )  and  car_model  ==  CAR . HYUNDAI_GENESIS :   
					 
					 
					 
					          if  platform_code _ecu  in  ( Ecu . fwdRadar ,  Ecu . eps )  and  car_model  ==  CAR . HYUNDAI_GENESIS :   
				
			 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					            continue   
					 
					 
					 
					            continue   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					          if  fuzzy _ecu  ==  Ecu . eps  and  car_model  in  no_eps_platforms :   
					 
					 
					 
					          if  platform_code _ecu  ==  Ecu . eps  and  car_model  in  no_eps_platforms :   
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					            continue   
					 
					 
					 
					            continue   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					          self . assertIn ( fuzzy _ecu,  [ e [ 0 ]  for  e  in  ecus ] )   
					 
					 
					 
					          self . assertIn ( platform_code _ecu,  [ e [ 0 ]  for  e  in  ecus ] )   
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  def  test_fw_part_number ( self ) :   
					 
					 
					 
					  def  test_fw_part_numbers  ( self ) :   
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					    # Hyundai places the ECU part number in their FW versions, assert all parsable   
					 
					 
					 
					    # Hyundai places the ECU part number in their FW versions, assert all parsable   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    # Some examples of valid formats: '56310-L0010', '56310L0010', '56310/M6300'   
					 
					 
					 
					    # Some examples of valid formats: '56310-L0010', '56310L0010', '56310/M6300'   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    for  car_model ,  ecus  in  FW_VERSIONS . items ( ) :   
					 
					 
					 
					    for  car_model ,  ecus  in  FW_VERSIONS . items ( ) :   
				
			 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
							 
						
					 
					 
					@ -48,42 +52,50 @@ class TestHyundaiFingerprint(unittest.TestCase): 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					          raise  unittest . SkipTest ( " No part numbers for car model " )   
					 
					 
					 
					          raise  unittest . SkipTest ( " No part numbers for car model " )   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					        for  ecu ,  fws  in  ecus . items ( ) :   
					 
					 
					 
					        for  ecu ,  fws  in  ecus . items ( ) :   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					          if  ecu [ 0 ]  not  in  FW_QUERY_CONFIG . platform_code_ecus :   
					 
					 
					 
					          if  ecu [ 0 ]  not  in  PLATFORM_CODE_ECUS :   
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					            continue   
					 
					 
					 
					            continue   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					          for  fw  in  fws :   
					 
					 
					 
					          for  fw  in  fws :   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					            match  =  PART_NUMBER_FW_PATTERN . search ( fw )   
					 
					 
					 
					            match  =  PART_NUMBER_FW_PATTERN . search ( fw )   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					            self . assertIsNotNone ( match ,  fw )   
					 
					 
					 
					            self . assertIsNotNone ( match ,  fw )   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  def  test_fuzzy_f w_dates ( self ) :   
					 
					 
					 
					  def  test_fw_dates ( self ) :   
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					    # Some newer platforms have date codes in a different format we don't yet parse,   
					 
					 
					 
					    # Some newer platforms have date codes in a different format we don't yet parse,   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    # for now assert date format is consistent for all FW across each platform   
					 
					 
					 
					    # for now assert date format is consistent for all FW across each platform   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    for  car_model ,  ecus  in  FW_VERSIONS . items ( ) :   
					 
					 
					 
					    for  car_model ,  ecus  in  FW_VERSIONS . items ( ) :   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					      with  self . subTest ( car_model = car_model ) :   
					 
					 
					 
					      with  self . subTest ( car_model = car_model ) :   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					        for  ecu ,  fws  in  ecus . items ( ) :   
					 
					 
					 
					        for  ecu ,  fws  in  ecus . items ( ) :   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					          if  ecu [ 0 ]  not  in  FW_QUERY_CONFIG . platform_code_ecus :   
					 
					 
					 
					          if  ecu [ 0 ]  not  in  PLATFORM_CODE_ECUS :   
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					            continue   
					 
					 
					 
					            continue   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					          codes  =  set ( )   
					 
					 
					 
					          codes  =  set ( )   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					          for  fw  in  fws :   
					 
					 
					 
					          for  fw  in  fws :   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					            codes  | =  FW_QUERY_CONFIG . fuzzy_ get_platform_codes( [ fw ] )   
					 
					 
					 
					            codes  | =  get_platform_codes ( [ fw ] )   
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					          # Either no dates should be parsed or all dates should be parsed   
					 
					 
					 
					          # Either no dates should be parsed or all dates should be parsed   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					          self . assertEqual ( len ( { b ' - '  in  code  for  code  in  codes } ) ,  1 )   
					 
					 
					 
					          self . assertEqual ( len ( { b ' - '  in  code  for  code  in  codes } ) ,  1 )   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  def  test_fuzzy_platform_codes ( self ) :   
					 
					 
					 
					  def  test_platform_codes_all_parsable ( self ) :   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					    # Asserts basic platform code parsing behavior   
					 
					 
					 
					    # Assert every supported ECU FW version returns one platform code   
				
			 
			
				
				
			
		
	
		
		
			
				
					
					 
					 
					 
					    codes  =  FW_QUERY_CONFIG . fuzzy_get_platform_codes ( [ b ' \xf1 \x00 DH LKAS 1.1 -150210 ' ] )   
					 
					 
					 
					    for  fw_by_addr  in  FW_VERSIONS . values ( ) :   
				
			 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					      for  addr ,  fws  in  fw_by_addr . items ( ) :   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					        if  addr [ 0 ]  in  PLATFORM_CODE_ECUS :   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					          for  f  in  fws :   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					            self . assertEqual ( 1 ,  len ( get_platform_codes ( [ f ] ) ) ,  f " Unable to parse FW:  { f } " )   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  def  test_platform_codes_spot_check ( self ) :   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					    # Asserts basic platform code parsing behavior for a few cases   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					    codes  =  get_platform_codes ( [ b ' \xf1 \x00 DH LKAS 1.1 -150210 ' ] )   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    self . assertEqual ( codes ,  { b " DH-1502 " } )   
					 
					 
					 
					    self . assertEqual ( codes ,  { b " DH-1502 " } )   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    # Some cameras and all radars do not have dates   
					 
					 
					 
					    # Some cameras and all radars do not have dates   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    codes  =  FW_QUERY_CONFIG . fuzzy_get_platform_codes ( [ b ' \xf1 \x00 AEhe SCC H-CUP      1.01 1.01 96400-G2000          ' ] )   
					 
					 
					 
					    codes  =  get_platform_codes ( [ b ' \xf1 \x00 AEhe SCC H-CUP      1.01 1.01 96400-G2000          ' ] )   
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					    self . assertEqual ( codes ,  { b " AEhe " } )   
					 
					 
					 
					    self . assertEqual ( codes ,  { b " AEhe " } )   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    codes  =  FW_QUERY_CONFIG . fuzzy_get_platform_codes ( [ b ' \xf1 \x00 CV1_ RDR -----      1.00 1.01 99110-CV000          ' ] )   
					 
					 
					 
					    codes  =  get_platform_codes ( [ b ' \xf1 \x00 CV1_ RDR -----      1.00 1.01 99110-CV000          ' ] )   
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					    self . assertEqual ( codes ,  { b " CV1 " } )   
					 
					 
					 
					    self . assertEqual ( codes ,  { b " CV1 " } )   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    codes  =  FW_QUERY_CONFIG . fuzzy_ get_platform_codes( [   
					 
					 
					 
					    codes  =  get_platform_codes ( [   
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					      b ' \xf1 \x00 DH LKAS 1.1 -150210 ' ,   
					 
					 
					 
					      b ' \xf1 \x00 DH LKAS 1.1 -150210 ' ,   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					      b ' \xf1 \x00 AEhe SCC H-CUP      1.01 1.01 96400-G2000          ' ,   
					 
					 
					 
					      b ' \xf1 \x00 AEhe SCC H-CUP      1.01 1.01 96400-G2000          ' ,   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					      b ' \xf1 \x00 CV1_ RDR -----      1.00 1.01 99110-CV000          ' ,   
					 
					 
					 
					      b ' \xf1 \x00 CV1_ RDR -----      1.00 1.01 99110-CV000          ' ,   
				
			 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
							 
						
					 
					 
					@ -91,7 +103,7 @@ class TestHyundaiFingerprint(unittest.TestCase): 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    self . assertEqual ( codes ,  { b " DH-1502 " ,  b " AEhe " ,  b " CV1 " } )   
					 
					 
					 
					    self . assertEqual ( codes ,  { b " DH-1502 " ,  b " AEhe " ,  b " CV1 " } )   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    # Returned platform codes must inclusively contain start/end dates   
					 
					 
					 
					    # Returned platform codes must inclusively contain start/end dates   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    codes  =  FW_QUERY_CONFIG . fuzzy_ get_platform_codes( [   
					 
					 
					 
					    codes  =  get_platform_codes ( [   
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					      b ' \xf1 \x00 LX2 MFC  AT USA LHD 1.00 1.07 99211-S8100 220222 ' ,   
					 
					 
					 
					      b ' \xf1 \x00 LX2 MFC  AT USA LHD 1.00 1.07 99211-S8100 220222 ' ,   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					      b ' \xf1 \x00 LX2 MFC  AT USA LHD 1.00 1.08 99211-S8100 211103 ' ,   
					 
					 
					 
					      b ' \xf1 \x00 LX2 MFC  AT USA LHD 1.00 1.08 99211-S8100 211103 ' ,   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					      b ' \xf1 \x00 ON  MFC  AT USA LHD 1.00 1.01 99211-S9100 190405 ' ,   
					 
					 
					 
					      b ' \xf1 \x00 ON  MFC  AT USA LHD 1.00 1.01 99211-S9100 190405 ' ,