Commit b6ee8a48 authored by Lionel Gauthier's avatar Lionel Gauthier

Message chart generator (mscgen)

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@6962 818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent db92e6be
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# The aim of this script is to collect some traces from oaisim stack and generate a sequence diagram image (png or jpeg). # The aim of this script is to collect some traces from oai stack and generate a sequence diagram image (png or jpeg).
# Actually it is a let's say a pre alpha release.
# an example of how it can be invoqued: msc_gen.py /tmp/msc_log.txt msc_log.txt is the input text file,
# it is generated by the execution of the oaisim stack: oaisim -...(misc args) | grep MSC_ > msc_log.txt
# Note L.G. to help: I put in script start_one_eNB_multi_UE_nas:
# $OPENAIR_TARGETS/SIMU/USER/oaisim -a -C1 -u $1 | tee /tmp/oai_log.txt | grep MSC_ > /tmp/msc_log.txt
# Now, examples of a mscgen trace in oaisim look like this:
# LOG_D(RRC, "[MSC_NEW][FRAME 00000][RRC_UE][MOD %02d][]\n", Mod_id+NB_eNB_INST); for declaring a new instance of a protocol
#
# LOG_D(RLC, "[MSC_MSG][FRAME %05d][RLC_AM][MOD %02d][RB %02d][--- MAC_DATA_REQ/ %d TB(s) --->][MAC_%s][MOD %02d][]\n", ....)
# for tracing a message between 2 protocol entities on the sequence diagram chart.
#
# LOG_D(RRC, "[MSC_NBOX][FRAME %05d][RRC_UE][MOD %02d][][Tx RRCConnectionReconfigurationComplete to ENB index %d][RRC_UE][MOD %02d][]\n", ...)
# for generating a notice box on the protocol entity sequence diagram chart.
import sys import sys
...@@ -29,56 +15,34 @@ from datetime import date ...@@ -29,56 +15,34 @@ from datetime import date
MSCGEN_OUTPUT_TYPE = "png" MSCGEN_OUTPUT_TYPE = "png"
MAX_MESSAGES_PER_PAGE = 36 MAX_MESSAGES_PER_PAGE = 36
SYSTEM_FRAME_NUMBER_STR = 'FRAME' MSC_NEW_STR = '[PROTO]'
MODULE_STR = 'MOD' MSC_MSG_STR = '[MESSAGE]'
RADIO_BEARER_STR = 'RB' MSC_BOX_STR = '[EVENT]'
MSC_NEW_STR = '[MSC_NEW]'
MSC_MSG_STR = '[MSC_MSG]'
MSC_NBOX_STR = '[MSC_NBOX]' # This list is filled as follow : g_proto_names[module_id_int] = (proto_name)
MSC_BOX_STR = '[MSC_BOX]' g_proto_names = []
MSC_ABOX_STR = '[MSC_ABOX]'
MSC_RBOX_STR = '[MSC_RBOX]'
# This dic is filled as follow : g_entities_dic[module_id_int][radio_bearer_id_int].append(entity_name) # list of messages
# where entity name can be any of the following IP, RRC_eNB, RRC_UE, PDCP, RLC_AM, RLC_UM, RLC_TM, MAC_eNB, MAC_UE, PHY g_messages = {}
g_entities_dic = {}
# This list is filled as follow : g_entities.append(protocol_entity)
# where protocol_entity is made with a entity name (IP, RRC_eNB, RRC_UE, PDCP, RLC_AM, ...) and '_'`module identifier` and
# optionnaly '_'`radio bearer identifier` or any other identifier(s)
# examples: RLC_AM_02_03, RRC_eNB_00
g_entities = []
# g_messages is filled with dictionnaries:
# message_dic['entity_src'] = protocol_entity_src
# message_dic['entity_dst'] = protocol_entity_dest
# message_dic['msg'] = message
# message_dic['line_color'] = g_display_color[entity_name]
# message_dic['text_color'] = g_display_color[entity_name]
# message_dic['time'] = system_frame_number
# message_dic['seq_no'] = sequence_number_generator()
# g_messages.append(message_dic)
g_messages = []
# g_display_order_dic is a dictionnary where the order of the display of entities sharing the same module identifier is hardcoded
#MAC and PHY valus have to be above num max radio bearer value
g_display_order_dic = {'IP': 0, 'RRC_eNB': 1, 'RRC_UE': 1, 'PDCP': 32, 'RLC_AM': 33, 'RLC_UM': 33, 'RLC_TM': 33, 'MAC_eNB': 1024, 'MAC_UE': 1024, 'PHY_UE': 2048, 'PHY_eNB': 2048}
# Display color of messages of sending entities # Display color of messages of sending entities
g_display_color = {'IP': '\"teal\"', g_display_color = ['\"teal\"',
'RRC_UE': '\"red\"', '\"red\"',
'RRC_eNB': '\"red\"', '\"red\"',
'PDCP': '\"blue\"', '\"blue\"',
'RLC_AM': '\"navy\"', '\"navy\"',
'RLC_UM': '\"navy\"', '\"navy\"',
'RLC_TM': '\"navy\"', '\"navy\"',
'MAC_UE': '\"indigo\"', '\"indigo\"',
'MAC_eNB': '\"indigo\"', '\"indigo\"',
'PHY_eNB': '\"indigo\"', '\"indigo\"',
'PHY_UE': '\"purple\"'} '\"purple\"']
g_final_display_order_list = []
g_sequence_generator = 0 g_sequence_generator = 0
...@@ -89,260 +53,107 @@ def sequence_number_generator(): ...@@ -89,260 +53,107 @@ def sequence_number_generator():
return l_seq return l_seq
# The aim of this procedure is to find the entity_type_name for the parsing part of code treating 'messages' or 'boxes'
# from whatever is the name of the protocol entity (RLC, RLC_AM, RLC_UM_03_02) all string identifying this protocol entity
# are returned.
# This has been written because for example when the RRC send a message to a RLC entity, it may not know if it is for a UM, AM, or TM
def getEntityNames( entity_name = 'unknown', module_id = -1, other_id = -1):
global g_entities_dic
print ("## getEntityNames( entity_name %s module_id %d other_id %d)" % (entity_name , module_id, other_id))
entity_main_name = entity_name.partition('_')[0]
for entity_name in g_entities_dic[module_id][other_id].iterkeys():
if entity_name.count(entity_main_name) > 0:
return g_entities_dic[module_id][other_id][entity_name]
print ("## WARNING getEntityNames( entity_name %s module_id %d other_id %d) UNKNOWN" % (entity_name , module_id, other_id)) def parse_oai_log_files():
return {}
def is_entity_declared( entity_name = 'unknown', module_id = -1, other_id = -1):
return 0
def parse_oai_log_file():
global g_entities_dic global g_entities_dic
global g_entities global g_entities
global g_messages global g_messages
global g_final_display_order_list global g_final_display_order_list
#open TXT file that contain OAI filtered traces for mscgen #open TXT file that contain OAI filtered traces for mscgen
fhandle = open(sys.argv[1], 'r') filenames = [
fcontent = fhandle.read() '/tmp/openair.msc.gtpu_enb.log',
fhandle.close() '/tmp/openair.msc.mac_enb.log',
'/tmp/openair.msc.mac_ue.log',
# split file content in lines '/tmp/openair.msc.nas_ue.log',
lines = fcontent.splitlines() '/tmp/openair.msc.pdcp_enb.log',
for line in lines: '/tmp/openair.msc.pdcp_ue.log',
system_frame_number = 'unknown' '/tmp/openair.msc.phy_enb.log',
message = 'unknown' '/tmp/openair.msc.phy_ue.log',
'/tmp/openair.msc.rlc_enb.log',
module_id = 'unknown' '/tmp/openair.msc.rlc_ue.log',
radio_bearer_id = '-1' '/tmp/openair.msc.rrc_enb.log',
protocol_entity_src = 'unknown' '/tmp/openair.msc.rrc_ue.log',
entity_name_src = 'unknown' '/tmp/openair.msc.s1ap_enb.log']
entity_name_main_src = 'unknown' for filename in filenames:
entity_name_type_src = 'unknown' fhandle = open(filename, 'r')
entity_tuple_name_src = 'unknown' fcontent = fhandle.read()
fhandle.close()
module_id_dest = 'unknown'
radio_bearer_id_dest = '-1' # split file content in lines
protocol_entity_dest = 'unknown' lines = fcontent.splitlines()
entity_name_dest = 'unknown' for line in lines:
entity_name_main_dest = 'unknown' print ("INPUT LINE: %s " % line)
entity_name_type_dest = 'unknown' partition = line.split(' ',3)
entity_tuple_name_dest= 'unknown' event_id = int(partition[0])
event_type = partition[1]
print ("INPUT LINE: %s " % line) entity_id = int(partition[2])
# if line is a trace of the creation of a new protocol instance if MSC_NEW_STR == event_type:
if MSC_NEW_STR in line: entity_name = partition[3]
partition = line.rpartition(MSC_NEW_STR) if len(g_proto_names) < (entity_id +1):
msc_log_string = partition[2] for i in range(len(g_proto_names),(entity_id +1)):
print (" %s " % msc_log_string) g_proto_names.append(None)
partition = msc_log_string.split('[') g_proto_names[entity_id] = entity_name
#print ("\n\n %s \n" % partition)
if len(partition) == 5: # if line is a trace of a message between 2 protocol entities or layers
elif MSC_MSG_STR == event_type:
for item in partition: print ("partition[3]:%s" % partition[3])
item = item.strip() sub_partition = partition[3].split(' ',4)
item = item.strip(']') arrow = sub_partition[0]
entity2_id = int(sub_partition[1])
if SYSTEM_FRAME_NUMBER_STR in item: mac = int(sub_partition[2])
system_frame_number = item.split(' ')[-1] time = sub_partition[3]
message = sub_partition[4]
elif MODULE_STR in item: Message = {}
module_id = item.split(' ')[-1] Message['mac'] = mac
Message['time'] = time
elif RADIO_BEARER_STR in item: Message['message'] = message
radio_bearer_id = item.split(' ')[-1] Message['line_color'] = g_display_color[entity_id]
Message['text_color'] = g_display_color[entity_id]
elif item != '': if arrow == '<-':
entity_name_src = item Message['type'] = "rx"
entity_partition = item.partition('_') Message['tx'] = entity2_id
entity_name_main_src = entity_partition[0] Message['rx'] = entity_id
entity_name_type_src = entity_partition[2] Message['discarded'] = False
g_messages[event_id] = Message
if radio_bearer_id == '': elif arrow == '->':
radio_bearer_id = '-1' Message['type'] = "tx"
Message['tx'] = entity_id
if radio_bearer_id == '-1': Message['rx'] = entity2_id
protocol_entity_src = entity_name_src+'_'+str(int(module_id)) Message['discarded'] = False
else: g_messages[event_id] = Message
protocol_entity_src = entity_name_src+'_'+str(int(module_id))+'_'+str(int(radio_bearer_id)) elif arrow == 'x-':
Message['type'] = "rx"
#print ("\n\nprotocol_entity = %s " % protocol_entity) Message['tx'] = entity2_id
module_id_int = int(module_id) Message['rx'] = entity_id
radio_bearer_id_int = int(radio_bearer_id) Message['discarded'] = True
g_messages[event_id] = Message
if module_id_int not in g_entities_dic: elif arrow == '-x':
g_entities_dic[module_id_int] = {} Message['type'] = "tx"
if radio_bearer_id_int not in g_entities_dic[module_id_int]: Message['tx'] = entity_id
g_entities_dic[module_id_int][radio_bearer_id_int] = {} Message['rx'] = entity2_id
Message['discarded'] = True
protocol_entity_dic = {} g_messages[event_id] = Message
protocol_entity_dic['full_name'] = protocol_entity_src
protocol_entity_dic['name_main'] = entity_name_main_src elif MSC_BOX_STR == event_type:
protocol_entity_dic['name_type'] = entity_name_type_src message = partition[3]
protocol_entity_dic['creation_time'] = system_frame_number Message = {}
g_entities_dic[module_id_int][radio_bearer_id_int][protocol_entity_src] = protocol_entity_dic Message['type'] = "box"
#print (" g_entities_dic[%d][%d].append(%s)" % (module_id_int, radio_bearer_id_int, entity_name_src)) Message['tx'] = entity_id
#print (" g_entities_dic= %s\n\n" % (g_entities_dic)) Message['rx'] = entity_id
Message['discarded'] = False
g_entities.append(protocol_entity_src) Message['mac'] = mac
#print (" %s \n" % protocol_entity) Message['time'] = time
Message['message'] = message
Message['line_color'] = g_display_color[entity_id]
# if line is a trace of a message between 2 protocol entities or layers Message['text_color'] = g_display_color[entity_id]
elif MSC_MSG_STR in line: g_messages[event_id] = Message
partition = line.strip().rpartition(MSC_MSG_STR)
msc_log_string = partition[2].strip()
print (" %s " % msc_log_string)
partition = msc_log_string.split('[')
print (" %s " % partition)
if len(partition) == 9:
system_frame_number = partition[1].strip().split(' ')[-1].strip(']')
module_id = partition[3].strip().split(' ')[-1].strip(']')
radio_bearer_id = partition[4].strip().split(' ')[-1].strip(']').strip()
if radio_bearer_id == '':
radio_bearer_id = '-1'
entity_name_src = partition[2].strip().split(' ')[-1].strip(']')
print ("entity_name_src = %s " % entity_name_src)
entity_dic = getEntityNames(entity_name_src, int(module_id), int(radio_bearer_id))
protocol_entity_src = entity_dic['full_name']
entity_name_main_src = entity_dic['name_main']
entity_name_type_src = entity_dic['name_type']
if entity_name_type_src != '':
entity_tuple_name_src = entity_name_main_src + '_' + entity_name_type_src
else:
entity_tuple_name_src = entity_name_main_src
message = partition[5].strip().strip(']').strip('<').strip('>').strip('-')
module_id_dest = partition[7].strip().split(' ')[-1].strip(']')
radio_bearer_id_dest = partition[8].strip().split(' ')[-1].strip(']')
if radio_bearer_id_dest == '':
radio_bearer_id_dest = '-1'
entity_name_dest = partition[6].strip().split(' ')[-1].strip(']')
entity_dic = getEntityNames(entity_name_dest, int(module_id_dest), int(radio_bearer_id_dest))
protocol_entity_dest = entity_dic['full_name']
entity_name_main_dest = entity_dic['name_main']
entity_name_type_dest = entity_dic['name_type']
message_dic = {}
#print ('%s' % protocol_entity)
print ('entity_tuple_name_src %s' % entity_tuple_name_src)
message_dic['entity_src'] = protocol_entity_src
message_dic['entity_dst'] = protocol_entity_dest
message_dic['msg'] = message
message_dic['line_color'] = g_display_color[entity_tuple_name_src]
message_dic['text_color'] = g_display_color[entity_tuple_name_src]
message_dic['time'] = system_frame_number
message_dic['seq_no'] = sequence_number_generator()
#print ('%s' % message_dic)
g_messages.append(message_dic)
# if line is a trace of an information to be displayed for 1 or more protocol entities
elif MSC_NBOX_STR in line :
partition = line.strip().rpartition(MSC_NBOX_STR)
msc_log_string = partition[2].strip()
partition = msc_log_string.split('[')
if len(partition) == 9:
system_frame_number = partition[1].strip().split(' ')[-1].strip(']')
module_id = partition[3].strip().split(' ')[-1].strip(']')
radio_bearer_id = partition[4].strip().split(' ')[-1].strip(']').strip()
if radio_bearer_id == '':
radio_bearer_id = '-1'
entity_name_src = partition[2].strip().split(' ')[-1].strip(']')
entity_dic = getEntityNames(entity_name_src, int(module_id), int(radio_bearer_id))
protocol_entity_src = entity_dic['full_name']
entity_name_main_src = entity_dic['name_main']
entity_name_type_src = entity_dic['name_type']
if entity_name_type_src != '':
entity_tuple_name_src = entity_name_main_src + '_' + entity_name_type_src
else:
entity_tuple_name_src = entity_name_main_src
box = partition[5].strip().strip(']')
module_id_dest = partition[7].strip().split(' ')[-1].strip(']')
radio_bearer_id_dest = partition[8].strip().split(' ')[-1].strip(']')
if radio_bearer_id_dest == '':
radio_bearer_id_dest = '-1'
entity_name_dest = partition[6].strip().split(' ')[-1].strip(']')
entity_dic = getEntityNames(entity_name_dest, int(module_id_dest), int(radio_bearer_id_dest))
protocol_entity_dest = entity_dic['full_name']
entity_name_main_dest = entity_dic['name_main']
entity_name_type_dest = entity_dic['name_type']
message_dic = {}
#print ('%s' % protocol_entity)
message_dic['entity_src'] = protocol_entity_src
message_dic['entity_dst'] = protocol_entity_dest
message_dic['box'] = box
#note does not work
message_dic['box_type'] = 'rbox'
message_dic['text_color'] = '\"#000000\"'
message_dic['textbg_color'] = g_display_color[entity_tuple_name_src]
message_dic['time'] = system_frame_number
message_dic['seq_no'] = sequence_number_generator()
#print ('%s' % message_dic)
g_messages.append(message_dic)
#print("------------------------------------") #print("------------------------------------")
#print (" %s " % ( g_entities_dic ) ) #print (" %s " % ( g_messages ) )
for module_id_int in sorted(g_entities_dic.iterkeys()): # for event_id_int in sorted(g_messages.iterkeys()):
module_display_order_dic = {}
for radio_bearer_id_int in sorted(g_entities_dic[module_id_int].iterkeys()):
for entity_name in g_entities_dic[module_id_int][radio_bearer_id_int]:
entity_main_name = g_entities_dic[module_id_int][radio_bearer_id_int][entity_name]['name_main']
entity_type_name = g_entities_dic[module_id_int][radio_bearer_id_int][entity_name]['name_type']
if entity_type_name != '':
entity_tuple_name = entity_main_name + '_' + entity_type_name
else:
entity_tuple_name = entity_main_name
#print (" entity_name = %s entity_main_name = %s module_id_int=%d" % ( entity_name, entity_main_name, module_id_int) )
if radio_bearer_id_int < 0:
module_display_order_dic[g_display_order_dic[entity_tuple_name]] = entity_name
else:
module_display_order_dic[g_display_order_dic[entity_tuple_name]*(radio_bearer_id_int+1)] = entity_name
#print("------------------------------------")
#print(" %s " % (module_display_order_dic))
for display_priority in sorted(module_display_order_dic.iterkeys()):
g_final_display_order_list.append(module_display_order_dic[display_priority])
#print("------------------------------------")
#print(" %s;" % (g_final_display_order_list))
def msc_chart_write_header(fileP): def msc_chart_write_header(fileP):
...@@ -351,7 +162,7 @@ def msc_chart_write_header(fileP): ...@@ -351,7 +162,7 @@ def msc_chart_write_header(fileP):
fileP.write("width = \"2048\";\n") fileP.write("width = \"2048\";\n")
entity_line_list_str = '' entity_line_list_str = ''
for entity in g_final_display_order_list: for entity in g_proto_names:
entity_line_list_str = entity_line_list_str + ' ' + entity + ',' entity_line_list_str = entity_line_list_str + ' ' + entity + ','
entity_line_list_str = entity_line_list_str.rstrip().strip(',') entity_line_list_str = entity_line_list_str.rstrip().strip(',')
...@@ -369,7 +180,7 @@ def msc_chart_generate(file_nameP): ...@@ -369,7 +180,7 @@ def msc_chart_generate(file_nameP):
for i in fe.readlines(): for i in fe.readlines():
print "error:",i print "error:",i
def get_nem_file_descriptor(): def get_new_file_descriptor():
global g_base_file_name global g_base_file_name
global g_page_index global g_page_index
l_file_name = g_base_file_name + str(g_page_index)+'.txt' l_file_name = g_base_file_name + str(g_page_index)+'.txt'
...@@ -378,7 +189,7 @@ def get_nem_file_descriptor(): ...@@ -378,7 +189,7 @@ def get_nem_file_descriptor():
###### MAIN STAR HERE ################# ###### MAIN STAR HERE #################
parse_oai_log_file() parse_oai_log_files()
g_page_index = 0 g_page_index = 0
g_message_index = 0 g_message_index = 0
...@@ -391,16 +202,18 @@ os.chdir(g_resultdir) ...@@ -391,16 +202,18 @@ os.chdir(g_resultdir)
g_base_file_name = 'oai_mscgen_page_' g_base_file_name = 'oai_mscgen_page_'
g_file = get_nem_file_descriptor() g_file = get_new_file_descriptor()
msc_chart_write_header(g_file) msc_chart_write_header(g_file)
for message in g_messages: for event_id_int in sorted(g_messages.iterkeys()):
#for message in g_messages:
if 'msg' in message: message = g_messages[event_id_int]
g_file.write(" %s=>%s [ label = \"(%d) Frm%s %s\", linecolour=%s , textcolour=%s ] ;\n" % (message['entity_src'], message['entity_dst'], message['seq_no'], message['time'], message['msg'], message['line_color'], message['text_color'])) if 'tx' in message['type']:
elif 'box' in message: g_file.write(" %s=>%s [ label = \"(%d|%s) %s\", linecolour=%s , textcolour=%s ] ;\n" % (g_proto_names[message['tx']], g_proto_names[message['rx']], event_id_int, message['time'], message['message'], message['line_color'], message['text_color']))
#g_file.write(" %s %s %s [ label = \"%s\", textbgcolour=%s , textcolour=%s ] ;\n" % (message['entity_src'], message['box_type'], message['entity_dst'], message['box'], message['textbg_color'], message['text_color'])) elif 'rx' in message['type']:
g_file.write(" %s %s %s [ label = \"%s\", textcolour=%s ] ;\n" % (message['entity_src'], message['box_type'], message['entity_dst'], message['box'], message['text_color'])) g_file.write(" %s<=%s [ label = \"(%d|%s) %s\", linecolour=%s , textcolour=%s ] ;\n" % (g_proto_names[message['rx']], g_proto_names[message['tx']], event_id_int, message['time'], message['message'], message['line_color'], message['text_color']))
elif 'box' in message['type']:
g_file.write(" %s note %s [ label = \"%s\", textcolour=%s ] ;\n" % (g_proto_names[message['tx']], g_proto_names[message['rx']], message['message'], message['text_color']))
g_message_index = g_message_index + 1 g_message_index = g_message_index + 1
...@@ -410,7 +223,7 @@ for message in g_messages: ...@@ -410,7 +223,7 @@ for message in g_messages:
msc_chart_generate(g_file.name) msc_chart_generate(g_file.name)
g_page_index = g_page_index + 1 g_page_index = g_page_index + 1
g_file = get_nem_file_descriptor() g_file = get_new_file_descriptor()
msc_chart_write_header(g_file) msc_chart_write_header(g_file)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment