@ -56,7 +56,7 @@ struct __attribute__((packed)) timestamp_t { 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					} ;  
					 
					 
					 
					} ;  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					libusb_context  * ctx  =  NULL ;  
					 
					 
					 
					libusb_context  * ctx  =  NULL ;  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					libusb_device_handle  * dev_handle ;  
					 
					 
					 
					libusb_device_handle  * dev_handle  =  NULL  ;  
				
			 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 
					 
					 
					pthread_mutex_t  usb_lock ;  
					 
					 
					 
					pthread_mutex_t  usb_lock ;  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					bool  spoofing_started  =  false ;  
					 
					 
					 
					bool  spoofing_started  =  false ;  
				
			 
			
		
	
	
		
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
					 
					@ -260,6 +260,7 @@ fail: 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  return  false ;   
					 
					 
					 
					  return  false ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					}  
					 
					 
					 
					}  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					// must be called before threads or with mutex
  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					void  usb_retry_connect ( )  {  
					 
					 
					 
					void  usb_retry_connect ( )  {  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  LOG ( " attempting to connect " ) ;   
					 
					 
					 
					  LOG ( " attempting to connect " ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  while  ( ! usb_connect ( ) )  {  usleep ( 100 * 1000 ) ;  }   
					 
					 
					 
					  while  ( ! usb_connect ( ) )  {  usleep ( 100 * 1000 ) ;  }   
				
			 
			
		
	
	
		
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
					 
					@ -358,16 +359,33 @@ void can_health(PubSocket *publisher) { 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    uint8_t  power_save_enabled ;   
					 
					 
					 
					    uint8_t  power_save_enabled ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  }  health ;   
					 
					 
					 
					  }  health ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  // create message
   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  capnp : : MallocMessageBuilder  msg ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  cereal : : Event : : Builder  event  =  msg . initRoot < cereal : : Event > ( ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  event . setLogMonoTime ( nanos_since_boot ( ) ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  auto  healthData  =  event . initHealth ( ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  bool  received  =  false ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  // recv from board
   
					 
					 
					 
					  // recv from board
   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  if  ( dev_handle  ! =  NULL )  {   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    pthread_mutex_lock ( & usb_lock ) ;   
					 
					 
					 
					    pthread_mutex_lock ( & usb_lock ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  do  {   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    cnt  =  libusb_control_transfer ( dev_handle ,  0xc0 ,  0xd2 ,  0 ,  0 ,  ( unsigned  char * ) & health ,  sizeof ( health ) ,  TIMEOUT ) ;   
					 
					 
					 
					    cnt  =  libusb_control_transfer ( dev_handle ,  0xc0 ,  0xd2 ,  0 ,  0 ,  ( unsigned  char * ) & health ,  sizeof ( health ) ,  TIMEOUT ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    if  ( cnt  ! =  sizeof ( health ) )  {   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					      handle_usb_issue ( cnt ,  __func__ ) ;   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    }   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  }  while ( cnt  ! =  sizeof ( health ) ) ;   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    pthread_mutex_unlock ( & usb_lock ) ;   
					 
					 
					 
					    pthread_mutex_unlock ( & usb_lock ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					    received  =  ( cnt  = =  sizeof ( health ) ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  }   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  // No panda connected, send empty health packet
   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  if  ( ! received ) {   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					    healthData . setHwType ( cereal : : HealthData : : HwType : : UNKNOWN ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					    auto  words  =  capnp : : messageToFlatArray ( msg ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					    auto  bytes  =  words . asBytes ( ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					    publisher - > send ( ( char * ) bytes . begin ( ) ,  bytes . size ( ) ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					    return ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  }   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  if  ( spoofing_started )  {   
					 
					 
					 
					  if  ( spoofing_started )  {   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					    health . ignition_line  =  1 ;   
					 
					 
					 
					    health . ignition_line  =  1 ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  }   
					 
					 
					 
					  }   
				
			 
			
		
	
	
		
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
					 
					@ -476,12 +494,6 @@ void can_health(PubSocket *publisher) { 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  ignition_last  =  ignition ;   
					 
					 
					 
					  ignition_last  =  ignition ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  // create message
   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  capnp : : MallocMessageBuilder  msg ;   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  cereal : : Event : : Builder  event  =  msg . initRoot < cereal : : Event > ( ) ;   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  event . setLogMonoTime ( nanos_since_boot ( ) ) ;   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  auto  healthData  =  event . initHealth ( ) ;   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  // set fields
   
					 
					 
					 
					  // set fields
   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  healthData . setUptime ( health . uptime ) ;   
					 
					 
					 
					  healthData . setUptime ( health . uptime ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  healthData . setVoltage ( health . voltage ) ;   
					 
					 
					 
					  healthData . setVoltage ( health . voltage ) ;   
				
			 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
							 
						
					 
					 
					@ -507,11 +519,9 @@ void can_health(PubSocket *publisher) { 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  auto  bytes  =  words . asBytes ( ) ;   
					 
					 
					 
					  auto  bytes  =  words . asBytes ( ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  publisher - > send ( ( char * ) bytes . begin ( ) ,  bytes . size ( ) ) ;   
					 
					 
					 
					  publisher - > send ( ( char * ) bytes . begin ( ) ,  bytes . size ( ) ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  pthread_mutex_lock ( & usb_lock ) ;   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  // send heartbeat back to panda
   
					 
					 
					 
					  // send heartbeat back to panda
   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  pthread_mutex_lock ( & usb_lock ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  libusb_control_transfer ( dev_handle ,  0x40 ,  0xf3 ,  1 ,  0 ,  NULL ,  0 ,  TIMEOUT ) ;   
					 
					 
					 
					  libusb_control_transfer ( dev_handle ,  0x40 ,  0xf3 ,  1 ,  0 ,  NULL ,  0 ,  TIMEOUT ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  pthread_mutex_unlock ( & usb_lock ) ;   
					 
					 
					 
					  pthread_mutex_unlock ( & usb_lock ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					}  
					 
					 
					 
					}  
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
	
		
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
					 
					@ -905,16 +915,17 @@ int main() { 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  assert ( err  = =  0 ) ;   
					 
					 
					 
					  assert ( err  = =  0 ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  libusb_set_debug ( ctx ,  3 ) ;   
					 
					 
					 
					  libusb_set_debug ( ctx ,  3 ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  // connect to the board
   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  usb_retry_connect ( ) ;   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  // create threads
   
					 
					 
					 
					 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  pthread_t  can_health_thread_handle ;   
					 
					 
					 
					  pthread_t  can_health_thread_handle ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  err  =  pthread_create ( & can_health_thread_handle ,  NULL ,   
					 
					 
					 
					  err  =  pthread_create ( & can_health_thread_handle ,  NULL ,   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					                       can_health_thread ,  NULL ) ;   
					 
					 
					 
					                       can_health_thread ,  NULL ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  assert ( err  = =  0 ) ;   
					 
					 
					 
					  assert ( err  = =  0 ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					
 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  // connect to the board
   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  pthread_mutex_lock ( & usb_lock ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  usb_retry_connect ( ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  pthread_mutex_unlock ( & usb_lock ) ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					
 
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					 
					 
					 
					 
					  // create threads
   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  pthread_t  can_send_thread_handle ;   
					 
					 
					 
					  pthread_t  can_send_thread_handle ;   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					  err  =  pthread_create ( & can_send_thread_handle ,  NULL ,   
					 
					 
					 
					  err  =  pthread_create ( & can_send_thread_handle ,  NULL ,   
				
			 
			
		
	
		
		
			
				
					
					 
					 
					 
					                       can_send_thread ,  NULL ) ;   
					 
					 
					 
					                       can_send_thread ,  NULL ) ;