mobileInsight-core
Part-II: Analyzer¶
In this series, we will review the codes in mobileInsight-desktop
,
the core modules and desktop version of MobileInsight
. Following the
discussions in Part-I, this article introduces
analyzers
, the core modules in MobileInsight for cellular protocol
analytics. Besides, we will also introduce other misc modules in
mobileInsight-desktop
.
Contents
Analyzers¶
Overview¶
Given cellular messages from Monitors
, MobileInsight further
triggers analyzers to perform diverse cellular analytics. We have
realized various analyzers, all of which are included in
mobile_insight/analyzer
, as shown below (this list still goes on and
long):
./mobileInsight-desktop/mobile_insight/analyzer/
├── __init__.py
├── analyzer.py
├── wcdma_rrc_analyzer.py
├── log_analyzer.py
├── lte_mac_analyzer.py
├── lte_rrc_analyzer.py
├── lte_nas_analyzer.py
├── lte_pdcp_analyzer.py
├── lte_phy_analyzer.py
├── lte_rlc_analyzer.py
└── ...
Some common analyzers are summarized as below. Note that to develop a cellular protocol analyzer, it is usually required to have a comprehensive understanding of the 3G/4G cellular protocols. This requires to read 3GPP standards, as listed below. Instead of elaborating the protocol-specific analytics, this article will focus on the common APIs, conventions, and structures of an analyzer. We next elaborate it.
Analyze r |
Descrip tion |
Standar ds/Refere nce |
---|---|---|
lte_mac_analyzer .py |
4G MAC protocol analyzer |
TS36.321 |
lte_meas urement_ analyzer. py |
Reports 4G-RRC measureme nt results |
TS36.331 |
lte_nas_analyzer .py |
4G EMM/ESM protocol analyzer |
TS24.301 |
lte_pdcp _analyze r.py |
4G PDCP protocol analyzer |
TS36.323 |
lte_phy_analyzer .py |
4G PHY layer (LL1) analyzer |
TS36.213, TS36.211 |
lte_rlc_analyzer .py |
4G RLC protocol analyzer |
TS36.322 |
lte_rrc_analyzer .py |
4G RRC protocol analyzer |
TS36.331 |
umts_nas _analyze r.py |
3G MM/GMM/SM /CM protocol analyzer |
TS24.008 |
mobility_mngt.py |
4G handoff decision logic inference |
TS36.304, TS36.331, MobileIns ight paper [Mobicom’ 16] |
wcdma_rr c_analyz er.py |
3G-RRC protocol analyzer |
TS25.331 |
modem_de bug_anal yzer.py |
analyzer for Qualcom’s modem debug messages |
N/A |
msg_logg er.py |
A simple message dumper to stdio and/or file |
N/A |
protocol_analyzer .py |
An abstracti on of tracking protocol state machine |
N/A |
Base class: Analyzer
¶
All MobileInsight analyzers should inherit from the base class
Analyzers
, which defines the basic interface for a monitor: -
Declare its dependency on cellular message types: enable_log
; -
Declare its dependency on other analyzers: include_analyzer
; - Bind
to a monitor: set_source
; - Callbacks in response to events from
monitor (add_source_callback
) or other analyzers
(include_analyzer
); - (Optional) pushes runtime cellular information
to other mobile apps (with MI-APP API
).
Each analyzer should overload these interfaces based on its specific environment. The following code snippet summaries the abstract interfaces (complete code in mobile_insight/monitor/analyzer.py):
from ..element import Element, Event
class Analyzer(Element):
def __init__(self):
Element.__init__(self)
"""
Task lists
1. Initialize empty monitor
2. Initialize empty list of callbacks for monitor and other analyzers
"""
# ...
def set_source(self,source):
"""
Bind this analyzer to a monitor (source)
The messages from the source will drive the analysis.
All parent analyzers this analyzer depends on will also be recursively bound to source
"""
def add_source_callback(self,callback):
"""
Add a callback function to the analyzer.
When a message arrives, the analyzer will trigger the callbacks for analysis.
"""
def rm_source_callback(self,callback):
"""
Delete a callback function to the analyzer.
"""
def include_analyzer(self,analyzer_name,callback_list,*args):
"""
Declares the dependency from other analyzers.
Once declared, the current analyzer will receive events
from other analyzers, then trigger functions in callback_list
"""
def recv(self,module,event):
"""
Handle the received events.
This is an overload member from Element
"""
In the following, we will use one example LtePhyAnalyzer
to show how
to develop your own analyzer, and overload above interfaces.
Declare its dependency on cellular message types: enable_log
¶
An analyzer should declare the cellular messages it need for protocol
analytics. This is realized by calling enable_log
, which is
typically called when binding the analyzer to the monitor
. In this
way, the monitor will activate the corresponding message collection at
hardware, and pushes this message to analyzer by calling the source
callbacks (registered via add_source_callback
).
The following shows one example of how to achieve it. In writing a new
analyzer, we should overload set_source
to include supported message
types, and register the callback in __init__
initialization
function.
def set_source(self,source):
"""
Set the trace source. Enable the cellular signaling messages
:param source: the trace source (collector).
"""
Analyzer.set_source(self,source)
#Phy-layer logs
source.enable_log("LTE_PHY_PDSCH_Packet")
source.enable_log("LTE_PHY_PUSCH_CSF")
def __init__(self):
Analyzer.__init__(self)
self.add_source_callback(self.__msg_callback)
# ...
Declare analyzer dependency include_analyzer
¶
In many cases, your analyzer can be built on top of existing analyzers,
thus reusing their analytical results. This modular approach simplifies
the development, and makes code reusing possible. Typically, to declare
the dependency of an analyzer (i.e., “parent analyzer”), your analyzer
should call include_analyzer
during the initialization (in
__init__
), and passes a callback function in response to these
analyzer’s events. The following code shows how it works:
def __init__(self):
Analyzer.__init__(self)
#...
#include analyzers
self.include_analyzer("LteRrcAnalyzer",[self.__on_event])
self.include_analyzer("WcdmaRrcAnalyzer",[self.__on_event])
#...
def __on_event(self,msg):
"""callbacks for the 3G/4G RRC messages"""
#...
Event-driven Callbacks¶
For both monitor and parent analyzer, an analyzer should provide a
callback function in response to their cellular events. These callbacks
are registered when binding to a monitor (add_source_callback
), or
declaring a parent analyzer (include_analyzer
). In both cases, the
callback takes one parameter msg
as input, which is the event raised
by monitor or parent analyzer. Inside the callback, you can decode this
message, and perform specific analytics tasks.
The following shows the cellular message callback in LtePhyAnalyzer
.
This callback is triggered by cellular messages from Monitor
. It
first determines the message type, decode the messages, then take
specific actions.
def __msg_callback(self,msg):
if msg.type_id == "LTE_PHY_PDSCH_Packet":
self.callback_pdsch(msg)
elif msg.type_id == "LTE_PHY_PUSCH_CSF":
self.callback_pusch(msg)
elif msg.type_id == "LTE_MAC_UL_Tx_Statistics":
self.callback_pusch_grant(msg)
def callback_pusch(self,msg):
"""
Callback for LTE_PHY_PUSCH_CSF.
Currently it updates CQI.
:param msg: raw LTE_PHY_PUSCH_CSF packet
"""
log_item = msg.data.decode()
self.cur_cqi0 = log_item['WideBand CQI CW0']
self.cur_cqi1 = log_item['WideBand CQI CW1']
Push notifications: MI-APP
¶
Besides event-driven callbacks, the analyzer also provides another
interface to push analytics results to other mobile apps. This is called
MI-APP API
. To learn how to use it, you can read the following
tutorial:
How to use ``MI-APP API`? <mi-app>`__
Other Modules¶
Cellular message configuration and parsing: dm_collector_c
¶
The introduction of this module can be found here:
Wireshark helper: ws_dissector
¶
ws_dissector
is simply a wrapper of Wireshark’s parsing functions.
It is called by DmLogPacket
(which calls WSDissector
in
`mobile_insight/monitor/dm_collector/dm_endec/ws_dissector.py) to
parse cellular messages. The structure is as follows:
.
├── Makefile # Makefile
├── WiresharkCMakeTarget.txt #CMake configuration for Wireshark
├── packet-aww.cpp
├── packet-aww.h
└── ws_dissector.cpp # Wrapper of wireshark parsers
Desktop-version packaging and installation: setup.py
and MANIFEST.in
¶
MobileInsight leverages the standardized Python setup scripts to package its desktop-version modules. It has two files:
``MANIFEST.in``: it specifies which files to be included, which files should not be included (such as
dm_collector_c
). It follows the standardized Python setup script format, as shown below (mobileInsight-desktop/MANIFEST.in
):
include README.md
include LICENSE
include setup.py
recursive-include GUI *
recursive-include examples *.json *.py *.mi2log *.mi2app *.txt
recursive-include mobile_insight *.py *.m *.pyd README
recursive-exclude examples *.db
recursive-exclude mobile_insight *.db
exclude mobile_insight/monitor/android_qmdl_monitor.py
exclude mobile_insight/analyzer/handoff_loop_analyzer.py
prune dm_collector_c
prune docs/docs
``setup.py``: this file is used to install MobileInsight on desktop. It is a standardized Python setup script, and implements the following installation logic:
It checks the desktop’s OS version (Win/OS X/Linux), and downloads the corresponding
ws_dissector
, ‘dm_collector_c.so/pyd` and wireshark libraries;It copies all Python modules to Python-2.7’s default directory, and other binaries/libraries to system folders.
Desktop-version GUI¶
The details of this GUI can be found here: