diff --git a/targets/SCRIPTS/msc_gen.py b/targets/SCRIPTS/msc_gen.py index 2fea2a2b84ff698d84e84516c15d391ac8b93860..4d45677cff0e92762dda1d364a9fed32e8a71c2d 100755 --- a/targets/SCRIPTS/msc_gen.py +++ b/targets/SCRIPTS/msc_gen.py @@ -1,21 +1,7 @@ #!/usr/bin/python # -*- 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). -# 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. +# The aim of this script is to collect some traces from oai stack and generate a sequence diagram image (png or jpeg). import sys @@ -29,56 +15,34 @@ from datetime import date MSCGEN_OUTPUT_TYPE = "png" MAX_MESSAGES_PER_PAGE = 36 -SYSTEM_FRAME_NUMBER_STR = 'FRAME' -MODULE_STR = 'MOD' -RADIO_BEARER_STR = 'RB' -MSC_NEW_STR = '[MSC_NEW]' -MSC_MSG_STR = '[MSC_MSG]' -MSC_NBOX_STR = '[MSC_NBOX]' -MSC_BOX_STR = '[MSC_BOX]' -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) -# 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_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} +MSC_NEW_STR = '[PROTO]' +MSC_MSG_STR = '[MESSAGE]' +MSC_BOX_STR = '[EVENT]' + + +# This list is filled as follow : g_proto_names[module_id_int] = (proto_name) +g_proto_names = [] + + + +# list of messages +g_messages = {} + # Display color of messages of sending entities -g_display_color = {'IP': '\"teal\"', - 'RRC_UE': '\"red\"', - 'RRC_eNB': '\"red\"', - 'PDCP': '\"blue\"', - 'RLC_AM': '\"navy\"', - 'RLC_UM': '\"navy\"', - 'RLC_TM': '\"navy\"', - 'MAC_UE': '\"indigo\"', - 'MAC_eNB': '\"indigo\"', - 'PHY_eNB': '\"indigo\"', - 'PHY_UE': '\"purple\"'} +g_display_color = ['\"teal\"', + '\"red\"', + '\"red\"', + '\"blue\"', + '\"navy\"', + '\"navy\"', + '\"navy\"', + '\"indigo\"', + '\"indigo\"', + '\"indigo\"', + '\"purple\"'] -g_final_display_order_list = [] g_sequence_generator = 0 @@ -89,260 +53,107 @@ def sequence_number_generator(): 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)) - - return {} - - -def is_entity_declared( entity_name = 'unknown', module_id = -1, other_id = -1): - return 0 - - -def parse_oai_log_file(): +def parse_oai_log_files(): global g_entities_dic global g_entities global g_messages global g_final_display_order_list #open TXT file that contain OAI filtered traces for mscgen - fhandle = open(sys.argv[1], 'r') - fcontent = fhandle.read() - fhandle.close() - - # split file content in lines - lines = fcontent.splitlines() - for line in lines: - system_frame_number = 'unknown' - message = 'unknown' - - module_id = 'unknown' - radio_bearer_id = '-1' - protocol_entity_src = 'unknown' - entity_name_src = 'unknown' - entity_name_main_src = 'unknown' - entity_name_type_src = 'unknown' - entity_tuple_name_src = 'unknown' - - module_id_dest = 'unknown' - radio_bearer_id_dest = '-1' - protocol_entity_dest = 'unknown' - entity_name_dest = 'unknown' - entity_name_main_dest = 'unknown' - entity_name_type_dest = 'unknown' - entity_tuple_name_dest= 'unknown' - - print ("INPUT LINE: %s " % line) - # if line is a trace of the creation of a new protocol instance - if MSC_NEW_STR in line: - partition = line.rpartition(MSC_NEW_STR) - msc_log_string = partition[2] - print (" %s " % msc_log_string) - partition = msc_log_string.split('[') - #print ("\n\n %s \n" % partition) - if len(partition) == 5: - - for item in partition: - item = item.strip() - item = item.strip(']') - - if SYSTEM_FRAME_NUMBER_STR in item: - system_frame_number = item.split(' ')[-1] - - elif MODULE_STR in item: - module_id = item.split(' ')[-1] - - elif RADIO_BEARER_STR in item: - radio_bearer_id = item.split(' ')[-1] - - elif item != '': - entity_name_src = item - entity_partition = item.partition('_') - entity_name_main_src = entity_partition[0] - entity_name_type_src = entity_partition[2] - - if radio_bearer_id == '': - radio_bearer_id = '-1' - - if radio_bearer_id == '-1': - protocol_entity_src = entity_name_src+'_'+str(int(module_id)) - else: - protocol_entity_src = entity_name_src+'_'+str(int(module_id))+'_'+str(int(radio_bearer_id)) - - #print ("\n\nprotocol_entity = %s " % protocol_entity) - module_id_int = int(module_id) - radio_bearer_id_int = int(radio_bearer_id) - - if module_id_int not in g_entities_dic: - g_entities_dic[module_id_int] = {} - if radio_bearer_id_int not in g_entities_dic[module_id_int]: - g_entities_dic[module_id_int][radio_bearer_id_int] = {} - - protocol_entity_dic = {} - protocol_entity_dic['full_name'] = protocol_entity_src - protocol_entity_dic['name_main'] = entity_name_main_src - protocol_entity_dic['name_type'] = entity_name_type_src - protocol_entity_dic['creation_time'] = system_frame_number - g_entities_dic[module_id_int][radio_bearer_id_int][protocol_entity_src] = protocol_entity_dic - #print (" g_entities_dic[%d][%d].append(%s)" % (module_id_int, radio_bearer_id_int, entity_name_src)) - #print (" g_entities_dic= %s\n\n" % (g_entities_dic)) - - g_entities.append(protocol_entity_src) - #print (" %s \n" % protocol_entity) - - - # if line is a trace of a message between 2 protocol entities or layers - elif MSC_MSG_STR in line: - 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) + filenames = [ + '/tmp/openair.msc.gtpu_enb.log', + '/tmp/openair.msc.mac_enb.log', + '/tmp/openair.msc.mac_ue.log', + '/tmp/openair.msc.nas_ue.log', + '/tmp/openair.msc.pdcp_enb.log', + '/tmp/openair.msc.pdcp_ue.log', + '/tmp/openair.msc.phy_enb.log', + '/tmp/openair.msc.phy_ue.log', + '/tmp/openair.msc.rlc_enb.log', + '/tmp/openair.msc.rlc_ue.log', + '/tmp/openair.msc.rrc_enb.log', + '/tmp/openair.msc.rrc_ue.log', + '/tmp/openair.msc.s1ap_enb.log'] + for filename in filenames: + fhandle = open(filename, 'r') + fcontent = fhandle.read() + fhandle.close() + + # split file content in lines + lines = fcontent.splitlines() + for line in lines: + print ("INPUT LINE: %s " % line) + partition = line.split(' ',3) + event_id = int(partition[0]) + event_type = partition[1] + entity_id = int(partition[2]) + if MSC_NEW_STR == event_type: + entity_name = partition[3] + if len(g_proto_names) < (entity_id +1): + for i in range(len(g_proto_names),(entity_id +1)): + g_proto_names.append(None) + g_proto_names[entity_id] = entity_name + + # if line is a trace of a message between 2 protocol entities or layers + elif MSC_MSG_STR == event_type: + print ("partition[3]:%s" % partition[3]) + sub_partition = partition[3].split(' ',4) + arrow = sub_partition[0] + entity2_id = int(sub_partition[1]) + mac = int(sub_partition[2]) + time = sub_partition[3] + message = sub_partition[4] + Message = {} + Message['mac'] = mac + Message['time'] = time + Message['message'] = message + Message['line_color'] = g_display_color[entity_id] + Message['text_color'] = g_display_color[entity_id] + if arrow == '<-': + Message['type'] = "rx" + Message['tx'] = entity2_id + Message['rx'] = entity_id + Message['discarded'] = False + g_messages[event_id] = Message + elif arrow == '->': + Message['type'] = "tx" + Message['tx'] = entity_id + Message['rx'] = entity2_id + Message['discarded'] = False + g_messages[event_id] = Message + elif arrow == 'x-': + Message['type'] = "rx" + Message['tx'] = entity2_id + Message['rx'] = entity_id + Message['discarded'] = True + g_messages[event_id] = Message + elif arrow == '-x': + Message['type'] = "tx" + Message['tx'] = entity_id + Message['rx'] = entity2_id + Message['discarded'] = True + g_messages[event_id] = Message + + elif MSC_BOX_STR == event_type: + message = partition[3] + Message = {} + Message['type'] = "box" + Message['tx'] = entity_id + Message['rx'] = entity_id + Message['discarded'] = False + Message['mac'] = mac + Message['time'] = time + Message['message'] = message + Message['line_color'] = g_display_color[entity_id] + Message['text_color'] = g_display_color[entity_id] + g_messages[event_id] = Message + + #print("------------------------------------") - #print (" %s " % ( g_entities_dic ) ) - - for module_id_int in sorted(g_entities_dic.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 (" %s " % ( g_messages ) ) + +# for event_id_int in sorted(g_messages.iterkeys()): - #print("------------------------------------") - #print(" %s;" % (g_final_display_order_list)) def msc_chart_write_header(fileP): @@ -351,7 +162,7 @@ def msc_chart_write_header(fileP): fileP.write("width = \"2048\";\n") 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.rstrip().strip(',') @@ -369,7 +180,7 @@ def msc_chart_generate(file_nameP): for i in fe.readlines(): print "error:",i -def get_nem_file_descriptor(): +def get_new_file_descriptor(): global g_base_file_name global g_page_index l_file_name = g_base_file_name + str(g_page_index)+'.txt' @@ -378,7 +189,7 @@ def get_nem_file_descriptor(): ###### MAIN STAR HERE ################# -parse_oai_log_file() +parse_oai_log_files() g_page_index = 0 g_message_index = 0 @@ -391,16 +202,18 @@ os.chdir(g_resultdir) 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) -for message in g_messages: - - if 'msg' in message: - 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'])) - elif 'box' in message: - #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'])) - 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'])) +for event_id_int in sorted(g_messages.iterkeys()): +#for message in g_messages: + message = g_messages[event_id_int] + if 'tx' in message['type']: + 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'])) + elif 'rx' in message['type']: + 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 @@ -410,7 +223,7 @@ for message in g_messages: msc_chart_generate(g_file.name) 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)