123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- #!/usr/bin/python
- # -*- coding: utf-8 -*-
- #
- # Author: Petter Reinholdtsen
- # Lisence: GPL v2 or later at your own choice
- """
- Script to scan for base stations and start submitt GSM packages on one
- or more the frequencies found using grgsm_livemon_headless to the
- loopback network device
- The idea is to gather GSM packages from as many of the GSM base
- stations and phones in the area as possible, by spreading across as
- many operators as possible.
- """
- import imp
- from optparse import OptionParser
- import subprocess
- import sys
- import distutils.spawn
- def find_gsm_bases():
- grgsm_scanner_path = distutils.spawn.find_executable("grgsm_scanner")
- scanner = imp.load_source('scanner', grgsm_scanner_path)
- sys.modules['scanner'] = scanner
- (options, args) = scanner.argument_parser().parse_args()
- list = scanner.do_scan(options.samp_rate, options.band, options.speed,
- options.ppm, options.gain, options.args)
- return list
- def select_freqs(serverlist, count = 1):
- """
- Select the requested number of frequencies, spread across as many base
- station operators (mcc+mnc) as possible, pick the ones with the
- strongest signals.
- Could consider arfcn, freq, cid, lac, mcc, mnc, ccch_conf, power,
- neighbours, cell_arfcns to get as wide spread as possible, but is
- only using mcc, mnc and power at the moment.
- """
- # Make shallow copy to avoid modifying the list of the caller when
- # removing elements below.
- listcopy = []
- for s in serverlist:
- listcopy.append(s)
- freqs = []
- operatorscount = {}
- # First, initialize operatorscount[] to zero for all operators
- for s in listcopy:
- if not (s.mcc, s.mnc) in operatorscount:
- operatorscount[(s.mcc, s.mnc)] = 0
- # Next, pick the number of unique frequences we want, one a the
- # time, while trying to get as many operators as we cal.
- while 0 < count:
- sorted_list = sorted(listcopy, key=lambda s:
- (operatorscount[(s.mcc,s.mnc)], s.mcc,
- s.mnc, -s.power))
- if 0 in sorted_list:
- s = sorted_list[0]
- freqs.append(s.freq)
- operatorscount[(s.mcc, s.mnc)] = operatorscount[(s.mcc, s.mnc)] + 1
- listcopy.remove(s)
- count = count - 1
- return freqs
- def argument_parser():
- parser = OptionParser(usage="%prog: [options]")
- parser.add_option("-n", "--numrecv", dest="numrecv", type="int",
- default=1,
- help="Set number of livemon processes to start (use one per receiver) [default=%default]")
- return parser
- def main(options = None):
- if options is None:
- (options, args) = argument_parser().parse_args()
- print("Locating potential GSM base station frequencies (this can take a few minutes).")
- list = find_gsm_bases()
- print("Found %d frequences" % len(list))
- if len(list) > 0:
- numreceivers = options.numrecv
- freqs = select_freqs(list, numreceivers)
- print("Listening on the frequencies for %d potential GSM base stations." % numreceivers)
- # Make sure a user process can listen on port 4729 by asking
- # livemon processes to listen on other ports.
- serverport = 4730
- procs = []
- for freq in freqs:
- print("Starting livemon for freqency %.0f, server on port %d" % (freq, serverport))
- proc = subprocess.Popen(["grgsm_livemon_headless",
- "--serverport=%d" % serverport,
- "-f", str(freq)])
- procs.append(proc)
- serverport = serverport + 1
- # Keep the processes in our process group, to make sure they all die when scan-and-livemon is killed
- for proc in procs:
- proc.wait()
- if __name__ == '__main__':
- main()
|