summaryrefslogtreecommitdiffstats
path: root/Src
diff options
context:
space:
mode:
authorTom2012-06-10 18:34:23 +0200
committerTom2012-06-10 18:34:23 +0200
commit7d99a18c935659967b19051f999e3fc353720e56 (patch)
tree29a8e30be74f1c45bd480375a601c7db15d8993e /Src
parentchanged images (diff)
downloadimsi-catcher-detection-7d99a18c935659967b19051f999e3fc353720e56.tar.gz
imsi-catcher-detection-7d99a18c935659967b19051f999e3fc353720e56.tar.xz
imsi-catcher-detection-7d99a18c935659967b19051f999e3fc353720e56.zip
increased shininess
Diffstat (limited to 'Src')
-rw-r--r--Src/PyCatcher/Databases/foobar.dbbin0 -> 2048 bytes
-rw-r--r--Src/PyCatcher/Databases/home.csv10
-rw-r--r--Src/PyCatcher/Databases/home.dbbin5120 -> 5120 bytes
-rw-r--r--Src/PyCatcher/GUI/catcher_main.glade45
-rw-r--r--Src/PyCatcher/foo.py24
-rw-r--r--Src/PyCatcher/src/driverConnector.py8
-rw-r--r--Src/PyCatcher/src/evaluators.py38
-rw-r--r--Src/PyCatcher/src/localAreaDatabse.py55
-rw-r--r--Src/PyCatcher/src/pyCatcherController.py68
-rw-r--r--Src/PyCatcher/src/pyCatcherModel.py16
-rw-r--r--Src/PyCatcher/src/pyCatcherView.py5
-rw-r--r--Src/PyCatcher/src/rules.py70
-rw-r--r--Src/PyCatcher/src/settings.py14
13 files changed, 269 insertions, 84 deletions
diff --git a/Src/PyCatcher/Databases/foobar.db b/Src/PyCatcher/Databases/foobar.db
new file mode 100644
index 0000000..9f7c605
--- /dev/null
+++ b/Src/PyCatcher/Databases/foobar.db
Binary files differ
diff --git a/Src/PyCatcher/Databases/home.csv b/Src/PyCatcher/Databases/home.csv
index 89e2960..d77926c 100644
--- a/Src/PyCatcher/Databases/home.csv
+++ b/Src/PyCatcher/Databases/home.csv
@@ -1,3 +1,9 @@
Country, Provider, ARFCN, rxlev, BSIC, LAC, Cell ID, Evaluation, Latitude, Longitude, Encryption, DB Status, DB Provider, Neighbours
-Germany, Vodafone, 62, -76, 7/4, 793, 21791, Ok, 0, 0, Not checked., Not looked up, None, 1 3 6 55 60 65 70 75 107 111 113 115 119
-Germany, Vodafone, 3, -83, 7/3, 793, 45352, Ok, 0, 0, Not checked., Not looked up, None, 1 6 55 62 65 70 75 111 113 119 725 729 731
+afone, 62, -75, 7/4, 793, 21791, Ok, 0, 0, Not looked up, None, 1 3 6 55 60 65 70 75 107 111 113 115 119
+Germany, Vodafone, 3, -84, 7/3, 793, 45352, Ok, 0, 0, Not looked up, None, 1 6 55 62 65 70 75 111 113 119 725 729 731
+Germany, Vodafone, 119, -89, 3/2, 793, 21781, Ok, 0, 0, Not looked up, None, 1 3 6 62 65 66 75 79 107 108 111 113 725 731
+Germany, T-Mobile, 49, -89, 7/0, 21014, 6321, Warning, 0, 0, Not looked up, None, 17 19 21 84 89 93 96 97 124
+Germany, Vodafone, 6, -88, 7/6, 793, 19222, Critical, 0, 0, Not looked up, None, 1 3 10 52 55 57 60 62 107 111 115 119 121
+Germany, O2, 1022, -90, 7/3, 50945, 39093, Critical, 0, 0, Not looked up, None, 654 667 670 675 682 705 711 721 1003 1014 1016 1020
+Germany, T-Mobile, 100, -90, 7/5, 21014, 47560, Critical, 0, 0, Not looked up, None, 17 18 21 29 31 36 97 98
+Germany, E-Plus, 812, -80, 3/6, 588, 7098, Critical, 0, 0, Not looked up, None, 803 809 820 822 823 825 828 977 990
diff --git a/Src/PyCatcher/Databases/home.db b/Src/PyCatcher/Databases/home.db
index 4c9ef1e..f91ad9e 100644
--- a/Src/PyCatcher/Databases/home.db
+++ b/Src/PyCatcher/Databases/home.db
Binary files differ
diff --git a/Src/PyCatcher/GUI/catcher_main.glade b/Src/PyCatcher/GUI/catcher_main.glade
index 65454cd..43747c9 100644
--- a/Src/PyCatcher/GUI/catcher_main.glade
+++ b/Src/PyCatcher/GUI/catcher_main.glade
@@ -404,24 +404,6 @@ Available Evaluators
</packing>
</child>
<child>
- <object class="GtkRadioButton" id="rb_weighted_evaluator">
- <property name="label" translatable="yes">Weighted Evaluator</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
- <property name="xalign">0</property>
- <property name="active">True</property>
- <property name="draw_indicator">True</property>
- <property name="group">rb_conservative_evaluator</property>
- </object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
<object class="GtkRadioButton" id="rb_grouped_evaluator">
<property name="label" translatable="yes">Grouped Evaluator</property>
<property name="visible">True</property>
@@ -436,7 +418,7 @@ Available Evaluators
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
- <property name="position">3</property>
+ <property name="position">2</property>
</packing>
</child>
</object>
@@ -1219,6 +1201,23 @@ PCH Scan Parameters
</packing>
</child>
<child>
+ <object class="GtkCheckButton" id="cb_integrate_pch">
+ <property name="label" translatable="yes">Integrate PCH Scans with Model</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_action_appearance">False</property>
+ <property name="xalign">0</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
<object class="GtkLabel" id="label8">
<property name="visible">True</property>
<property name="can_focus">False</property>
@@ -1226,7 +1225,7 @@ PCH Scan Parameters
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
- <property name="position">3</property>
+ <property name="position">4</property>
</packing>
</child>
<child>
@@ -1241,7 +1240,7 @@ PCH Scan Parameters
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
- <property name="position">4</property>
+ <property name="position">5</property>
</packing>
</child>
<child>
@@ -1252,7 +1251,7 @@ PCH Scan Parameters
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
- <property name="position">5</property>
+ <property name="position">6</property>
</packing>
</child>
<child>
@@ -1264,7 +1263,7 @@ PCH Scan Parameters
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
- <property name="position">6</property>
+ <property name="position">7</property>
</packing>
</child>
</object>
diff --git a/Src/PyCatcher/foo.py b/Src/PyCatcher/foo.py
new file mode 100644
index 0000000..d6ce582
--- /dev/null
+++ b/Src/PyCatcher/foo.py
@@ -0,0 +1,24 @@
+max_prime = 30#775146
+candidates = range(2,max_prime)
+current_prime = 5
+primes = [2,3,5]
+
+while candidates and current_prime < max_prime:
+ if len(primes) %10 == 0:
+ print current_prime
+ for number in candidates:
+ if number % current_prime == 0:
+ candidates.remove(number)
+ current_prime = candidates[0]
+ candidates.remove(current_prime)
+ primes.append(current_prime)
+
+print primes
+
+result = 0
+
+for number in primes:
+ if 600851475143%number ==0:
+ result = number
+
+print result
diff --git a/Src/PyCatcher/src/driverConnector.py b/Src/PyCatcher/src/driverConnector.py
index cf6f15a..97acf0a 100644
--- a/Src/PyCatcher/src/driverConnector.py
+++ b/Src/PyCatcher/src/driverConnector.py
@@ -217,6 +217,7 @@ class PCHThread(threading.Thread):
while(pch_retries > 0 and scan_time.seconds < max_scan_time and not self._thread_break):
scan_time = datetime.datetime.now() - start_time
poll_result = poll_obj.poll(0)
+ pch_failed = False
if poll_result:
line = scan_process.stdout.readline()
else:
@@ -240,6 +241,8 @@ class PCHThread(threading.Thread):
if 'FBSB RESP: result=255' in line:
if(pch_retries > 0):
retry = True
+ else:
+ pch_failed = True
break
if(retry):
@@ -251,9 +254,6 @@ class PCHThread(threading.Thread):
if scan_process:
scan_process.kill()
- print 'Different TMSI: %d'%len(self._tmsi_dict)
- for key, value in self._tmsi_dict.iteritems():
- print key, value
result = {
'Pagings': pages_found,
@@ -262,7 +262,7 @@ class PCHThread(threading.Thread):
}
if not self._thread_break:
- self._scan_finished_callback((arfcn, result))
+ self._scan_finished_callback((arfcn, result), pch_failed)
class BufferFillerThread(threading.Thread):
def __init__(self, buffer, process):
diff --git a/Src/PyCatcher/src/evaluators.py b/Src/PyCatcher/src/evaluators.py
index 759d400..d567de3 100644
--- a/Src/PyCatcher/src/evaluators.py
+++ b/Src/PyCatcher/src/evaluators.py
@@ -1,9 +1,8 @@
from rules import RuleResult
-from settings import Rule_Groups, Rule_Weights
+from settings import Rule_Groups
class EvaluatorSelect:
CONSERVATIVE = 0
- WEIGHTED = 1
GROUP = 2
class Evaluator:
@@ -32,16 +31,6 @@ class ConservativeEvaluator(Evaluator):
return final_result, {'Decision founded on': decision_rule}
-
-class WeightedEvaluator(Evaluator):
- identifier = 'Weighted Evaluator'
-
- def evaluate(self, result_list):
- for rule, evaluation in reseult_list:
- pass
-
-
-
class GroupEvaluator(Evaluator):
identifier = 'Group Evaluator'
@@ -50,28 +39,35 @@ class GroupEvaluator(Evaluator):
for group in Rule_Groups:
group_results.append(self.evaluate_group_results(self.convert_to_group_result_list(group,result_list)))
- if group_results.count(RuleResult.CRITICAL) > 0:
- return RuleResult.CRITICAL
- elif group_results.count(RuleResult.WARNING) > 0:
- return RuleResult.WARNING
+ criticals = group_results.count(RuleResult.CRITICAL)
+ warnings = group_results.count(RuleResult.WARNING)
+ oks = group_results.count(RuleResult.OK)
+
+ if criticals > 0:
+ return RuleResult.CRITICAL,{'Criticals': criticals, 'Warnings': warnings, 'Oks':oks}
+ elif warnings > 0:
+ return RuleResult.WARNING,{'Criticals': criticals, 'Warnings': warnings, 'Oks':oks}
+ elif oks > 0:
+ return RuleResult.OK,{'Criticals': criticals, 'Warnings': warnings, 'Oks':oks}
else:
- return RuleResult.OK
+ return RuleResult.CRITICAL,{'Reason': 'No evaluation possible, all active rules yield IGNORE.'}
def convert_to_group_result_list(self, group, result_list):
group_result_list = []
for rule in group:
- group_results.append(result_list[rule])
+ if result_list.has_key(rule):
+ group_result_list.append(result_list[rule])
return group_result_list
def evaluate_group_results(self, results):
oks = results.count(RuleResult.OK)
warnings = results.count(RuleResult.WARNING)
criticals = results.count(RuleResult.CRITICAL)
- if criticals >= oks and criticals >= warnings:
+ if criticals >= oks and criticals >= warnings and not criticals == 0:
return RuleResult.CRITICAL
- elif warnings >= oks and warnings>= criticals:
+ elif warnings >= oks and warnings>= criticals and not warnings == 0:
return RuleResult.WARNING
- elif oks >= criticals and oks >= warnings:
+ elif oks >= criticals and oks >= warnings and not oks == 0:
return RuleResult.OK
else:
return RuleResult.IGNORE \ No newline at end of file
diff --git a/Src/PyCatcher/src/localAreaDatabse.py b/Src/PyCatcher/src/localAreaDatabse.py
index de08035..99f3971 100644
--- a/Src/PyCatcher/src/localAreaDatabse.py
+++ b/Src/PyCatcher/src/localAreaDatabse.py
@@ -7,6 +7,7 @@ class LocalAreaDatabase:
def __init__(self):
self._connection = None
self._cursor = None
+ self.cache = []
def load_or_create_database(self, name):
if self._connection:
@@ -22,6 +23,8 @@ class LocalAreaDatabase:
if not database_exists:
self._create_base_table()
+ self.refresh_object_cache()
+
def _create_base_table(self):
sql = '''CREATE TABLE basestations(
cellid INTEGER, country TEXT, provider TEXT, arfcn INTEGER, bsic TEXT, lac INTEGER,
@@ -65,6 +68,31 @@ class LocalAreaDatabase:
self._connection.commit()
def get_station(self, cellID):
+ for item in self.cache:
+ if item.cellID == cellID:
+ return item
+ return None
+
+ def refresh_object_cache(self):
+ if not self._connection:
+ return
+ self.cache = []
+ sql = 'SELECT * FROM basestations'
+ self._cursor.execute(sql)
+ try:
+ result = self._cursor.fetchall()
+ for line in result:
+ self.cache.append(
+ LACDBEntry(
+ line[0], line[1], line[2], line[3], line[4],
+ line[5], line[6], line[7],line[8]
+ )
+ )
+ except:
+ print 'shouldnt happen'
+ return
+
+ def _get_station(self, cellID):
if not self._connection:
return None
sql = 'SELECT * FROM basestations WHERE cellid =%d'%cellID
@@ -80,7 +108,7 @@ class LocalAreaDatabase:
self.insert_or_alter_base_station(station)
def insert_or_alter_base_station(self, base_station):
- lookupresult = self.get_station(base_station.cell)
+ lookupresult = self._get_station(base_station.cell)
if lookupresult:
self._alter_station(base_station,lookupresult[6],lookupresult[7],lookupresult[8])
else:
@@ -90,4 +118,27 @@ class LocalAreaDatabase:
if self._cursor:
self._cursor.close()
if self._connection:
- self._connection.close() \ No newline at end of file
+ self._connection.close()
+
+class LACDBEntry():
+ def __init__(self, cellID, country, provider, arfcn, bsic, lac, rxmin, rxmax, sightings):
+ self.cellID = cellID
+ self.country = country
+ self.provider = provider
+ self.arfcn = arfcn
+ self.bsic = bsic
+ self.lac = lac
+ self.rxmin = rxmin
+ self.rxmax = rxmax
+ self.sightings = sightings
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Src/PyCatcher/src/pyCatcherController.py b/Src/PyCatcher/src/pyCatcherController.py
index 3d3beac..1ab2a70 100644
--- a/Src/PyCatcher/src/pyCatcherController.py
+++ b/Src/PyCatcher/src/pyCatcherController.py
@@ -5,9 +5,9 @@ from driverConnector import DriverConnector
from pyCatcherModel import BaseStationInformation, BaseStationInformationList
from pyCatcherView import PyCatcherGUI
from filters import ARFCNFilter,ProviderFilter
-from evaluators import EvaluatorSelect, ConservativeEvaluator, WeightedEvaluator, GroupEvaluator
+from evaluators import EvaluatorSelect, ConservativeEvaluator,GroupEvaluator
from rules import ProviderRule, ARFCNMappingRule, CountryMappingRule, LACMappingRule, UniqueCellIDRule, \
- LACMedianRule, NeighbourhoodStructureRule, PureNeighbourhoodRule, FullyDiscoveredNeighbourhoodsRule, RuleResult, CellIDDatabaseRule, LocationAreaDatabaseRule, RxChangeRule, LACChangeRule
+ LACMedianRule, NeighbourhoodStructureRule, PureNeighbourhoodRule, DiscoveredNeighboursRule, RuleResult, CellIDDatabaseRule, LocationAreaDatabaseRule, RxChangeRule, LACChangeRule,PCHRule
import pickle
from localAreaDatabse import LocalAreaDatabase
from cellIDDatabase import CellIDDatabase, CellIDDBStatus, CIDDatabases
@@ -33,7 +33,6 @@ class PyCatcherController:
self._conservative_evaluator = ConservativeEvaluator()
self._group_evaluator = GroupEvaluator()
- self._weighted_evaluator = WeightedEvaluator()
self._active_evaluator = self._conservative_evaluator
self._pch_scan_running = False
@@ -58,7 +57,7 @@ class PyCatcherController:
self.neighbourhood_structure_rule.is_active = True
self.pure_neighbourhood_rule = PureNeighbourhoodRule()
self.pure_neighbourhood_rule.is_active = True
- self.full_discovered_neighbourhoods_rule = FullyDiscoveredNeighbourhoodsRule()
+ self.full_discovered_neighbourhoods_rule = DiscoveredNeighboursRule()
self.full_discovered_neighbourhoods_rule.is_active = False
self.cell_id_db_rule = CellIDDatabaseRule()
self.cell_id_db_rule.is_active = False
@@ -69,16 +68,21 @@ class PyCatcherController:
self.lac_change_rule.is_active = True
self.rx_change_rule = RxChangeRule()
self.rx_change_rule.is_active = True
+ self.pch_scan_integration = PCHRule()
+ self.pch_scan_integration.is_active = True
self._rules = [self.provider_rule, self.country_mapping_rule, self.arfcn_mapping_rule, self.lac_mapping_rule,
self.unique_cell_id_rule, self.lac_median_rule, self.neighbourhood_structure_rule,
self.pure_neighbourhood_rule, self.full_discovered_neighbourhoods_rule, self.cell_id_db_rule,
- self.location_area_database_rule, self.lac_change_rule, self.rx_change_rule]
+ self.location_area_database_rule, self.lac_change_rule, self.rx_change_rule, self.pch_scan_integration]
self.use_google = False
self.use_open_cell_id = False
self.use_local_db = (False, '')
+ self.pch_active = False
+ self.sweep_active = False
+
self._location = ''
gtk.main()
@@ -87,11 +91,18 @@ class PyCatcherController:
self._gui.log_line(message)
def start_scan(self):
+ if self.pch_active:
+ self._gui.log_line('Cannot sweep while PCH is active')
+ return
self._gui.log_line("start scan")
+ self.sweep_active = True
self._driver_connector.start_scanning(self._found_base_station_callback)
def stop_scan(self):
+ if not self.sweep_active:
+ return
self._gui.log_line("stop scan")
+ self.sweep_active = False
self._driver_connector.stop_scanning()
def start_firmware(self):
@@ -126,11 +137,14 @@ class PyCatcherController:
self._active_evaluator = self._conservative_evaluator
elif evaluator == EvaluatorSelect.GROUP:
self._active_evaluator = self._group_evaluator
- elif evaluator == EvaluatorSelect.WEIGHTED:
- self._active_evaluator = self._weighted_evaluator
self.trigger_evaluation()
def user_pch_scan(self, provider):
+ if self.sweep_active:
+ self._gui.log_line('Cannot PCH scan during active sweep scan.')
+ return
+ else:
+ self.pch_active = True
if not provider:
self._gui.set_user_image()
return
@@ -156,6 +170,11 @@ class PyCatcherController:
def normal_pch_scan(self, arfcns, timeout):
+ if self.sweep_active:
+ self._gui.log_line('Cannot PCH scan during active sweep scan.')
+ return
+ else:
+ self.pch_active = True
self._accumulated_pch_results = []
self._user_mode_flag = False
self._scan_pch(arfcns, timeout)
@@ -176,8 +195,27 @@ class PyCatcherController:
self._pch_scan_running = True
self._driver_connector.start_pch_scan(arfcn, self._pch_timeout, self._pch_done_callback)
- def _pch_done_callback(self, results):
+ def _pch_done_callback(self, results, pch_failed):
arfcn, values = results
+
+ if pch_failed:
+ self._gui.log_line('PCH scan failed (%d)'%arfcn)
+ if not self._user_mode_flag :
+ if self._remaining_pch_arfcns:
+ self._do_next_pch_scan()
+ else:
+ self._gui.set_pch_results(self._accumulated_pch_results)
+ else:
+ self._gui.set_user_image(RuleResult.IGNORE)
+ self.pch_active = False
+ return
+
+ for station in self._base_station_list._get_unfiltered_list():
+ if station.arfcn == arfcn and self.pch_scan_integration.is_active:
+ station.imm_ass_non_hop = values['Assignments_non_hopping']
+ station.imm_ass_hop = values['Assignments_hopping']
+ station. pagings = values['Pagings']
+ station.pch_scan_done = True
self._accumulated_pch_results.append(results)
self._gui.log_line('Finished PCH scan on ARFCN %d'%arfcn)
self._pch_scan_running = False
@@ -197,6 +235,7 @@ class PyCatcherController:
else:
self._gui.log_line('Paging/Assignment threshold not met')
self._gui.set_user_image(RuleResult.CRITICAL)
+ self.pch_active = False
def _return_normalised_pagings(self, pagings):
return (float(pagings) / float(USR_timeout))*10
@@ -251,6 +290,7 @@ class PyCatcherController:
self._location = new_location
self._local_area_database.load_or_create_database(self._location)
self._gui.log_line('Location changed to %s'%self._location)
+ self._local_area_database.refresh_object_cache()
def save_project(self, path):
filehandler = open(path, 'w')
@@ -261,6 +301,13 @@ class PyCatcherController:
def load_project(self, path):
filehandler = open(path, 'r')
base_station_list = pickle.load(filehandler)
+ #bit of a hack to be able to use old scans
+ for station in base_station_list._get_unfiltered_list():
+ if not hasattr(station, 'pagings'):
+ station.imm_ass_hop = 0
+ station.imm_ass_non_hop = 0
+ station.pagings = 0
+ station.pch_scan_done = False
self._base_station_list = base_station_list
self.trigger_evaluation()
filehandler.close()
@@ -297,9 +344,9 @@ class PyCatcherController:
return
path = Database_path + self._location + '.csv'
file = open(path,'w')
- file.write('Country, Provider, ARFCN, rxlev, BSIC, LAC, Cell ID, Evaluation, Latitude, Longitude, Encryption, DB Status, DB Provider, Neighbours\n')
+ file.write('Country, Provider, ARFCN, rxlev, BSIC, LAC, Cell ID, Evaluation, Latitude, Longitude, DB Status, DB Provider, Neighbours\n')
for item in self._base_station_list._get_unfiltered_list():
- file.write('%s, %s, %d, %d, %s, %d, %d, %s, %d, %d, %s, %s, %s, %s\n'%
+ file.write('%s, %s, %d, %d, %s, %d, %d, %s, %d, %d, %s, %s, %s\n'%
(item.country,
item.provider,
item.arfcn,
@@ -310,7 +357,6 @@ class PyCatcherController:
item.evaluation,
item.latitude,
item.longitude,
- item.encryption,
item.db_status,
item.db_provider,
' '.join(map(str,item.neighbours))))
diff --git a/Src/PyCatcher/src/pyCatcherModel.py b/Src/PyCatcher/src/pyCatcherModel.py
index 0370da5..b1cfb31 100644
--- a/Src/PyCatcher/src/pyCatcherModel.py
+++ b/Src/PyCatcher/src/pyCatcherModel.py
@@ -33,14 +33,22 @@ class BaseStationInformation:
self.longitude = 0
self.db_status = CellIDDBStatus.NOT_LOOKED_UP
self.db_provider = CIDDatabases.NONE
- self.imm_ass = 0
+
+ self.imm_ass_hop = 0
+ self.imm_ass_non_hop = 0
self.pagings = 0
+ self.pch_scan_done = False
def get_list_model(self):
return self.provider, str(self.arfcn), str(self.rxlev), str(self.cell),self.evaluation, self.discovery_time,self.times_scanned
def create_report(self):
+
+ pch_scan_string = 'No'
+ if self.pch_scan_done:
+ pch_scan_string = 'Yes'
+
report_params = '''------- Base Station Parameters -----------
Country: %s
Provider: %s
@@ -50,12 +58,16 @@ BSIC: %s
LAC: %s
Cell ID: %s
Neighbours: %s
+PCH Scan done: %s
+IAs (hopping): %d
+IAs (non hopping): %d
+Pagings (hopping/10s): %d
Latitude: %s
Longitude: %s
Database Status: %s
Database Provider: %s
Evaluation: %s\n
-'''%(self.country,self.provider, self.arfcn, self.rxlev, self.bsic, self.lac, self.cell, ', '.join(map(str,self.neighbours)),self.latitude,self.longitude,self.db_status, self.db_provider,self.evaluation)
+'''%(self.country,self.provider, self.arfcn, self.rxlev, self.bsic, self.lac, self.cell, ', '.join(map(str,self.neighbours)),pch_scan_string,self.imm_ass_hop,self.imm_ass_non_hop,self.pagings,self.latitude,self.longitude,self.db_status, self.db_provider,self.evaluation)
report_rules ='------- Rule Results -----------\n'
for key in self.rules_report.keys():
diff --git a/Src/PyCatcher/src/pyCatcherView.py b/Src/PyCatcher/src/pyCatcherView.py
index 07c7d10..9d8cfef 100644
--- a/Src/PyCatcher/src/pyCatcherView.py
+++ b/Src/PyCatcher/src/pyCatcherView.py
@@ -137,8 +137,6 @@ class PyCatcherGUI:
def _update_evaluators(self):
if self._builder.get_object('rb_conservative_evaluator').get_active():
self._catcher_controller.set_evaluator(EvaluatorSelect.CONSERVATIVE)
- elif self._builder.get_object('rb_weighted_evaluator').get_active():
- self._catcher_controller.set_evaluator(EvaluatorSelect.WEIGHTED)
elif self._builder.get_object('rb_grouped_evaluator').get_active():
self._catcher_controller.set_evaluator(EvaluatorSelect.GROUP)
@@ -172,13 +170,16 @@ class PyCatcherGUI:
print 'NODE CLICKED'
def _on_user_close_clicked(self, widget):
+ self._catcher_controller.trigger_evaluation()
self._user_window.hide()
def _on_pch_close_clicked(self, widget):
+ self._catcher_controller.pch_scan_integration.is_active = self._builder.get_object('cb_integrate_pch').get_active()
self._catcher_controller.trigger_evaluation()
self._pch_window.hide()
def _on_pch_scan_clicked(self, widget):
+ self._catcher_controller.pch_scan_integration.is_active = self._builder.get_object('cb_integrate_pch').get_active()
arfcns = map(int, self._builder.get_object('te_pch_arfcns').get_text().strip().split(','))
timeout = int(self._builder.get_object('te_pch_timeout').get_text())
self._catcher_controller.normal_pch_scan(arfcns, timeout)
diff --git a/Src/PyCatcher/src/rules.py b/Src/PyCatcher/src/rules.py
index 29676cf..447c7b5 100644
--- a/Src/PyCatcher/src/rules.py
+++ b/Src/PyCatcher/src/rules.py
@@ -1,5 +1,5 @@
from settings import Provider_list, Provider_Country_list, LAC_mapping, ARFCN_mapping, LAC_threshold, DB_RX_threshold, \
- CH_RX_threshold
+ CH_RX_threshold, Pagings_per_10s_threshold, Assignment_limit, Neighbours_threshold
from cellIDDatabase import CellIDDBStatus
import math
@@ -133,6 +133,7 @@ class NeighbourhoodStructureRule (Rule):
identifier = 'Neighbourhood Structure'
def check(self, arfcn, base_station_list):
+ own_provider = self._extract_provider(arfcn, base_station_list)
own_neighbours = self._extract_neighbours(arfcn, base_station_list)
if not len(own_neighbours):
return RuleResult.CRITICAL
@@ -149,13 +150,24 @@ class NeighbourhoodStructureRule (Rule):
if foreign_neighbour_arfcn in own_neighbours:
at_least_one_indirect_neighbour = True
- if at_least_one_neighbour_found:
+ incoming_edges = False
+ all_neighbours = []
+ for station in base_station_list:
+ if station.provider == own_provider:
+ for neighbour in station.neighbours:
+ all_neighbours.append(neighbour)
+ for neighbour_arfcn in all_neighbours:
+ if neighbour_arfcn == arfcn:
+ incoming_edges = True
+ break
+
+ if at_least_one_neighbour_found and incoming_edges:
return RuleResult.OK
- elif at_least_one_indirect_neighbour:
+
+ if at_least_one_neighbour_found or at_least_one_indirect_neighbour:
return RuleResult.WARNING
- else:
- return RuleResult.CRITICAL
+ return RuleResult.CRITICAL
class PureNeighbourhoodRule (Rule):
identifier = 'Pure Neighbourhoods'
@@ -176,8 +188,8 @@ class PureNeighbourhoodRule (Rule):
return RuleResult.CRITICAL
-class FullyDiscoveredNeighbourhoodsRule (Rule):
- identifier = 'Fully Discovered Neighbourhoods'
+class DiscoveredNeighboursRule (Rule):
+ identifier = 'Discovered Neighbours'
def check(self, arfcn, base_station_list):
@@ -187,13 +199,22 @@ class FullyDiscoveredNeighbourhoodsRule (Rule):
if item.arfcn in neighbours:
found += 1
- if len(neighbours) != found:
- return RuleResult.CRITICAL
+ if Neighbours_threshold < 0:
+ return RuleResult.IGNORE
+
+ if 0 <= Neighbours_threshold <=1:
+ if (float(found) / float(neighbours)) >= Neighbours_threshold:
+ return RuleResult.OK
+ else:
+ return RuleResult.CRITICAL
else:
- return RuleResult.OK
+ if found >= int(Neighbours_threshold):
+ return RuleResult.OK
+ else:
+ return RuleResult.CRITICAL
class LocationAreaDatabaseRule(Rule):
- identifier = 'Location Area Database'
+ identifier = 'Local Area Database'
def __init__(self):
self.location_database_object = None
@@ -205,10 +226,11 @@ class LocationAreaDatabaseRule(Rule):
result = self.location_database_object.get_station(item.cell)
if not result:
return RuleResult.CRITICAL
- rxmin = result[6]
- rxmax = result[7]
+ rxmin = result.rxmin
+ rxmax = result.rxmax
rxmin_thresh = rxmin - math.fabs(rxmin * DB_RX_threshold)
rxmax_thresh = rxmax + math.fabs(rxmax * DB_RX_threshold)
+
if rxmin_thresh <= float(item.rxlev) <= rxmax_thresh:
return RuleResult.OK
else:
@@ -289,3 +311,25 @@ class RxChangeRule (Rule):
else:
self._old_rx[arfcn] = item.rxlev, item.times_scanned, RuleResult.IGNORE
return RuleResult.IGNORE
+
+class PCHRule (Rule):
+ identifier = 'PCH Scan'
+
+ def check(self, arfcn, base_station_list):
+ for item in base_station_list:
+ if arfcn == item.arfcn:
+ if not item.pch_scan_done:
+ return RuleResult.IGNORE
+ else:
+ if item.imm_ass_non_hop > 0:
+ return RuleResult.CRITICAL
+ if item.pagings >= Pagings_per_10s_threshold and item.imm_ass_hop >= Assignment_limit:
+ return RuleResult.OK
+ else:
+ return RuleResult.CRITICAL
+
+
+
+
+
+
diff --git a/Src/PyCatcher/src/settings.py b/Src/PyCatcher/src/settings.py
index e263d72..f5cf511 100644
--- a/Src/PyCatcher/src/settings.py
+++ b/Src/PyCatcher/src/settings.py
@@ -49,7 +49,7 @@ ARFCN_mapping = {
LAC_threshold = 0.05
-DB_RX_threshold = 0.05
+DB_RX_threshold = 0.1
CH_RX_threshold = 0.07
@@ -57,11 +57,17 @@ Pagings_per_10s_threshold = 20
Assignment_limit = 0
-#Evaluator Configuration ---------------------------------------------------------------------------------------
+Neighbours_threshold = 4
-Rule_Groups = []
+#Evaluator Configuration ---------------------------------------------------------------------------------------
-Rule_Weights = {}
+Rule_Groups = [
+ ['Provider Check', 'Country Provider Mapping', 'ARFCN Mapping', 'LAC Mapping', 'Unique CellID'],
+ ['LAC Median Deviation', 'Neighbourhood Structure', 'Pure Neighbourhoods', 'Fully Discovered Neighbourhoods'],
+ ['Local Area Database','CellID Database'],
+ ['LAC Change Rule','rx Change Rule'],
+ ['PCH Scan']
+]
#PCH Parameters ------------------------------------------------------------------------------------------------