#---------------------------------------------------------------------- # Includes #---------------------------------------------------------------------- import gps, os, time, shlex, sys, subprocess, re, math from datetime import datetime from dateutil import zoneinfo #---------------------------------------------------------------------- # Global Variables / Constants #---------------------------------------------------------------------- # Global debug to output console DEBUG = True # Global to write the date and column headers WRITE_FILE_HEADER = True # Automatically connect even when disconnected AUTO_CONNECT = True # Global for which data set to get RUN_RSSI = True RUN_IPERF = False # Pause through loop PRESS_ANY_KEY = False # Directory constants - The name of the file is the date and time RSSI_DIRECTORY = "./rssi/" MBPS_DIRECTORY = "./mbps/" CREATE_DIRS_IF_NOT_EXIST = False # wimaxcu constants SCAN_RSSI_STRING = "RSSI : " STATUS_LINK_RSSI_STRING = "RSSI : " # Iperf server IPERF_SERVER = "iperf.wiscnet.net" #---------------------------------------------------------------------- # Function: iperf_from_server() # Parameters: none. # Returns: Overall value (mbps) from the command or -1 # Description: Runs iperf tcp test with the server address in the global variable. # With the current command the output interval is set to every 2 seconds. The first # "0.0-" that is output from the iperf command is going to be 0.0-2.0 and the overall # will be output by 0.0-10.x. An example output of the average is below: # [1860] 0.0-10.1 sec 1.43 MBytes 1.19 Mbits/sec # So after we find the second "0.0-" we look for "Mbits/sec" and work backwards to # get the overall throughput #---------------------------------------------------------------------- def iperf_from_server(): # Local Variables isSecond = False mbps = -1 # Try running an iperf test and grab the overall Mbits/sec p = subprocess.Popen(["iperf", "-c", IPERF_SERVER, "-i2"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) try: for line in p.stdout.readlines(): # Command outputs 0.0- twice, 2nd one contains the overall average if re.search("0.0-",line) and not isSecond: isSecond = True elif re.search("0.0-",line) and isSecond: # Found the second one, get the Mbits/sec and work backwards for the value idx = line.index("Mbits/sec") mbps = line[idx-5:idx-1] except: print 'Waiting for subprocess to end before exiting...' p.communicate() sys.exit() return mbps #---------------------------------------------------------------------- # Function: rssi_wimaxcu_connected() # Parameters: none. # Returns: Overall rssi value from the "wimaxcu status link" command or -1 # Description: Runs the "wimaxcu status link" command and searches for the # rssi output value. #---------------------------------------------------------------------- def rssi_wimaxcu_connected(): # Local Variables # Default return value if failed rssi = -1 # Run wimaxcu status link p = subprocess.Popen(["wimaxcu", "status", "link"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) for line in p.stdout.readlines(): # Look for the RSSI line if re.search(STATUS_LINK_RSSI_STRING,line): # Found the rssi line, now have to find the index of the value idx = line.index(STATUS_LINK_RSSI_STRING) + len(STATUS_LINK_RSSI_STRING) # Only get the number, disregard the dB on the end of the output rssi = line[idx:idx+3] return rssi #---------------------------------------------------------------------- # Function: get_rssi_from_scan(x) # Parameters: x - String to search for the RSSI value # Returns: RSSI value or -1 # Description: Searches x, a single line, for the output of the RSSI value. The format it # searches for is the output of the "wimaxcu scan" command. #---------------------------------------------------------------------- def get_rssi_from_scan(x): # Local Variables rssi = -1 if re.search(SCAN_RSSI_STRING,x): idx = x.index(SCAN_RSSI_STRING) + len(SCAN_RSSI_STRING) rssi = x[idx:idx+3] return rssi; #---------------------------------------------------------------------- # Function: wimaxcu_scan_geni() # Parameters: None. # Returns: RSSI value of the GENI network or -1 # Description: Runs the wimaxcu_scan command and searches the output for # the GENI network. If the GENI network is found, the RSSI value is returned. # This is useful when multiple networks are listed under the scan. #---------------------------------------------------------------------- def wimaxcu_scan_geni(): # Local Variables rssi = -1 is_geni = False; nsp = ""; ID = ""; signal = ""; rssi = ""; cinr = ""; NetworkType = ""; Activated = ""; # Run wimaxcu scan p = subprocess.Popen(["wimaxcu", "scan"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) try: while not is_geni: line = p.stdout.readline() if re.search("Network found.", line): nsp = p.stdout.readline() ID = p.stdout.readline() signal = p.stdout.readline() rssi = p.stdout.readline() cinr = p.stdout.readline() NetworkType = p.stdout.readline() Activated = p.stdout.readline() print '\tNetwork found: ', nsp if re.search("NSP : GENI 4G", nsp): is_geni = True if not line: return -1; except: print 'Waiting for subprocess to end before exiting...' p.communicate() sys.exit() p.communicate() return get_rssi_from_scan(rssi) #---------------------------------------------------------------------- # Function: is_connected() # Parameters: None. # Returns: True or False if is connected to GENI network # Description: Checks to see if rssi returned from the connected # function returns -1 -> which means it is not connected #---------------------------------------------------------------------- def is_connected(): return (rssi_wimaxcu_connected() != -1) #---------------------------------------------------------------------- # Function: wimaxcu_connect() # Parameters: None. # Returns: True or False if is connected to GENI network # Description: Checks to see if rssi returned from the connected # function returns -1 -> which means it is not connected #---------------------------------------------------------------------- def wimaxcu_connect(): # Local Variables geni_network_found = False while not geni_network_found: print 'Scanning for GENI network...' if wimaxcu_scan_geni() != -1: geni_network_found = True # Run wimaxcu connect print 'Connecting to GENI network...' p = subprocess.Popen(["wimaxcu", "connect", "network", "51"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) output = p.communicate() print output[0] print 'GENI network connected' #---------------------------------------------------------------------- # Function: is_dir() # Parameters: x - Path to check if it is a directory. # Returns: None. # Description: Checks to see if the path is a directory and prompts # the user to create the directory if it is not already created. #---------------------------------------------------------------------- def is_dir(x): if not os.path.isdir(x): print x + ' does not exist.' if CREATE_DIRS_IF_NOT_EXIST: print 'Creating ' + x + 'directory.' os.makedirs(x) if os.path.isdir(x): return True else: return False else: return True; return False #--------------------------------- # Main Program Entrance #--------------------------------- # Get the date and time now = datetime.now() # Initialize main program variables rssi_filename = RSSI_DIRECTORY + "{0}.txt".format(now.strftime("%Y-%m-%d_%H:%M")) mbps_filename = MBPS_DIRECTORY + "{0}.txt".format(now.strftime("%Y-%m-%d_%H:%M")) iperf_header_written = False rssi_header_written = False # Verify the RSSI and MBPS directory exist if not is_dir(RSSI_DIRECTORY): sys.exit("Rssi directory does not exist and could not be created.") if not is_dir(MBPS_DIRECTORY): sys.exit("Mbps directory does not exist and could not be created.") while 1: if AUTO_CONNECT: while not is_connected(): wimaxcu_connect() else: if not is_connected(): sys.exit('Please connect to the GENI network or enable AUTO_CONNECT. Exiting...') # Setup communication to GPS daemon lat = 0 lon = 0 session = gps.gps(mode=gps.WATCH_NEWSTYLE) session.poll() session.stream() # Wait until we get location information, takes a little bit of time print 'Getting gps signal...' while session.fix.latitude == lat: session.poll(),time.sleep(1) while session.fix.longitude == lon: session.poll(),time.sleep(1) lat = session.fix.latitude lon = session.fix.longitude # Check for valid signal, had nan once if math.isnan(lat) or math.isnan(lon): print 'Error getting GPS signal.' sys.exit(lat) session.poll() lat = session.fix.latitude lon = session.fix.longitude if RUN_RSSI: rssi = rssi_wimaxcu_connected() # Write lat,long,dbm to a file with open(rssi_filename, mode='a') as f: if WRITE_FILE_HEADER: if not rssi_header_written: f.write("latitude,longitude,RSSI\n") rssi_header_written = True f.write('{0},{1},{2}\n'.format(lat,lon,rssi)) session.poll() lat = session.fix.latitude lon = session.fix.longitude if RUN_IPERF: mbps = iperf_from_server() # Write lat,long,dbm to a file with open(mbps_filename, mode='a') as f: if WRITE_FILE_HEADER: if not iperf_header_written: f.write("latitude,longitude,Mbps\n") iperf_header_written = True f.write('{0},{1},{2}\n'.format(lat,lon,mbps)) # Print output to the console if DEBUG: print '------------------------------------' print now.strftime("%Y-%m-%d %H:%M") print 'latitude ' , lat print 'longitude ' , lon if RUN_RSSI: print 'rssi ' , rssi if RUN_IPERF: print 'mbps ' , mbps print '------------------------------------\n\n' if PRESS_ANY_KEY: raw_input('Hit enter for next location') # Close the GPS session session.close()