#!/usr/bin/env python3 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  struct 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								import  traceback 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								from  typing  import  Any 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								from  collections  import  defaultdict 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								from  tqdm  import  tqdm 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								import  panda . python . uds  as  uds 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								from  cereal  import  car 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								from  selfdrive . car . fingerprints  import  FW_VERSIONS ,  get_attr_from_cars 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								from  selfdrive . car . isotp_parallel_query  import  IsoTpParallelQuery 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								from  selfdrive . car . toyota . values  import  CAR  as  TOYOTA 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								from  selfdrive . swaglog  import  cloudlog 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Ecu  =  car . CarParams . Ecu 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								def  p16 ( val ) : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  struct . pack ( " !H " ,  val ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TESTER_PRESENT_REQUEST  =  bytes ( [ uds . SERVICE_TYPE . TESTER_PRESENT ,  0x0 ] ) 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TESTER_PRESENT_RESPONSE  =  bytes ( [ uds . SERVICE_TYPE . TESTER_PRESENT  +  0x40 ,  0x0 ] ) 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								SHORT_TESTER_PRESENT_REQUEST  =  bytes ( [ uds . SERVICE_TYPE . TESTER_PRESENT ] ) 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								SHORT_TESTER_PRESENT_RESPONSE  =  bytes ( [ uds . SERVICE_TYPE . TESTER_PRESENT  +  0x40 ] ) 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								DEFAULT_DIAGNOSTIC_REQUEST  =  bytes ( [ uds . SERVICE_TYPE . DIAGNOSTIC_SESSION_CONTROL , 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                    uds . SESSION_TYPE . DEFAULT ] ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								DEFAULT_DIAGNOSTIC_RESPONSE  =  bytes ( [ uds . SERVICE_TYPE . DIAGNOSTIC_SESSION_CONTROL  +  0x40 , 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                    uds . SESSION_TYPE . DEFAULT ,  0x0 ,  0x32 ,  0x1 ,  0xf4 ] ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								EXTENDED_DIAGNOSTIC_REQUEST  =  bytes ( [ uds . SERVICE_TYPE . DIAGNOSTIC_SESSION_CONTROL , 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                     uds . SESSION_TYPE . EXTENDED_DIAGNOSTIC ] ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								EXTENDED_DIAGNOSTIC_RESPONSE  =  bytes ( [ uds . SERVICE_TYPE . DIAGNOSTIC_SESSION_CONTROL  +  0x40 , 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                      uds . SESSION_TYPE . EXTENDED_DIAGNOSTIC ,  0x0 ,  0x32 ,  0x1 ,  0xf4 ] ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								UDS_VERSION_REQUEST  =  bytes ( [ uds . SERVICE_TYPE . READ_DATA_BY_IDENTIFIER ] )  +  \
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  p16 ( uds . DATA_IDENTIFIER_TYPE . APPLICATION_SOFTWARE_IDENTIFICATION ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								UDS_VERSION_RESPONSE  =  bytes ( [ uds . SERVICE_TYPE . READ_DATA_BY_IDENTIFIER  +  0x40 ] )  +  \
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  p16 ( uds . DATA_IDENTIFIER_TYPE . APPLICATION_SOFTWARE_IDENTIFICATION ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								HYUNDAI_VERSION_REQUEST_LONG  =  bytes ( [ uds . SERVICE_TYPE . READ_DATA_BY_IDENTIFIER ] )  +  \
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  p16 ( 0xf100 )   # Long description 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								HYUNDAI_VERSION_REQUEST_MULTI  =  bytes ( [ uds . SERVICE_TYPE . READ_DATA_BY_IDENTIFIER ] )  +  \
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  p16 ( uds . DATA_IDENTIFIER_TYPE . VEHICLE_MANUFACTURER_SPARE_PART_NUMBER )  +  \
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  p16 ( uds . DATA_IDENTIFIER_TYPE . APPLICATION_SOFTWARE_IDENTIFICATION )  +  \
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  p16 ( 0xf100 ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								HYUNDAI_VERSION_RESPONSE  =  bytes ( [ uds . SERVICE_TYPE . READ_DATA_BY_IDENTIFIER  +  0x40 ] ) 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TOYOTA_VERSION_REQUEST  =  b ' \x1a \x88 \x01 ' 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TOYOTA_VERSION_RESPONSE  =  b ' \x5a \x88 \x01 ' 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								VOLKSWAGEN_VERSION_REQUEST_MULTI  =  bytes ( [ uds . SERVICE_TYPE . READ_DATA_BY_IDENTIFIER ] )  +  \
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  p16 ( uds . DATA_IDENTIFIER_TYPE . VEHICLE_MANUFACTURER_SPARE_PART_NUMBER )  +  \
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  p16 ( uds . DATA_IDENTIFIER_TYPE . VEHICLE_MANUFACTURER_ECU_SOFTWARE_VERSION_NUMBER )  +  \
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  p16 ( uds . DATA_IDENTIFIER_TYPE . APPLICATION_DATA_IDENTIFICATION ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								VOLKSWAGEN_VERSION_RESPONSE  =  bytes ( [ uds . SERVICE_TYPE . READ_DATA_BY_IDENTIFIER  +  0x40 ] ) 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								OBD_VERSION_REQUEST  =  b ' \x09 \x04 ' 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								OBD_VERSION_RESPONSE  =  b ' \x49 \x04 ' 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								DEFAULT_RX_OFFSET  =  0x8 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								VOLKSWAGEN_RX_OFFSET  =  0x6a 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								MAZDA_VERSION_REQUEST  =  bytes ( [ uds . SERVICE_TYPE . READ_DATA_BY_IDENTIFIER ] )  +  \
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  p16 ( uds . DATA_IDENTIFIER_TYPE . VEHICLE_MANUFACTURER_ECU_SOFTWARE_NUMBER ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								MAZDA_VERSION_RESPONSE  =   bytes ( [ uds . SERVICE_TYPE . READ_DATA_BY_IDENTIFIER  +  0x40 ] )  +  \
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  p16 ( uds . DATA_IDENTIFIER_TYPE . VEHICLE_MANUFACTURER_ECU_SOFTWARE_NUMBER ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								NISSAN_DIAGNOSTIC_REQUEST_KWP  =  bytes ( [ uds . SERVICE_TYPE . DIAGNOSTIC_SESSION_CONTROL ,  0xc0 ] ) 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								NISSAN_DIAGNOSTIC_RESPONSE_KWP  =  bytes ( [ uds . SERVICE_TYPE . DIAGNOSTIC_SESSION_CONTROL  +  0x40 ,  0xc0 ] ) 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								NISSAN_VERSION_REQUEST_KWP  =  b ' \x21 \x83 ' 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								NISSAN_VERSION_RESPONSE_KWP  =  b ' \x61 \x83 ' 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								NISSAN_VERSION_REQUEST_STANDARD  =  bytes ( [ uds . SERVICE_TYPE . READ_DATA_BY_IDENTIFIER ] )  +  \
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  p16 ( uds . DATA_IDENTIFIER_TYPE . VEHICLE_MANUFACTURER_ECU_SOFTWARE_NUMBER ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								NISSAN_VERSION_RESPONSE_STANDARD  =   bytes ( [ uds . SERVICE_TYPE . READ_DATA_BY_IDENTIFIER  +  0x40 ] )  +  \
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  p16 ( uds . DATA_IDENTIFIER_TYPE . VEHICLE_MANUFACTURER_ECU_SOFTWARE_NUMBER ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								NISSAN_RX_OFFSET  =  0x20 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								SUBARU_VERSION_REQUEST  =  bytes ( [ uds . SERVICE_TYPE . READ_DATA_BY_IDENTIFIER ] )  +  \
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  p16 ( uds . DATA_IDENTIFIER_TYPE . APPLICATION_DATA_IDENTIFICATION ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								SUBARU_VERSION_RESPONSE  =  bytes ( [ uds . SERVICE_TYPE . READ_DATA_BY_IDENTIFIER  +  0x40 ] )  +  \
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  p16 ( uds . DATA_IDENTIFIER_TYPE . APPLICATION_DATA_IDENTIFICATION ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								# brand, request, response, response offset 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								REQUESTS  =  [ 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Subaru 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ( 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    " subaru " , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [ TESTER_PRESENT_REQUEST ,  SUBARU_VERSION_REQUEST ] , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [ TESTER_PRESENT_RESPONSE ,  SUBARU_VERSION_RESPONSE ] , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    DEFAULT_RX_OFFSET , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ) , 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Hyundai 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  ( 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    " hyundai " , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [ HYUNDAI_VERSION_REQUEST_LONG ] , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [ HYUNDAI_VERSION_RESPONSE ] , 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    DEFAULT_RX_OFFSET , 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ( 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    " hyundai " , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [ HYUNDAI_VERSION_REQUEST_MULTI ] , 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    [ HYUNDAI_VERSION_RESPONSE ] , 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    DEFAULT_RX_OFFSET , 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Honda 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ( 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    " honda " , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [ UDS_VERSION_REQUEST ] , 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    [ UDS_VERSION_RESPONSE ] , 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    DEFAULT_RX_OFFSET , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Toyota 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ( 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    " toyota " , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [ SHORT_TESTER_PRESENT_REQUEST ,  TOYOTA_VERSION_REQUEST ] , 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    [ SHORT_TESTER_PRESENT_RESPONSE ,  TOYOTA_VERSION_RESPONSE ] , 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    DEFAULT_RX_OFFSET , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ( 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    " toyota " , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [ SHORT_TESTER_PRESENT_REQUEST ,  OBD_VERSION_REQUEST ] , 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    [ SHORT_TESTER_PRESENT_RESPONSE ,  OBD_VERSION_RESPONSE ] , 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    DEFAULT_RX_OFFSET , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ( 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    " toyota " , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [ TESTER_PRESENT_REQUEST ,  DEFAULT_DIAGNOSTIC_REQUEST ,  EXTENDED_DIAGNOSTIC_REQUEST ,  UDS_VERSION_REQUEST ] , 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    [ TESTER_PRESENT_RESPONSE ,  DEFAULT_DIAGNOSTIC_RESPONSE ,  EXTENDED_DIAGNOSTIC_RESPONSE ,  UDS_VERSION_RESPONSE ] , 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    DEFAULT_RX_OFFSET , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Volkswagen 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ( 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    " volkswagen " , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [ VOLKSWAGEN_VERSION_REQUEST_MULTI ] , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [ VOLKSWAGEN_VERSION_RESPONSE ] , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    VOLKSWAGEN_RX_OFFSET , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ( 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    " volkswagen " , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [ VOLKSWAGEN_VERSION_REQUEST_MULTI ] , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [ VOLKSWAGEN_VERSION_RESPONSE ] , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    DEFAULT_RX_OFFSET , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ) , 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Mazda 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ( 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    " mazda " , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [ MAZDA_VERSION_REQUEST ] , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [ MAZDA_VERSION_RESPONSE ] , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    DEFAULT_RX_OFFSET , 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Nissan 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ( 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    " nissan " , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [ NISSAN_DIAGNOSTIC_REQUEST_KWP ,  NISSAN_VERSION_REQUEST_KWP ] , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [ NISSAN_DIAGNOSTIC_RESPONSE_KWP ,  NISSAN_VERSION_RESPONSE_KWP ] , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    DEFAULT_RX_OFFSET , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ( 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    " nissan " , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [ NISSAN_DIAGNOSTIC_REQUEST_KWP ,  NISSAN_VERSION_REQUEST_KWP ] , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [ NISSAN_DIAGNOSTIC_RESPONSE_KWP ,  NISSAN_VERSION_RESPONSE_KWP ] , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    NISSAN_RX_OFFSET , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ( 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    " nissan " , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [ NISSAN_VERSION_REQUEST_STANDARD ] , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [ NISSAN_VERSION_RESPONSE_STANDARD ] , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    NISSAN_RX_OFFSET , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								] 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								def  chunks ( l ,  n = 128 ) : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  for  i  in  range ( 0 ,  len ( l ) ,  n ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    yield  l [ i : i  +  n ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								def  build_fw_dict ( fw_versions ) : 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  fw_versions_dict  =  { } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  for  fw  in  fw_versions : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    addr  =  fw . address 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    sub_addr  =  fw . subAddress  if  fw . subAddress  !=  0  else  None 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    fw_versions_dict [ ( addr ,  sub_addr ) ]  =  fw . fwVersion 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  return  fw_versions_dict 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								def  match_fw_to_car_fuzzy ( fw_versions_dict ,  log = True ,  exclude = None ) : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  """ Do a fuzzy FW match. This function will return a match, and the number of firmware version 
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  that  were  matched  uniquely  to  that  specific  car .  If  multiple  ECUs  uniquely  match  to  different  cars 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  the  match  is  rejected . """ 
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # These ECUs are known to be shared between models (EPS only between hybrid/ICE version) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Getting this exactly right isn't crucial, but excluding camera and radar makes it almost 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # impossible to get 3 matching versions, even if two models with shared parts are released at the same 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # time and only one is in our database. 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  exclude_types  =  [ Ecu . fwdCamera ,  Ecu . fwdRadar ,  Ecu . eps ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Build lookup table from (addr, subaddr, fw) to list of candidate cars 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  all_fw_versions  =  defaultdict ( list ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  for  candidate ,  fw_by_addr  in  FW_VERSIONS . items ( ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  candidate  ==  exclude : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      continue 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  addr ,  fws  in  fw_by_addr . items ( ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  addr [ 0 ]  in  exclude_types : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        continue 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      for  f  in  fws : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        all_fw_versions [ ( addr [ 1 ] ,  addr [ 2 ] ,  f ) ] . append ( candidate ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  match_count  =  0 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  candidate  =  None 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  for  addr ,  version  in  fw_versions_dict . items ( ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # All cars that have this FW response on the specified address 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    candidates  =  all_fw_versions [ ( addr [ 0 ] ,  addr [ 1 ] ,  version ) ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  len ( candidates )  ==  1 : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      match_count  + =  1 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  candidate  is  None : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        candidate  =  candidates [ 0 ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      # We uniquely matched two different cars. No fuzzy match possible 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      elif  candidate  !=  candidates [ 0 ] : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  set ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  match_count  > =  2 : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  log : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      cloudlog . error ( f " Fingerprinted  { candidate }  using fuzzy match.  { match_count }  matching ECUs " ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { candidate } 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  else : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  set ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								def  match_fw_to_car_exact ( fw_versions_dict ) : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  """ Do an exact FW match. Returns all cars that match the given 
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  FW  versions  for  a  list  of  " essential "  ECUs .  If  an  ECU  is  not  considered 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  essential  the  FW  version  can  be  missing  to  get  a  fingerprint ,  but  if  it ' s present it 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  needs  to  match  the  database . """ 
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  invalid  =  [ ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  candidates  =  FW_VERSIONS 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  for  candidate ,  fws  in  candidates . items ( ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ecu ,  expected_versions  in  fws . items ( ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ecu_type  =  ecu [ 0 ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      addr  =  ecu [ 1 : ] 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      found_version  =  fw_versions_dict . get ( addr ,  None ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      ESSENTIAL_ECUS  =  [ Ecu . engine ,  Ecu . eps ,  Ecu . esp ,  Ecu . fwdRadar ,  Ecu . fwdCamera ,  Ecu . vsa ] 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      if  ecu_type  ==  Ecu . esp  and  candidate  in  ( TOYOTA . RAV4 ,  TOYOTA . COROLLA ,  TOYOTA . HIGHLANDER ,  TOYOTA . SIENNA ,  TOYOTA . LEXUS_IS )  and  found_version  is  None : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								        continue 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      # On some Toyota models, the engine can show on two different addresses 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      if  ecu_type  ==  Ecu . engine  and  candidate  in  ( TOYOTA . CAMRY ,  TOYOTA . COROLLA_TSS2 ,  TOYOTA . CHR ,  TOYOTA . LEXUS_IS )  and  found_version  is  None : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								        continue 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      # Ignore non essential ecus 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      if  ecu_type  not  in  ESSENTIAL_ECUS  and  found_version  is  None : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        continue 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  found_version  not  in  expected_versions : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        invalid . append ( candidate ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  set ( candidates . keys ( ) )  -  set ( invalid ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								def  match_fw_to_car ( fw_versions ,  allow_fuzzy = True ) : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  fw_versions_dict  =  build_fw_dict ( fw_versions ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  matches  =  match_fw_to_car_exact ( fw_versions_dict ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  exact_match  =  True 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  allow_fuzzy  and  len ( matches )  ==  0 : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    matches  =  match_fw_to_car_fuzzy ( fw_versions_dict ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # Fuzzy match found 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  len ( matches )  ==  1 : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      exact_match  =  False 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  exact_match ,  matches 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								def  get_fw_versions ( logcan ,  sendcan ,  bus ,  extra = None ,  timeout = 0.1 ,  debug = False ,  progress = False ) : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ecu_types  =  { } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Extract ECU addresses to query from fingerprints 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # ECUs using a subadress need be queried one by one, the rest can be done in parallel 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  addrs  =  [ ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  parallel_addrs  =  [ ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  versions  =  get_attr_from_cars ( ' FW_VERSIONS ' ,  combine_brands = False ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  extra  is  not  None : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    versions . update ( extra ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  for  brand ,  brand_versions  in  versions . items ( ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  c  in  brand_versions . values ( ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      for  ecu_type ,  addr ,  sub_addr  in  c . keys ( ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        a  =  ( brand ,  addr ,  sub_addr ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  a  not  in  ecu_types : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          ecu_types [ ( addr ,  sub_addr ) ]  =  ecu_type 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  sub_addr  is  None : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          if  a  not  in  parallel_addrs : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            parallel_addrs . append ( a ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          if  [ a ]  not  in  addrs : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            addrs . append ( [ a ] ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  addrs . insert ( 0 ,  parallel_addrs ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  fw_versions  =  { } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  for  i ,  addr  in  enumerate ( tqdm ( addrs ,  disable = not  progress ) ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  addr_chunk  in  chunks ( addr ) : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      for  brand ,  request ,  response ,  response_offset  in  REQUESTS : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        try : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								          addrs  =  [ ( a ,  s )  for  ( b ,  a ,  s )  in  addr_chunk  if  b  in  ( brand ,  ' any ' ) ] 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								          if  addrs : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								            query  =  IsoTpParallelQuery ( sendcan ,  logcan ,  bus ,  addrs ,  request ,  response ,  response_offset ,  debug = debug ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								            t  =  2  *  timeout  if  i  ==  0  else  timeout 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            fw_versions . update ( query . get_data ( t ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        except  Exception : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          cloudlog . warning ( f " FW query exception:  { traceback . format_exc ( ) } " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Build capnp list to put into CarParams 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  car_fw  =  [ ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  for  addr ,  version  in  fw_versions . items ( ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    f  =  car . CarParams . CarFw . new_message ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    f . ecu  =  ecu_types [ addr ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    f . fwVersion  =  version 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    f . address  =  addr [ 0 ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  addr [ 1 ]  is  not  None : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      f . subAddress  =  addr [ 1 ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    car_fw . append ( f ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  return  car_fw 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								if  __name__  ==  " __main__ " : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  import  time 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  import  argparse 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  import  cereal . messaging  as  messaging 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  from  selfdrive . car . vin  import  get_vin 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  parser  =  argparse . ArgumentParser ( description = ' Get firmware version of ECUs ' ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  parser . add_argument ( ' --scan ' ,  action = ' store_true ' ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  parser . add_argument ( ' --debug ' ,  action = ' store_true ' ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  args  =  parser . parse_args ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  logcan  =  messaging . sub_sock ( ' can ' ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  sendcan  =  messaging . pub_sock ( ' sendcan ' ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  extra :  Any  =  None 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  args . scan : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    extra  =  { } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # Honda 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  i  in  range ( 256 ) : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      extra [ ( Ecu . unknown ,  0x18da00f1  +  ( i  <<  8 ) ,  None ) ]  =  [ ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      extra [ ( Ecu . unknown ,  0x700  +  i ,  None ) ]  =  [ ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      extra [ ( Ecu . unknown ,  0x750 ,  i ) ]  =  [ ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    extra  =  { " any " :  { " debug " :  extra } } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  time . sleep ( 1. ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  t  =  time . time ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  print ( " Getting vin... " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  addr ,  vin  =  get_vin ( logcan ,  sendcan ,  1 ,  retry = 10 ,  debug = args . debug ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  print ( f " VIN:  { vin } " ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  print ( f " Getting VIN took  { time . time ( )  -  t : .3f }  s " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  print ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  t  =  time . time ( ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  fw_vers  =  get_fw_versions ( logcan ,  sendcan ,  1 ,  extra = extra ,  debug = args . debug ,  progress = True ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  _ ,  candidates  =  match_fw_to_car ( fw_vers ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  print ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  print ( " Found FW versions " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  print ( " { " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  for  version  in  fw_vers : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    subaddr  =  None  if  version . subAddress  ==  0  else  hex ( version . subAddress ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print ( f "   (Ecu. { version . ecu } ,  { hex ( version . address ) } ,  { subaddr } ): [ { version . fwVersion } ] " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  print ( " } " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  print ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  print ( " Possible matches: " ,  candidates ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  print ( f " Getting fw took  { time . time ( )  -  t : .3f }  s " )