#!/usr/bin/env python3 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  os 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  random 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  argparse 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  datetime  as  dt 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  subprocess  as  sp 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								from  typing  import  Tuple 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								from  laika . downloader  import  download_nav 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								from  laika . gps_time  import  GPSTime 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								from  laika . helpers  import  ConstellationId 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								cache_dir  =  ' /tmp/gpstest/ ' 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								def  download_rinex ( ) : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # TODO: check if there is a better way to get the full brdc file for LimeGPS 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  gps_time  =  GPSTime . from_datetime ( dt . datetime . utcnow ( ) ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  utc_time  =  dt . datetime . utcnow ( ) # - dt.timedelta(1) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  gps_time  =  GPSTime . from_datetime ( dt . datetime ( utc_time . year ,  utc_time . month ,  utc_time . day ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  download_nav ( gps_time ,  cache_dir ,  ConstellationId . GPS ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								def  get_coords ( lat ,  lon ,  s1 ,  s2 ,  o1 = 0 ,  o2 = 0 )  - >  Tuple [ int ,  int ] : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  lat_add  =  random . random ( ) * s1  +  o1 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  lon_add  =  random . random ( ) * s2  +  o2 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  lat  =  ( ( lat  +  lat_add  +  90 )  %  180 )  -  90 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  lon  =  ( ( lon  +  lon_add  +  180 )  %  360 )  -  180 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  round ( lat ,  5 ) ,  round ( lon ,  5 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								def  get_continuous_coords ( lat ,  lon )  - >  Tuple [ int ,  int ] : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # continuously move around the world 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  get_coords ( lat ,  lon ,  0.01 ,  0.01 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								def  get_random_coords ( lat ,  lon )  - >  Tuple [ int ,  int ] : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # jump around the world 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  get_coords ( lat ,  lon ,  20 ,  20 ,  10 ,  20 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								def  run_limeSDR_loop ( lat ,  lon ,  alt ,  contin_sim ,  rinex_file ,  timeout ) : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  while  True : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    try : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      # TODO: add starttime setting and altitude 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      # -t 2023/01/15,00:00:00 -T 2023/01/15,00:00:00 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      # this needs to match the date of the navigation file 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      print ( f " starting LimeGPS, Location:  { lat }   { lon }   { alt } " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      cmd  =  [ " LimeGPS/LimeGPS " ,  " -e " ,  rinex_file ,  " -l " ,  f " { lat } , { lon } , { alt } " ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      print ( f " CMD:  { cmd } " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      sp . check_output ( cmd ,  stderr = sp . PIPE ,  timeout = timeout ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    except  KeyboardInterrupt : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      print ( " stopping LimeGPS " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    except  sp . TimeoutExpired : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      print ( " LimeGPS timeout reached! " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    except  Exception  as  e : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      out_stderr  =  e . stderr . decode ( ' utf-8 ' ) # pylint:disable=no-member 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  " Device is busy. "  in  out_stderr : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        print ( " GPS simulation is already running, Device is busy! " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      print ( f " LimeGPS crashed:  { str ( e ) } " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      print ( f " stderr: \n { e . stderr . decode ( ' utf-8 ' ) } " ) # pylint:disable=no-member 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      return 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  contin_sim : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      lat ,  lon  =  get_continuous_coords ( lat ,  lon ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      lat ,  lon  =  get_random_coords ( lat ,  lon ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								def  run_hackRF_loop ( lat ,  lon ,  rinex_file ,  timeout ) : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  timeout  is  not  None : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print ( " no jump mode for hackrf! " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  try : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print ( f " starting gps-sdr-sim, Location:  { lat } , { lon } " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # create 30second file and replay with hackrf endless 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    cmd  =  [ " gps-sdr-sim/gps-sdr-sim " ,  " -e " ,  rinex_file ,  " -l " ,  f " { lat } , { lon } ,-200 " ,  " -d " ,  " 30 " ] 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    sp . check_output ( cmd ,  stderr = sp . PIPE ,  timeout = timeout ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # created in current working directory 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  except  Exception : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print ( " Failed to generate gpssim.bin " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  try : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print ( " starting hackrf_transfer " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # create 30second file and replay with hackrf endless 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    cmd  =  [ " hackrf/host/hackrf-tools/src/hackrf_transfer " ,  " -t " ,  " gpssim.bin " , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								           " -f " ,  " 1575420000 " ,  " -s " ,  " 2600000 " ,  " -a " ,  " 1 " ,  " -R " ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    sp . check_output ( cmd ,  stderr = sp . PIPE ,  timeout = timeout ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  except  KeyboardInterrupt : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print ( " stopping hackrf_transfer " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  except  Exception  as  e : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print ( f " hackrf_transfer crashed: { str ( e ) } " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								def  main ( lat ,  lon ,  alt ,  jump_sim ,  contin_sim ,  hackrf_mode ) : 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  hackrf_mode : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  not  os . path . exists ( ' hackrf ' ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      print ( " hackrf not found run  ' setup_hackrf.sh '  first " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  not  os . path . exists ( ' gps-sdr-sim ' ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      print ( " gps-sdr-sim not found run  ' setup_hackrf.sh '  first " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    output  =  sp . check_output ( [ " hackrf/host/hackrf-tools/src/hackrf_info " ] ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  output . strip ( )  ==  b " "  or  b " No HackRF boards found. "  in  output : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      print ( " No HackRF boards found! " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  else : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  not  os . path . exists ( ' LimeGPS ' ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      print ( " LimeGPS not found run  ' setup.sh '  first " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  not  os . path . exists ( ' LimeSuite ' ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      print ( " LimeSuite not found run  ' setup.sh '  first " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    output  =  sp . check_output ( [ " LimeSuite/builddir/LimeUtil/LimeUtil " ,  " --find " ] ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  output . strip ( )  ==  b " " : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      print ( " No LimeSDR device found! " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print ( f " Device:  { output . strip ( ) . decode ( ' utf-8 ' ) } " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  lat  ==  0  and  lon  ==  0 : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    lat ,  lon  =  get_random_coords ( 47.2020 ,  15.7403 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  rinex_file  =  download_rinex ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  timeout  =  None 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  jump_sim : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    timeout  =  30 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  if  hackrf_mode : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    run_hackRF_loop ( lat ,  lon ,  rinex_file ,  timeout ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  else : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    run_limeSDR_loop ( lat ,  lon ,  alt ,  contin_sim ,  rinex_file ,  timeout ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								if  __name__  ==  " __main__ " : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  parser  =  argparse . ArgumentParser ( description = " Simulate static [or random jumping] GPS signal. " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  parser . add_argument ( " lat " ,  type = float ,  nargs = ' ? ' ,  default = 0 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  parser . add_argument ( " lon " ,  type = float ,  nargs = ' ? ' ,  default = 0 ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  parser . add_argument ( " alt " ,  type = float ,  nargs = ' ? ' ,  default = 0 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  parser . add_argument ( " --jump " ,  action = " store_true " ,  help = " signal that jumps around the world " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  parser . add_argument ( " --contin " ,  action = " store_true " ,  help = " continuously/slowly moving around the world " ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  parser . add_argument ( " --hackrf " ,  action = " store_true " ,  help = " hackrf mode (DEFAULT: LimeSDR) " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  args  =  parser . parse_args ( ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  main ( args . lat ,  args . lon ,  args . alt ,  args . jump ,  args . contin ,  args . hackrf )