# include  <cassert> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <unistd.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <fcntl.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <errno.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <termios.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "common/swaglog.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "common/gpio.h" 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  "common/util.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "pigeon.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// Termios on macos doesn't define all baud rate constants
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# ifndef B460800 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define   B460800 0010004 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								using  namespace  std : : string_literals ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								extern  ExitHandler  do_exit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								const  std : : string  ack  =  " \xb5 \x62 \x05 \x01 \x02 \x00 " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								const  std : : string  nack  =  " \xb5 \x62 \x05 \x00 \x02 \x00 " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Pigeon  *  Pigeon : : connect ( Panda  *  p ) { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  PandaPigeon  *  pigeon  =  new  PandaPigeon ( ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  pigeon - > connect ( p ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  pigeon ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Pigeon  *  Pigeon : : connect ( const  char  *  tty ) { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  TTYPigeon  *  pigeon  =  new  TTYPigeon ( ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  pigeon - > connect ( tty ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  pigeon ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								bool  Pigeon : : wait_for_ack ( ) { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  std : : string  s ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  while  ( ! do_exit ) { 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    s  + =  receive ( ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( s . find ( ack )  ! =  std : : string : : npos ) { 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      LOGD ( " Received ACK from ublox " ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return  true ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else  if  ( s . find ( nack )  ! =  std : : string : : npos )  { 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      LOGE ( " Received NACK from ublox " ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return  false ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else  if  ( s . size ( )  >  0x1000 )  { 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      LOGE ( " No response from ublox " ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return  false ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    util : : sleep_for ( 1 ) ;  // Allow other threads to be scheduled
  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  false ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								bool  Pigeon : : send_with_ack ( std : : string  cmd ) { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  send ( cmd ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  wait_for_ack ( ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  Pigeon : : init ( )  { 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  for  ( int  i  =  0 ;  i  <  10 ;  i + + ) { 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( do_exit )  return ; 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    LOGW ( " panda GPS start " ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // power off pigeon
  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    set_power ( false ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    util : : sleep_for ( 100 ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // 9600 baud at init
  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    set_baud ( 9600 ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // power on pigeon
  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    set_power ( true ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    util : : sleep_for ( 500 ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // baud rate upping
  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    send ( " \x24 \x50 \x55 \x42 \x58 \x2C \x34 \x31 \x2C \x31 \x2C \x30 \x30 \x30 \x37 \x2C \x30 \x30 \x30 \x33 \x2C \x34 \x36 \x30 \x38 \x30 \x30 \x2C \x30 \x2A \x31 \x35 \x0D \x0A " s ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    util : : sleep_for ( 100 ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // set baud rate to 460800
  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    set_baud ( 460800 ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // init from ubloxd
  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // To generate this data, run selfdrive/locationd/test/ubloxd.py
  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! send_with_ack ( " \xB5 \x62 \x06 \x00 \x14 \x00 \x03 \xFF \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x01 \x00 \x01 \x00 \x00 \x00 \x00 \x00 \x1E \x7F " s ) )  continue ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! send_with_ack ( " \xB5 \x62 \x06 \x00 \x14 \x00 \x00 \xFF \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x19 \x35 " s ) )  continue ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! send_with_ack ( " \xB5 \x62 \x06 \x00 \x14 \x00 \x01 \x00 \x00 \x00 \xC0 \x08 \x00 \x00 \x00 \x08 \x07 \x00 \x01 \x00 \x01 \x00 \x00 \x00 \x00 \x00 \xF4 \x80 " s ) )  continue ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! send_with_ack ( " \xB5 \x62 \x06 \x00 \x14 \x00 \x04 \xFF \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x1D \x85 " s ) )  continue ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! send_with_ack ( " \xB5 \x62 \x06 \x00 \x00 \x00 \x06 \x18 " s ) )  continue ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! send_with_ack ( " \xB5 \x62 \x06 \x00 \x01 \x00 \x01 \x08 \x22 " s ) )  continue ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! send_with_ack ( " \xB5 \x62 \x06 \x00 \x01 \x00 \x03 \x0A \x24 " s ) )  continue ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! send_with_ack ( " \xB5 \x62 \x06 \x08 \x06 \x00 \x64 \x00 \x01 \x00 \x00 \x00 \x79 \x10 " s ) )  continue ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! send_with_ack ( " \xB5 \x62 \x06 \x24 \x24 \x00 \x05 \x00 \x04 \x03 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x5A \x63 " s ) )  continue ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! send_with_ack ( " \xB5 \x62 \x06 \x1E \x14 \x00 \x00 \x00 \x00 \x00 \x01 \x03 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x3C \x37 " s ) )  continue ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! send_with_ack ( " \xB5 \x62 \x06 \x24 \x00 \x00 \x2A \x84 " s ) )  continue ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! send_with_ack ( " \xB5 \x62 \x06 \x23 \x00 \x00 \x29 \x81 " s ) )  continue ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! send_with_ack ( " \xB5 \x62 \x06 \x1E \x00 \x00 \x24 \x72 " s ) )  continue ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! send_with_ack ( " \xB5 \x62 \x06 \x01 \x03 \x00 \x01 \x07 \x01 \x13 \x51 " s ) )  continue ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! send_with_ack ( " \xB5 \x62 \x06 \x01 \x03 \x00 \x02 \x15 \x01 \x22 \x70 " s ) )  continue ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! send_with_ack ( " \xB5 \x62 \x06 \x01 \x03 \x00 \x02 \x13 \x01 \x20 \x6C " s ) )  continue ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! send_with_ack ( " \xB5 \x62 \x06 \x01 \x03 \x00 \x0A \x09 \x01 \x1E \x70 " s ) )  continue ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! send_with_ack ( " \xB5 \x62 \x06 \x01 \x03 \x00 \x0A \x0B \x01 \x20 \x74 " s ) )  continue ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    LOGW ( " panda GPS on " ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return ; 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  } 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  LOGE ( " failed to initialize panda GPS " ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  PandaPigeon : : connect ( Panda  *  p )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  panda  =  p ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  PandaPigeon : : set_baud ( int  baud )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  panda - > usb_write ( 0xe2 ,  1 ,  0 ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  panda - > usb_write ( 0xe4 ,  1 ,  baud / 300 ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  PandaPigeon : : send ( const  std : : string  & s )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  int  len  =  s . length ( ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  char  *  dat  =  s . data ( ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  unsigned  char  a [ 0x20 + 1 ] ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  a [ 0 ]  =  1 ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  for  ( int  i = 0 ;  i < len ;  i + = 0x20 )  { 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  ll  =  std : : min ( 0x20 ,  len - i ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    memcpy ( & a [ 1 ] ,  & dat [ i ] ,  ll ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    panda - > usb_bulk_write ( 2 ,  a ,  ll + 1 ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								std : : string  PandaPigeon : : receive ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  std : : string  r ; 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  r . reserve ( 0x1000  +  0x40 ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  unsigned  char  dat [ 0x40 ] ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  while  ( r . length ( )  <  0x1000 ) { 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  len  =  panda - > usb_read ( 0xe0 ,  1 ,  0 ,  dat ,  sizeof ( dat ) ) ; 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( len  < =  0 )  break ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    r . append ( ( char * ) dat ,  len ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  r ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  PandaPigeon : : set_power ( bool  power )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  panda - > usb_write ( 0xd9 ,  power ,  0 ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								PandaPigeon : : ~ PandaPigeon ( ) { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  handle_tty_issue ( int  err ,  const  char  func [ ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  LOGE_100 ( " tty error %d  \" %s \"  in %s " ,  err ,  strerror ( err ) ,  func ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  TTYPigeon : : connect ( const  char  *  tty )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  pigeon_tty_fd  =  open ( tty ,  O_RDWR ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( pigeon_tty_fd  <  0 ) { 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    handle_tty_issue ( errno ,  __func__ ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    assert ( pigeon_tty_fd  > =  0 ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  int  err  =  tcgetattr ( pigeon_tty_fd ,  & pigeon_tty ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  assert ( err  = =  0 ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // configure tty
  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  pigeon_tty . c_cflag  & =  ~ PARENB ;                                             // disable parity
  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  pigeon_tty . c_cflag  & =  ~ CSTOPB ;                                             // single stop bit
  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  pigeon_tty . c_cflag  | =  CS8 ;                                                 // 8 bits per byte
  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  pigeon_tty . c_cflag  & =  ~ CRTSCTS ;                                            // no RTS/CTS flow control
  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  pigeon_tty . c_cflag  | =  CREAD  |  CLOCAL ;                                      // turn on READ & ignore ctrl lines
  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  pigeon_tty . c_lflag  & =  ~ ICANON ;                                             // disable canonical mode
  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  pigeon_tty . c_lflag  & =  ~ ISIG ;                                               // disable interpretation of INTR, QUIT and SUSP
  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  pigeon_tty . c_iflag  & =  ~ ( IXON  |  IXOFF  |  IXANY ) ;                             // turn off software flow ctrl
  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  pigeon_tty . c_iflag  & =  ~ ( IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL ) ;    // disable any special handling of received bytes
  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  pigeon_tty . c_oflag  & =  ~ OPOST ;                                              // prevent special interpretation of output bytes
  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  pigeon_tty . c_oflag  & =  ~ ONLCR ;                                              // prevent conversion of newline to carriage return/line feed
  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // configure blocking behavior
  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  pigeon_tty . c_cc [ VMIN ]  =  0 ;   // min amount of characters returned
  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  pigeon_tty . c_cc [ VTIME ]  =  0 ;  // max blocking time in s/10 (0=inf)
  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  err  =  tcsetattr ( pigeon_tty_fd ,  TCSANOW ,  & pigeon_tty ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  assert ( err  = =  0 ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  TTYPigeon : : set_baud ( int  baud ) { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  speed_t  baud_const  =  0 ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  switch ( baud ) { 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  case  9600 : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    baud_const  =  B9600 ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    break ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  case  460800 : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    baud_const  =  B460800 ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    break ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  default : 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    assert ( false ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // make sure everything is tx'ed before changing baud
  
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  int  err  =  tcdrain ( pigeon_tty_fd ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  assert ( err  = =  0 ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // change baud
  
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  err  =  tcgetattr ( pigeon_tty_fd ,  & pigeon_tty ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  assert ( err  = =  0 ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  err  =  cfsetspeed ( & pigeon_tty ,  baud_const ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  assert ( err  = =  0 ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  err  =  tcsetattr ( pigeon_tty_fd ,  TCSANOW ,  & pigeon_tty ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  assert ( err  = =  0 ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // flush
  
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  err  =  tcflush ( pigeon_tty_fd ,  TCIOFLUSH ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  assert ( err  = =  0 ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  TTYPigeon : : send ( const  std : : string  & s )  { 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  int  err  =  write ( pigeon_tty_fd ,  s . data ( ) ,  s . length ( ) ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if ( err  <  0 )  {  handle_tty_issue ( err ,  __func__ ) ;  } 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  err  =  tcdrain ( pigeon_tty_fd ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if ( err  <  0 )  {  handle_tty_issue ( err ,  __func__ ) ;  } 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								std : : string  TTYPigeon : : receive ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  std : : string  r ; 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  r . reserve ( 0x1000  +  0x40 ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  char  dat [ 0x40 ] ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  while  ( r . length ( )  <  0x1000 ) { 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  len  =  read ( pigeon_tty_fd ,  dat ,  sizeof ( dat ) ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if ( len  <  0 )  { 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      handle_tty_issue ( len ,  __func__ ) ; 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    }  else  if  ( len  = =  0 ) { 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      break ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else  { 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      r . append ( dat ,  len ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  r ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  TTYPigeon : : set_power ( bool  power ) { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# ifdef QCOM2 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  int  err  =  0 ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  err  + =  gpio_init ( GPIO_UBLOX_RST_N ,  true ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  err  + =  gpio_init ( GPIO_UBLOX_SAFEBOOT_N ,  true ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  err  + =  gpio_init ( GPIO_UBLOX_PWR_EN ,  true ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  err  + =  gpio_set ( GPIO_UBLOX_RST_N ,  power ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  err  + =  gpio_set ( GPIO_UBLOX_SAFEBOOT_N ,  power ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  err  + =  gpio_set ( GPIO_UBLOX_PWR_EN ,  power ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  assert ( err  = =  0 ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								TTYPigeon : : ~ TTYPigeon ( ) { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  close ( pigeon_tty_fd ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}