# include  "tools/cabana/canmessages.h" 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "tools/cabana/dbcmanager.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								CANMessages  * can  =  nullptr ; 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								CANMessages : : CANMessages ( QObject  * parent )  :  QObject ( parent )  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  can  =  this ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  QObject : : connect ( this ,  & CANMessages : : received ,  this ,  & CANMessages : : process ,  Qt : : QueuedConnection ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  QObject : : connect ( & settings ,  & Settings : : changed ,  this ,  & CANMessages : : settingChanged ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								CANMessages : : ~ CANMessages ( )  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  replay - > stop ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  bool  event_filter ( const  Event  * e ,  void  * opaque )  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  CANMessages  * c  =  ( CANMessages  * ) opaque ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  c - > eventFilter ( e ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  CANMessages : : loadRoute ( const  QString  & route ,  const  QString  & data_dir ,  uint32_t  replay_flags )  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  replay  =  new  Replay ( route ,  { " can " ,  " roadEncodeIdx " ,  " wideRoadEncodeIdx " ,  " carParams " } ,  { } ,  nullptr ,  replay_flags ,  data_dir ,  this ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  replay - > setSegmentCacheLimit ( settings . cached_segment_limit ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  replay - > installEventFilter ( event_filter ,  this ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  QObject : : connect ( replay ,  & Replay : : seekedTo ,  this ,  & CANMessages : : seekedTo ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  QObject : : connect ( replay ,  & Replay : : segmentsMerged ,  this ,  & CANMessages : : eventsMerged ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  QObject : : connect ( replay ,  & Replay : : streamStarted ,  this ,  & CANMessages : : streamStarted ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( replay - > load ( ) )  { 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  auto  & segments  =  replay - > route ( ) - > segments ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( std : : none_of ( segments . begin ( ) ,  segments . end ( ) ,  [ ] ( auto  & s )  {  return  s . second . rlog . length ( )  >  0 ;  } ) )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      qWarning ( )  < <  " no rlogs in route "  < <  route ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  false ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    replay - > start ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  true ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  false ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  CANMessages : : process ( QHash < QString ,  CanData >  * messages )  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  for  ( auto  it  =  messages - > begin ( ) ;  it  ! =  messages - > end ( ) ;  + + it )  { 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    can_msgs [ it . key ( ) ]  =  it . value ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  emit  updated ( ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  emit  msgsReceived ( messages ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  delete  messages ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  processing  =  false ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								bool  CANMessages : : eventFilter ( const  Event  * event )  { 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  static  std : : unique_ptr  new_msgs  =  std : : make_unique < QHash < QString ,  CanData > > ( ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  static  double  prev_update_ts  =  0 ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( event - > which  = =  cereal : : Event : : Which : : CAN )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    double  current_sec  =  replay - > currentSeconds ( ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( counters_begin_sec  = =  0  | |  counters_begin_sec  > =  current_sec )  { 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      new_msgs - > clear ( ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      counters . clear ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      counters_begin_sec  =  current_sec ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  can_events  =  event - > event . getCan ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( const  auto  & c  :  can_events )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      QString  id  =  QString ( " %1:%2 " ) . arg ( c . getSrc ( ) ) . arg ( c . getAddress ( ) ,  1 ,  16 ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      CanData  & data  =  ( * new_msgs ) [ id ] ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      data . ts  =  current_sec ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      data . dat  =  QByteArray ( ( char  * ) c . getDat ( ) . begin ( ) ,  c . getDat ( ) . size ( ) ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      data . count  =  + + counters [ id ] ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      if  ( double  delta  =  ( current_sec  -  counters_begin_sec ) ;  delta  >  0 )  { 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								        data . freq  =  data . count  /  delta ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    double  ts  =  millis_since_boot ( ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ( ts  -  prev_update_ts )  >  ( 1000.0  /  settings . fps )  & &  ! processing  & &  ! new_msgs - > isEmpty ( ) )  { 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      // delay posting CAN message if UI thread is busy
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      processing  =  true ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      prev_update_ts  =  ts ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      // use pointer to avoid data copy in queued connection.
   
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      emit  received ( new_msgs . release ( ) ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      new_msgs . reset ( new  QHash < QString ,  CanData > ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      new_msgs - > reserve ( 100 ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  true ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  CANMessages : : seekTo ( double  ts )  { 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  replay - > seekTo ( std : : max ( double ( 0 ) ,  ts ) ,  false ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  counters_begin_sec  =  0 ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  emit  updated ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  CANMessages : : settingChanged ( )  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  replay - > setSegmentCacheLimit ( settings . cached_segment_limit ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}