summaryrefslogtreecommitdiffstats
path: root/Src
diff options
context:
space:
mode:
authorTom2012-03-18 14:47:12 +0100
committerTom2012-03-18 14:47:12 +0100
commitafb35ce2e297fd8285befdfd998bb5804bf5addc (patch)
treeae09f0d2faedcad05e2474029788b1d0ba61dc4d /Src
parentdiagrams for presentation added (diff)
downloadimsi-catcher-detection-afb35ce2e297fd8285befdfd998bb5804bf5addc.tar.gz
imsi-catcher-detection-afb35ce2e297fd8285befdfd998bb5804bf5addc.tar.xz
imsi-catcher-detection-afb35ce2e297fd8285befdfd998bb5804bf5addc.zip
presentation nearly finished
Diffstat (limited to 'Src')
-rw-r--r--Src/PyCatcher/GUI/catcher_main.glade150
-rw-r--r--Src/PyCatcher/src/evaluators.py10
-rw-r--r--Src/PyCatcher/src/filters.py13
-rw-r--r--Src/PyCatcher/src/parstertest.py47
-rw-r--r--Src/PyCatcher/src/pyCatcherController.py35
-rw-r--r--Src/PyCatcher/src/pyCatcherModel.py104
-rw-r--r--Src/PyCatcher/src/pyCatcherView.py17
-rw-r--r--Src/PyCatcher/src/rules.py128
-rw-r--r--Src/PyCatcher/src/settings.py16
-rw-r--r--Src/osmolib/src/host/layer23/src/misc/catcher.c5
10 files changed, 419 insertions, 106 deletions
diff --git a/Src/PyCatcher/GUI/catcher_main.glade b/Src/PyCatcher/GUI/catcher_main.glade
index 89e0578..68f17cd 100644
--- a/Src/PyCatcher/GUI/catcher_main.glade
+++ b/Src/PyCatcher/GUI/catcher_main.glade
@@ -340,7 +340,21 @@
</packing>
</child>
<child>
- <placeholder/>
+ <object class="GtkCheckButton" id="cb_filter_900">
+ <property name="label" translatable="yes">Show only the 900 MHz band</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">7</property>
+ </packing>
</child>
</object>
<packing>
@@ -357,6 +371,7 @@
</object>
<object class="GtkWindow" id="main_window">
<property name="can_focus">False</property>
+ <property name="title" translatable="yes">Base Station Analysis Toolkit</property>
<property name="default_width">800</property>
<property name="default_height">600</property>
<property name="has_resize_grip">False</property>
@@ -614,12 +629,21 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
- <object class="GtkTreeView" id="tv_stations">
+ <object class="GtkScrolledWindow" id="scrolledwindow1">
<property name="visible">True</property>
<property name="can_focus">True</property>
- <signal name="select-cursor-row" handler="_on_tv_stations_clicked" swapped="no"/>
- <child internal-child="selection">
- <object class="GtkTreeSelection" id="treeview-selection"/>
+ <property name="vscrollbar_policy">always</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="tv_stations">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscroll_policy">natural</property>
+ <signal name="select-cursor-row" handler="_on_tv_stations_clicked" swapped="no"/>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="treeview-selection"/>
+ </child>
+ </object>
</child>
</object>
<packing>
@@ -640,10 +664,18 @@
</packing>
</child>
<child>
- <object class="GtkTextView" id="te_log">
+ <object class="GtkScrolledWindow" id="scrolledwindow2">
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="editable">False</property>
+ <property name="vscrollbar_policy">always</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTextView" id="te_log">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">False</property>
+ </object>
+ </child>
</object>
<packing>
<property name="expand">True</property>
@@ -769,8 +801,8 @@
</packing>
</child>
<child>
- <object class="GtkCheckButton" id="cb_uniqueness">
- <property name="label" translatable="yes">Unique Cell ID</property>
+ <object class="GtkCheckButton" id="cb_arfcn_provider">
+ <property name="label" translatable="yes">ARFCN/Provider Mapping</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@@ -780,19 +812,20 @@
<property name="draw_indicator">True</property>
</object>
<packing>
- <property name="expand">False</property>
+ <property name="expand">True</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
<child>
- <object class="GtkCheckButton" id="cb_neighbourhood">
- <property name="label" translatable="yes">Neighbourhood Structure</property>
+ <object class="GtkCheckButton" id="cb_lac">
+ <property name="label" translatable="yes">LAC Median Deviation</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>
@@ -802,22 +835,84 @@
</packing>
</child>
<child>
- <object class="GtkCheckButton" id="cb_lac">
- <property name="label" translatable="yes">LAC Integrity</property>
+ <object class="GtkCheckButton" id="cb_pure_neighbourhood">
+ <property name="label" translatable="yes">Pure Neighbourhoods</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">False</property>
+ <property name="expand">True</property>
<property name="fill">True</property>
<property name="position">5</property>
</packing>
</child>
<child>
+ <object class="GtkCheckButton" id="cb_neighbourhood_structure">
+ <property name="label" translatable="yes">Neighbourhood Structure</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">False</property>
+ <property name="fill">True</property>
+ <property name="position">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="cb_neighbours_discovered">
+ <property name="label" translatable="yes">Fully discovered Neighbourhoods</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="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">7</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="cb_uniqueness">
+ <property name="label" translatable="yes">Unique Cell ID</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">False</property>
+ <property name="fill">True</property>
+ <property name="position">8</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHSeparator" id="sepa1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">9</property>
+ </packing>
+ </child>
+ <child>
<object class="GtkCheckButton" id="cb_cell_id_database">
<property name="label" translatable="yes">Cell ID Database</property>
<property name="visible">True</property>
@@ -830,7 +925,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
- <property name="position">6</property>
+ <property name="position">10</property>
</packing>
</child>
<child>
@@ -869,7 +964,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
- <property name="position">7</property>
+ <property name="position">11</property>
</packing>
</child>
<child>
@@ -885,7 +980,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
- <property name="position">8</property>
+ <property name="position">12</property>
</packing>
</child>
<child>
@@ -924,24 +1019,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
- <property name="position">9</property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="cb_arfcn_provider">
- <property name="label" translatable="yes">ARFCN/Provider Mapping</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">10</property>
+ <property name="position">13</property>
</packing>
</child>
</object>
diff --git a/Src/PyCatcher/src/evaluators.py b/Src/PyCatcher/src/evaluators.py
index de624fa..719f996 100644
--- a/Src/PyCatcher/src/evaluators.py
+++ b/Src/PyCatcher/src/evaluators.py
@@ -13,21 +13,27 @@ class StationClass:
class Evaluator:
return_type = type(RuleResult)
+ identifier = 'Base Class'
def evaluate(self, result_list):
- return RuleResult.CRITICAL
+ return RuleResult.CRITICAL, {'Evaluator Base Class':'This should not happen!'}
class ConservativeEvaluator(Evaluator):
+ identifier = 'Conservative Evaluator'
+
def evaluate(self, result_list):
final_result = RuleResult.OK
+ decision_rule = 'None'
for key in result_list.keys():
if result_list[key] == RuleResult.WARNING:
final_result = RuleResult.WARNING
+ decision_rule = key
if result_list[key] == RuleResult.CRITICAL:
final_result = RuleResult.CRITICAL
+ decision_rule = key
break
- return final_result
+ return final_result, {'Decision founded on': decision_rule}
class BayesEvaluator(Evaluator):
return_type = type(int)
diff --git a/Src/PyCatcher/src/filters.py b/Src/PyCatcher/src/filters.py
index 6247aac..b574ade 100644
--- a/Src/PyCatcher/src/filters.py
+++ b/Src/PyCatcher/src/filters.py
@@ -6,6 +6,12 @@ class Filter:
def execute(self, station_list):
raise NotImplementedError('Filter not yet implemented')
+class BandFilter(Filter):
+ band = 0
+
+ def execute(self, station_list):
+ raise NotImplementedError('Band Filters should not be executed!')
+
class ARFCNFilter(Filter):
def execute(self, station_list):
filtered_list = []
@@ -25,7 +31,6 @@ class ProviderFilter(Filter):
filtered_list.append(station)
return filtered_list
-#FIXME: provide extra abstraction for parameterless filters (on/off filters)
-class FoundFilter(Filter):
- def execute(self, station_list):
- pass \ No newline at end of file
+class BandFilter900(BandFilter):
+ band = 900
+
diff --git a/Src/PyCatcher/src/parstertest.py b/Src/PyCatcher/src/parstertest.py
new file mode 100644
index 0000000..c824b36
--- /dev/null
+++ b/Src/PyCatcher/src/parstertest.py
@@ -0,0 +1,47 @@
+def si_to_bin(si):
+ system_information = si.split(' ')
+ neighbours = system_information[3:19]
+ bin_representation = ''
+ for value in neighbours:
+ bin_representation += str(bin(int(value, 16))[2:].zfill(8))
+ return bin_representation
+
+def parse_bit_mask(si, offset):
+ bin_representation = si_to_bin(si)
+ neighbours = []
+ for x in xrange(1,125):
+ index = 0-x
+ bit = bin_representation[index]
+ if bit == '1':
+ neighbours.append(abs(index) + offset)
+ return neighbours
+
+
+def parse_900(si):
+ neighbours = parse_bit_mask(si, 0)
+ print neighbours
+
+def parse_1800(si,siter,sibis):
+ pass
+
+def parse_900_ext(si):
+ pass
+
+
+
+system_information_1 = '59 06 1A 0B B9 3B 30 00 00 00 00 00 00 00 00 00 00 00 00 80 9D 00 00'
+system_information_2 = '59 06 1a 00 00 00 00 02 10 00 00 00 00 00 48 20 95 00 00 08 a5 00 00'
+system_information_3 = '59 06 1a 00 00 00 0b 90 08 00 00 00 01 14 08 00 11 00 00 88 a5 00 00'
+system_information_4 = '59 06 1a 00 00 00 0b 90 08 00 00 00 01 14 08 00 11 00 00 88 a5 00 00'
+
+parse_900(system_information_2)
+
+
+
+
+
+
+
+
+
+
diff --git a/Src/PyCatcher/src/pyCatcherController.py b/Src/PyCatcher/src/pyCatcherController.py
index 9dce790..1de5f6e 100644
--- a/Src/PyCatcher/src/pyCatcherController.py
+++ b/Src/PyCatcher/src/pyCatcherController.py
@@ -3,9 +3,10 @@ import gtk.glade
from driverConnector import DriverConnector
from pyCatcherModel import BaseStationInformation, BaseStationInformationList
from pyCatcherView import PyCatcherGUI
-from filters import ARFCNFilter,FoundFilter,ProviderFilter
+from filters import ARFCNFilter,ProviderFilter, BandFilter900
from evaluators import EvaluatorSelect, BayesEvaluator, ConservativeEvaluator, WeightedEvaluator
-from rules import ProviderRule, ARFCNMappingRule, CountryMappingRule, LACMappingRule, UniqueCellIDRule, LACIntegrityRule
+from rules import ProviderRule, ARFCNMappingRule, CountryMappingRule, LACMappingRule, UniqueCellIDRule, \
+ LACMedianRule, NeighbourhoodStructureRule, PureNeighbourhoodRule, FullyDiscoveredNeighbourhoodsRule
import pickle
class PyCatcherController:
@@ -20,7 +21,9 @@ class PyCatcherController:
self.arfcn_filter = ARFCNFilter()
self.provider_filter = ProviderFilter()
- #self.found_filter = FoundFilter()
+
+ self.band_filter = BandFilter900()
+ self.band_filter.is_active = True
self._filters = [self.arfcn_filter, self.provider_filter]
@@ -39,10 +42,18 @@ class PyCatcherController:
self.lac_mapping_rule.is_active = True
self.unique_cell_id_rule = UniqueCellIDRule()
self.unique_cell_id_rule.is_active = True
+ self.lac_median_rule = LACMedianRule()
+ self.lac_median_rule.is_active = True
+ self.neighbourhood_structure_rule = NeighbourhoodStructureRule()
+ 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.is_active = False
self._rules = [self.provider_rule, self.country_mapping_rule, self.arfcn_mapping_rule, self.lac_mapping_rule,
- self.unique_cell_id_rule]
-
+ self.unique_cell_id_rule, self.lac_median_rule, self.neighbourhood_structure_rule,
+ self.pure_neighbourhood_rule, self.full_discovered_neighbourhoods_rule]
gtk.main()
def log_message(self, message):
@@ -71,11 +82,6 @@ class PyCatcherController:
self._gui.log_line("found " + base_station.provider + ' (' + str(base_station.arfcn) + ')')
self._base_station_list.add_station(base_station)
self.trigger_evaluation()
-
- def trigger_redraw(self):
- dotcode = self._base_station_list.get_dot_code(self._filters)#,self.found_filter)
- if dotcode != 'digraph bsnetwork { }':
- self._gui.load_dot(dotcode)
def _firmware_waiting_callback(self):
self._gui.log_line("firmware waiting for device")
@@ -112,5 +118,10 @@ class PyCatcherController:
def trigger_evaluation(self):
self._base_station_list.evaluate(self._rules, self._active_evaluator)
- self._base_station_list.refill_store(self.bs_tree_list_data)
- self.trigger_redraw() \ No newline at end of file
+ self._base_station_list.refill_store(self.bs_tree_list_data, self.band_filter, self._filters)
+ self.trigger_redraw()
+
+ def trigger_redraw(self):
+ dotcode = self._base_station_list.get_dot_code(self.band_filter, self._filters)
+ if dotcode != 'digraph bsnetwork { }':
+ self._gui.load_dot(dotcode) \ No newline at end of file
diff --git a/Src/PyCatcher/src/pyCatcherModel.py b/Src/PyCatcher/src/pyCatcherModel.py
index 20f4ab7..bf4be14 100644
--- a/Src/PyCatcher/src/pyCatcherModel.py
+++ b/Src/PyCatcher/src/pyCatcherModel.py
@@ -18,35 +18,44 @@ class BaseStationInformation:
self.lac = 0
self.cell = 0
self.rules_report = {}
+ self.evaluation_report = {}
self.evaluation = 'NYE'
+ self.evaluation_by = 'NYE'
def get_list_model(self):
return self.provider, str(self.arfcn), str(self.rxlev), self.evaluation, self.discovery_time
def get_neighbour_arfcn(self):
- neighbours = self.system_info_t2[3:19]
+ if 1 < self.arfcn < 125:
+ return self._parse_900()
+ return []
+
+ def si_to_bin(self, si):
+ neighbours = si[3:19]
bin_representation = ''
- neighbour_arfcn = []
-
for value in neighbours:
bin_representation += str(bin(int(value, 16))[2:].zfill(8))
-
-
- # for i, bit in enumerate(reversed(a)):
- # if bit == '1':
- # print i
+ return bin_representation
+ def parse_bit_mask(self, si, offset):
+ bin_representation = self.si_to_bin(si)
+ neighbours = []
for x in xrange(1,125):
index = 0-x
bit = bin_representation[index]
if bit == '1':
- neighbour_arfcn.append(abs(index))
- return neighbour_arfcn
-
- def get_neighbour_arfcn_ter(self):
+ neighbours.append(abs(index) + offset)
+ return neighbours
+
+
+ def _parse_900(self):
+ neighbours = self.parse_bit_mask(self.system_info_t2, 0)
+ return map(int, neighbours)
+
+ def _parse_1800(self):
pass
-
- def get_neighbour_arfcn_bis(self):
+
+ def _parse_900_ext(self):
pass
def create_report(self):
@@ -66,55 +75,77 @@ Evaluation: %s\n
for key in self.rules_report.keys():
report_rules += str(key) + ': ' + str(self.rules_report[key]) + '\n'
report_rules +='\n\n'
+
+ report_evaluation ='------- Evaluation Report (' + self.evaluation_by + ')-----------\n'
+ for key in self.evaluation_report.keys():
+ report_evaluation += str(key) + ': ' + str(self.evaluation_report[key]) + '\n'
+ report_evaluation +='\n\n'
+
report_raw = '''------- Raw Information -----------
SystemInfo_2: %s
SystemInfo_2ter: %s
SystemInfo_2bis: %s
'''%(' '.join(self.system_info_t2), ' '.join(self.system_info_t2ter), ' '.join(self.system_info_t2bis))
- return report_params + report_rules + report_raw
+
+
+ return report_params + report_rules + report_evaluation + report_raw
class BaseStationInformationList:
def __init__(self):
self._base_station_list = []
def add_station(self, base_station):
+ base_station.found = True
for item in self._base_station_list:
- if item.arfcn == base_station.arfcn:
+ #TODO: check if this works like i thought
+ if item.arfcn == base_station.arfcn and item.bsic == base_station.bsic:
item.discovery_time = datetime.datetime.now().strftime('%T')
break
else:
self._base_station_list.append(base_station)
- def get_dot_code(self, filters=None, found_filter=None):
+ def get_dot_code(self, band_filter, filters=None):
preamble = r'digraph bsnetwork { '
postamble = r'}'
code = ''
- filtered_list = self._base_station_list
-
- if found_filter is None:
- print_neighbours = True
- else:
- print_neighbours = not found_filter.is_active
-
- if filters is not None:
- for filter in filters:
- if filter.is_active:
- filtered_list = filter.execute(filtered_list)
-
+
+ filtered_list = self._get_filtered_list(band_filter, filters)
+
for station in filtered_list:
code += str(station.arfcn) + r' [color=red]; '
- if print_neighbours:
- for neighbour in station.get_neighbour_arfcn():
- code += str(station.arfcn) + r' -> ' + str(neighbour) + r'; '
+ for neighbour in station.get_neighbour_arfcn():
+ code += str(station.arfcn) + r' -> ' + str(neighbour) + r'; '
#TODO: make printing the source a fixed option
#print preamble + code + postamble
return preamble + code + postamble
- def refill_store(self, store):
+ def refill_store(self, store, band_filter, filters=None):
store.clear()
- for item in self._base_station_list:
+ filtered_list = self._get_filtered_list(band_filter, filters)
+ for item in filtered_list:
store.append(item.get_list_model())
-
+
+
+ def _get_filtered_list(self, band_filter, filters):
+ filtered_list = []
+
+ #only implemented for 900 band so far, so no distinction
+ if band_filter.is_active:
+ for item in self._base_station_list:
+ if 0 < item.arfcn < 125:
+ filtered_list.append(item)
+ else:
+ for item in self._base_station_list:
+ filtered_list.append(item)
+
+ if filters is not None:
+ for filter in filters:
+ if filter.is_active:
+ filtered_list = filter.execute(filtered_list)
+
+ return filtered_list
+
+
def create_report(self, arfcn):
for item in self._base_station_list:
if item.arfcn == int(arfcn):
@@ -127,5 +158,6 @@ class BaseStationInformationList:
if rule.is_active:
rule_results[rule.identifier] = rule.check(station.arfcn, self._base_station_list)
station.rules_report = rule_results.copy()
- station.evaluation = evaluator.evaluate(rule_results)
+ station.evaluation, station.evaluation_report = evaluator.evaluate(rule_results)
+ station.evaluation_by = evaluator.identifier
\ No newline at end of file
diff --git a/Src/PyCatcher/src/pyCatcherView.py b/Src/PyCatcher/src/pyCatcherView.py
index d20e8ca..a5be2e7 100644
--- a/Src/PyCatcher/src/pyCatcherView.py
+++ b/Src/PyCatcher/src/pyCatcherView.py
@@ -3,7 +3,6 @@ import gtk
from xdot import DotWidget
import datetime
import time
-from filters import ARFCNFilter, FoundFilter, ProviderFilter
class PyCatcherGUI:
@@ -68,13 +67,13 @@ class PyCatcherGUI:
self._catcher_controller.arfcn_filter.is_active = True
else:
self._catcher_controller.arfcn_filter.is_active = False
-
- #if self._builder.get_object('cb_only_scanned_bs').get_active():
- # self._catcher_controller.found_filter.is_active = True
- #else:
- # self._catcher_controller.found_filter.is_active = False
- self._catcher_controller.trigger_redraw()
+ if self._builder.get_object('cb_filter_900').get_active():
+ self._catcher_controller.band_filter.is_active = True
+ else:
+ self._catcher_controller.band_filter.is_active = False
+
+ self._catcher_controller.trigger_evaluation()
def _update_rules(self):
self._catcher_controller.provider_rule.is_active = self._builder.get_object('cb_provider_known').get_active()
@@ -82,6 +81,10 @@ class PyCatcherGUI:
self._catcher_controller.arfcn_mapping_rule.is_active = self._builder.get_object('cb_arfcn_provider').get_active()
self._catcher_controller.lac_mapping_rule.is_active = self._builder.get_object('cb_lac_provider').get_active()
self._catcher_controller.unique_cell_id_rule.is_active = self._builder.get_object('cb_uniqueness').get_active()
+ self._catcher_controller.lac_median_rule.is_active = self._builder.get_object('cb_lac').get_active()
+ self._catcher_controller.neighbourhood_structure_rule.is_active = self._builder.get_object('cb_neighbourhood_structure').get_active()
+ self._catcher_controller.pure_neighbourhood_rule.is_active = self._builder.get_object('cb_pure_neighbourhood').get_active()
+ self._catcher_controller.full_discovered_neighbourhoods_rule.is_active = self._builder.get_object('cb_neighbours_discovered').get_active()
self._catcher_controller.trigger_evaluation()
def _update_evaluators(self):
diff --git a/Src/PyCatcher/src/rules.py b/Src/PyCatcher/src/rules.py
index 6ec7f3e..312b26f 100644
--- a/Src/PyCatcher/src/rules.py
+++ b/Src/PyCatcher/src/rules.py
@@ -1,9 +1,10 @@
-from settings import Provider_list, Provider_Country_list, LAC_mapping, ARFCN_mapping
+from settings import Provider_list, Provider_Country_list, LAC_mapping, ARFCN_mapping, LAC_threshold
class RuleResult:
OK = 'Ok'
WARNING = 'Warning'
CRITICAL = 'Critical'
+ IGNORE = 'Ignore'
class Rule:
is_active = False
@@ -12,11 +13,22 @@ class Rule:
def check(self, arfcn, base_station_list):
return RuleResult.CRITICAL
+ def _extract_neighbours(self, arfcn, base_station_list):
+ for item in base_station_list:
+ if item.arfcn == arfcn:
+ return item.get_neighbour_arfcn()
+
+ def _extract_provider(self, arfcn, base_station_list):
+ for item in base_station_list:
+ if item.arfcn == arfcn:
+ return item.provider
+
class ProviderRule (Rule):
identifier = 'Provider Check'
def check(self, arfcn, base_station_list):
result = RuleResult.CRITICAL
+
for station in base_station_list:
if station.arfcn == arfcn:
if station.provider in Provider_list:
@@ -29,6 +41,7 @@ class CountryMappingRule (Rule):
def check(self, arfcn, base_station_list):
result = RuleResult.OK
+
for station in base_station_list:
if station.arfcn == arfcn:
if station.provider in Provider_Country_list:
@@ -43,6 +56,7 @@ class ARFCNMappingRule (Rule):
def check(self, arfcn, base_station_list):
result = RuleResult.CRITICAL
+
for station in base_station_list:
if station.arfcn == arfcn:
if station.provider in ARFCN_mapping:
@@ -55,6 +69,7 @@ class LACMappingRule (Rule):
def check(self, arfcn, base_station_list):
result = RuleResult.CRITICAL
+
for station in base_station_list:
if station.arfcn == arfcn:
if station.provider in LAC_mapping:
@@ -62,29 +77,132 @@ class LACMappingRule (Rule):
result = RuleResult.OK
return result
-class LACIntegrityRule (Rule):
- identifier = 'LAC Integrity'
-
class UniqueCellIDRule (Rule):
identifier = 'Unique CellID'
def check(self, arfcn, base_station_list):
result = RuleResult.OK
cell_id = 0
+
for station in base_station_list:
if station.arfcn == arfcn:
cell_id = station.cell
+
for station in base_station_list:
if station.arfcn != arfcn:
if station.cell == cell_id:
result = RuleResult.CRITICAL
return result
+class LACMedianRule (Rule):
+ identifier = 'LAC Median Deviation'
+
+ def check(self, arfcn, base_station_list):
+ lac_median_list = []
+ provider = self._extract_provider(arfcn, base_station_list)
+ lac_to_test = 0
+
+ for item in base_station_list:
+ if arfcn == item.arfcn:
+ lac_to_test = item.lac
+ if provider == item.provider:
+ lac_median_list.append(item.lac)
+
+ if len(lac_median_list) < 2:
+ return RuleResult.IGNORE
+
+ lac_median_list.sort()
+ median = lac_median_list[int(len(lac_median_list)/2)]
+ upper_bound = median + median * LAC_threshold
+ lower_bound = median - median * LAC_threshold
+
+ if lower_bound < lac_to_test < upper_bound:
+ return RuleResult.OK
+ else:
+ return RuleResult.CRITICAL
+
+
class NeighbourhoodStructureRule (Rule):
identifier = 'Neighbourhood Structure'
+ def check(self, arfcn, base_station_list):
+ #TODO: remove this when parser fully implemented
+ if not 0 < arfcn < 125:
+ return RuleResult.IGNORE
+
+ neighbours = self._extract_neighbours(arfcn, base_station_list)
+
+ if not len(neighbours):
+ return RuleResult.CRITICAL
+
+ at_least_one_neighbour_found = False
+
+ for item in base_station_list:
+ if item.arfcn in neighbours:
+ at_least_one_neighbour_found = True
+ break
+
+ if at_least_one_neighbour_found:
+ return RuleResult.OK
+ else:
+ return RuleResult.CRITICAL
+
+
+class PureNeighbourhoodRule (Rule):
+ identifier = 'Pure Neighbourhoods'
+
+ def check(self, arfcn, base_station_list):
+ #TODO: remove this when parser fully implemented
+ if not 0 < arfcn < 125:
+ return RuleResult.IGNORE
+
+ neighbours = self._extract_neighbours(arfcn, base_station_list)
+ provider = self._extract_provider(arfcn, base_station_list)
+ all_neighbours_pure = True
+ for item in base_station_list:
+ if item.arfcn in neighbours:
+ if not item.provider == provider:
+ all_neighbours_pure = False
+
+ if all_neighbours_pure:
+ return RuleResult.OK
+ else:
+ return RuleResult.CRITICAL
+
+
+class FullyDiscoveredNeighbourhoodsRule (Rule):
+ identifier = 'Fully Discovered Neighbourhoods'
+
+ def check(self, arfcn, base_station_list):
+ #TODO: remove this when parser fully implemented
+ if not 0 < arfcn < 125:
+ return RuleResult.IGNORE
+
+ neighbours = self._extract_neighbours(arfcn, base_station_list)
+ all_neighbours_discovered = True
+ for item in base_station_list:
+ if item.arfcn in neighbours:
+ neighbours.remove(item.arfcn)
+
+ if len(neighbours):
+ return RuleResult.WARNING
+ else:
+ return RuleResult.OK
+
+class LocationAreaDatabaseRule(Rule):
+ identifier = 'Location Area Database'
+
+ def check(self, arfcn, base_station_list):
+ pass
+
class CellIDDatabaseRule (Rule):
identifier = 'CellID Database'
+ def check(self, arfcn, base_station_list):
+ pass
+
class BDDLearningRule (Rule):
- identifier = 'BDD Learning' \ No newline at end of file
+ identifier = 'BDD Learning'
+
+ def check(self, arfcn, base_station_list):
+ pass
diff --git a/Src/PyCatcher/src/settings.py b/Src/PyCatcher/src/settings.py
index 048a8aa..9d94054 100644
--- a/Src/PyCatcher/src/settings.py
+++ b/Src/PyCatcher/src/settings.py
@@ -19,23 +19,31 @@ Commands = {'osmocon_command' : [Osmocon_lib + '/host/osmocon/osmocon',
#Rules Configuration -------------------------------------------------------------------------------------------
-Provider_list = ['T-Mobile', 'O2']
+Provider_list = ['T-Mobile', 'O2', 'Vodafone', 'E-Plus']
Provider_Country_list = {
'T-Mobile':'Germany',
- 'O2':'France'
+ 'O2':'Germany',
+ 'Vodafone':'Germany',
+ 'E-Plus':'Germany'
}
LAC_mapping = {
'T-Mobile' : [21000,22000],
- 'O2' : [0,9999]
+ 'O2' : [0,9999],
+ 'Vodafone' : [0,100000],
+ 'E-Plus' : [0,100000]
}
ARFCN_mapping = {
'T-Mobile' : [0,9999],
- 'O2' : [0,9999]
+ 'O2' : [0,9999],
+ 'Vodafone' : [0,9999],
+ 'E-Plus' : [0,9999]
}
+LAC_threshold = 0.5
+
BSIC_database = ''
Cell_ID_database = ''
diff --git a/Src/osmolib/src/host/layer23/src/misc/catcher.c b/Src/osmolib/src/host/layer23/src/misc/catcher.c
index 754ad60..82e7ea2 100644
--- a/Src/osmolib/src/host/layer23/src/misc/catcher.c
+++ b/Src/osmolib/src/host/layer23/src/misc/catcher.c
@@ -179,12 +179,15 @@ static void log_sysinfo(void)
{
struct rx_meas_stat *meas = &ms->meas;
struct gsm48_sysinfo *s = &sysinfo;
+ struct gsm322_cellsel *cs = &ms->cellsel;
int8_t rxlev;
char ta_str[32] = "";
if (log_si.ta != 0xff)
sprintf(ta_str, " TA=%d", log_si.ta);
+
+
//LOGP(DSUM, LOGL_INFO, "Cell: ARFCN=%d MCC=%s MNC=%s (%s, %s)%s\n",
// arfcn, gsm_print_mcc(s->mcc), gsm_print_mnc(s->mnc),
// gsm_get_mcc(s->mcc), gsm_get_mnc(s->mcc, s->mnc), ta_str);
@@ -199,6 +202,7 @@ static void log_sysinfo(void)
LOGFILE("BSIC: %d,%d\n", s->bsic >> 3, s->bsic & 7);
rxlev = meas->rxlev / meas->frames - 110;
LOGFILE("rxlev: %d\n", rxlev);
+
//if (s->si1)
// log_frame("si1", s->si1_msg);
if (s->si2)
@@ -226,6 +230,7 @@ static void log_sysinfo(void)
LOGFLUSH();
}
+
static void timeout_cb(void *arg)
{
switch (state) {