DEBUG  =  False 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								def  msg ( x ) : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  DEBUG : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print  " S: " , x . encode ( " hex " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  len ( x )  < =  7 : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ret  =  chr ( len ( x ) )  +  x 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  else : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    assert  False 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  ret . ljust ( 8 ,  " \x00 " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								kmsgs  =  [ ] 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								def  recv ( panda ,  cnt ,  addr ,  nbus ) : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  global  kmsgs 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ret  =  [ ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  while  len ( ret )  <  cnt : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    kmsgs  + =  panda . can_recv ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    nmsgs  =  [ ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ids ,  ts ,  dat ,  bus  in  kmsgs : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ids  ==  addr  and  bus  ==  nbus  and  len ( ret )  <  cnt : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ret . append ( dat ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      else : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        # leave around 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        nmsgs . append ( ( ids ,  ts ,  dat ,  bus ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    kmsgs  =  nmsgs [ - 256 : ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  map ( str ,  ret ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								def  isotp_recv_subaddr ( panda ,  addr ,  bus ,  sendaddr ,  subaddr ) : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  msg  =  recv ( panda ,  1 ,  addr ,  bus ) [ 0 ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # TODO: handle other subaddr also communicating  
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  assert  ord ( msg [ 0 ] )  ==  subaddr 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ord ( msg [ 1 ] ) & 0xf0  ==  0x10 : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # first 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    tlen  =  ( ( ord ( msg [ 1 ] )  &  0xf )  <<  8 )  |  ord ( msg [ 2 ] ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    dat  =  msg [ 3 : ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # 0 block size? 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    CONTINUE  =  chr ( subaddr )  +  " \x30 "  +  " \x00 " * 6 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    panda . can_send ( sendaddr ,  CONTINUE ,  bus ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    idx  =  1 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  mm  in  recv ( panda ,  ( tlen - len ( dat )  +  5 ) / 6 ,  addr ,  bus ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      assert  ord ( mm [ 0 ] )  ==  subaddr 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      assert  ord ( mm [ 1 ] )  ==  ( 0x20  |  ( idx & 0xF ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      dat  + =  mm [ 2 : ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      idx  + =  1 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  elif  ord ( msg [ 1 ] ) & 0xf0  ==  0x00 : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # single 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    tlen  =  ord ( msg [ 1 ] )  &  0xf 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    dat  =  msg [ 2 : ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  else : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print  msg . encode ( " hex " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    assert  False 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  dat [ 0 : tlen ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# **** import below this line **** 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								def  isotp_send ( panda ,  x ,  addr ,  bus = 0 ,  recvaddr = None ,  subaddr = None ) : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  recvaddr  is  None : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    recvaddr  =  addr + 8 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  len ( x )  < =  7  and  subaddr  is  None : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    panda . can_send ( addr ,  msg ( x ) ,  bus ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  elif  len ( x )  < =  6  and  subaddr  is  not  None : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    panda . can_send ( addr ,  chr ( subaddr ) + msg ( x ) [ 0 : 7 ] ,  bus ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  else : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  subaddr : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ss  =  chr ( subaddr )  +  chr ( 0x10  +  ( len ( x ) >> 8 ) )  +  chr ( len ( x ) & 0xFF )  +  x [ 0 : 5 ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      x  =  x [ 5 : ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ss  =  chr ( 0x10  +  ( len ( x ) >> 8 ) )  +  chr ( len ( x ) & 0xFF )  +  x [ 0 : 6 ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      x  =  x [ 6 : ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    idx  =  1 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    sends  =  [ ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    while  len ( x )  >  0 : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  subaddr : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        sends . append ( ( ( chr ( subaddr )  +  chr ( 0x20  +  ( idx & 0xF ) )  +  x [ 0 : 6 ] ) . ljust ( 8 ,  " \x00 " ) ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        x  =  x [ 6 : ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      else : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        sends . append ( ( ( chr ( 0x20  +  ( idx & 0xF ) )  +  x [ 0 : 7 ] ) . ljust ( 8 ,  " \x00 " ) ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        x  =  x [ 7 : ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      idx  + =  1 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # actually send 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    panda . can_send ( addr ,  ss ,  bus ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    rr  =  recv ( panda ,  1 ,  recvaddr ,  bus ) [ 0 ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  rr . find ( " \x30 \x01 " )  !=  - 1 : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      for  s  in  sends [ : - 1 ] : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        panda . can_send ( addr ,  s ,  0 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        rr  =  recv ( panda ,  1 ,  recvaddr ,  bus ) [ 0 ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      panda . can_send ( addr ,  sends [ - 1 ] ,  0 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      panda . can_send_many ( [ ( addr ,  None ,  s ,  0 )  for  s  in  sends ] ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								def  isotp_recv ( panda ,  addr ,  bus = 0 ,  sendaddr = None ,  subaddr = None ) : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  sendaddr  is  None : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    sendaddr  =  addr - 8 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  subaddr  is  not  None : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    dat  =  isotp_recv_subaddr ( panda ,  addr ,  bus ,  sendaddr ,  subaddr ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  else : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    msg  =  recv ( panda ,  1 ,  addr ,  bus ) [ 0 ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ord ( msg [ 0 ] ) & 0xf0  ==  0x10 : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      # first 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      tlen  =  ( ( ord ( msg [ 0 ] )  &  0xf )  <<  8 )  |  ord ( msg [ 1 ] ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      dat  =  msg [ 2 : ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      # 0 block size? 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      CONTINUE  =  " \x30 "  +  " \x00 " * 7 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      panda . can_send ( sendaddr ,  CONTINUE ,  bus ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      idx  =  1 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      for  mm  in  recv ( panda ,  ( tlen - len ( dat )  +  6 ) / 7 ,  addr ,  bus ) : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								        assert  ord ( mm [ 0 ] )  ==  ( 0x20  |  ( idx & 0xF ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dat  + =  mm [ 1 : ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        idx  + =  1 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    elif  ord ( msg [ 0 ] ) & 0xf0  ==  0x00 : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      # single 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      tlen  =  ord ( msg [ 0 ] )  &  0xf 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      dat  =  msg [ 1 : ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      assert  False 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    dat  =  dat [ 0 : tlen ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  DEBUG : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print  " R: " , dat . encode ( " hex " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  dat