# include  <stdio.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <stdlib.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <string.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <signal.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <unistd.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <sched.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <sys/time.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <sys/cdefs.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <sys/types.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <sys/time.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <assert.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <math.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <ctime> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <chrono> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <map> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <vector> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <zmq.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <capnp/serialize.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "cereal/gen/cpp/log.capnp.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "common/params.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "common/swaglog.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "common/timing.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "ublox_msg.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								volatile  int  do_exit  =  0 ;  // Flag for process exit on signal
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  set_do_exit ( int  sig )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  do_exit  =  1 ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								using  namespace  ublox ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  ubloxd_main ( poll_ubloxraw_msg_func  poll_func ,  send_gps_event_func  send_func )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  LOGW ( " starting ubloxd " ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  signal ( SIGINT ,  ( sighandler_t )  set_do_exit ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  signal ( SIGTERM ,  ( sighandler_t )  set_do_exit ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  UbloxMsgParser  parser ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  void  * context  =  zmq_ctx_new ( ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  void  * gpsLocationExternal  =  zmq_socket ( context ,  ZMQ_PUB ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  zmq_bind ( gpsLocationExternal ,  " tcp://*:8032 " ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  void  * ubloxGnss  =  zmq_socket ( context ,  ZMQ_PUB ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  zmq_bind ( ubloxGnss ,  " tcp://*:8033 " ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // ubloxRaw = 8042
  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  void  * subscriber  =  zmq_socket ( context ,  ZMQ_SUB ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  zmq_setsockopt ( subscriber ,  ZMQ_SUBSCRIBE ,  " " ,  0 ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  zmq_connect ( subscriber ,  " tcp://127.0.0.1:8042 " ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  while  ( ! do_exit )  { 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    zmq_msg_t  msg ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    zmq_msg_init ( & msg ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  err  =  poll_func ( gpsLocationExternal ,  ubloxGnss ,  subscriber ,  & msg ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if ( err  <  0 )  { 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      LOGE_100 ( " zmq_poll error %s in %s " ,  strerror ( errno  ) ,  __FUNCTION__ ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      break ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else  if ( err  = =  0 )  { 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      continue ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // format for board, make copy due to alignment issues, will be freed on out of scope
  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    auto  amsg  =  kj : : heapArray < capnp : : word > ( ( zmq_msg_size ( & msg )  /  sizeof ( capnp : : word ) )  +  1 ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    memcpy ( amsg . begin ( ) ,  zmq_msg_data ( & msg ) ,  zmq_msg_size ( & msg ) ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    capnp : : FlatArrayMessageReader  cmsg ( amsg ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    cereal : : Event : : Reader  event  =  cmsg . getRoot < cereal : : Event > ( ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  uint8_t  * data  =  event . getUbloxRaw ( ) . begin ( ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    size_t  len  =  event . getUbloxRaw ( ) . size ( ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    size_t  bytes_consumed  =  0 ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    while ( bytes_consumed  <  len  & &  ! do_exit )  { 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      size_t  bytes_consumed_this_time  =  0U ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if ( parser . add_data ( data  +  bytes_consumed ,  ( uint32_t ) ( len  -  bytes_consumed ) ,  bytes_consumed_this_time ) )  { 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // New message available
  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if ( parser . msg_class ( )  = =  CLASS_NAV )  { 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          if ( parser . msg_id ( )  = =  MSG_NAV_PVT )  { 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            //LOGD("MSG_NAV_PVT");
  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            auto  words  =  parser . gen_solution ( ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if ( words . size ( )  >  0 )  { 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								              auto  bytes  =  words . asBytes ( ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								              send_func ( parser . msg_class ( ) ,  parser . msg_id ( ) ,  gpsLocationExternal ,  bytes . begin ( ) ,  bytes . size ( ) ,  0 ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          }  else 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            LOGW ( " Unknown nav msg id: 0x%02X " ,  parser . msg_id ( ) ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        }  else  if ( parser . msg_class ( )  = =  CLASS_RXM )  { 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          if ( parser . msg_id ( )  = =  MSG_RXM_RAW )  { 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            //LOGD("MSG_RXM_RAW");
  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            auto  words  =  parser . gen_raw ( ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if ( words . size ( )  >  0 )  { 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								              auto  bytes  =  words . asBytes ( ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								              send_func ( parser . msg_class ( ) ,  parser . msg_id ( ) ,  ubloxGnss ,  bytes . begin ( ) ,  bytes . size ( ) ,  0 ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          }  else  if ( parser . msg_id ( )  = =  MSG_RXM_SFRBX )  { 
 
							 
						 
					
						
							
								
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            //LOGD("MSG_RXM_SFRBX");
  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            auto  words  =  parser . gen_nav_data ( ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if ( words . size ( )  >  0 )  { 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								              auto  bytes  =  words . asBytes ( ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								              send_func ( parser . msg_class ( ) ,  parser . msg_id ( ) ,  ubloxGnss ,  bytes . begin ( ) ,  bytes . size ( ) ,  0 ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          }  else 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            LOGW ( " Unknown rxm msg id: 0x%02X " ,  parser . msg_id ( ) ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        }  else 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          LOGW ( " Unknown msg class: 0x%02X " ,  parser . msg_class ( ) ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        parser . reset ( ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      bytes_consumed  + =  bytes_consumed_this_time ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    zmq_msg_close ( & msg ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  zmq_close ( subscriber ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  zmq_close ( gpsLocationExternal ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  zmq_close ( ubloxGnss ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  zmq_ctx_destroy ( context ) ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  0 ; 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}