Beispiel #1
0
def find_retx_within_a_range(QCATEntries, startIndex, endIndex, direction):
    tot_rlc_count = rw.initFullRRCMap(0.0)
    retx_rlc_count = rw.initFullRRCMap(0.0)
    # method 2
    exist_sn_set = set([])
    for index in range(startIndex, endIndex + 1):
        cur_entry = QCATEntries[index]
        if cur_entry.logID == const.UL_PDU_ID or \
           cur_entry.logID == const.DL_PDU_ID:
            cur_rrcID = cur_entry.rrcID
            cur_rlc_pdus = cur_entry.ul_pdu[0]
            if direction.lower() == "down":
                cur_rlc_pdus = cur_entry.dl_pdu[0]

            if cur_rrcID:
                # check current sequence number
                for sn in cur_rlc_pdus["sn"]:
                    if sn in exist_sn_set:
                        retx_rlc_count[cur_rrcID] += 1
                    else:
                        exist_sn_set.add(sn)
                    tot_rlc_count[cur_rrcID] += 1

    ratio = 0.0
    total_sum = float(sum(tot_rlc_count.values()))
    retx_sum = float(sum(retx_rlc_count.values()))
    if total_sum > 0.0:
        ratio = retx_sum / total_sum
        # ratio = retx_sum

    return tot_rlc_count, retx_rlc_count, ratio, total_sum
Beispiel #2
0
def UDP_loss_stats(QCATEntries, udp_clt_lookup_table, udp_srv_lookup_table,
                   hash_target, srv_ip):
    # Statistic result
    udp_loss_per_rrc_map = rw.initFullRRCMap(0.0)
    udp_total_per_rrc_map = rw.initFullRRCMap(0.0)
    udp_srv_fail_recv_list = []  # list of UDP dropped over the internet
    udp_clt_fail_log_list = []

    # parse each UDP entry to check whether if appears on the server side table
    # use server ip to script the direction
    for hash_key, indexList in udp_clt_lookup_table.items():
        for entryIndex in indexList:
            cur_entry = QCATEntries[entryIndex]
            # count the src UDP packet
            udp_total_per_rrc_map[cur_entry.rrcID] += 1
            if not udp_srv_lookup_table.has_key(hash_key):
                udp_loss_per_rrc_map[cur_entry.rrcID] += 1
                udp_srv_fail_recv_list.append(entryIndex)

    # reverse map server side to the client side to check whether mis-log
    for hash_key in udp_srv_lookup_table.keys():
        if not udp_clt_lookup_table.has_key(hash_key):
            udp_clt_fail_log_list.append(hash_key)

    return udp_loss_per_rrc_map, udp_total_per_rrc_map, udp_srv_fail_recv_list, udp_clt_fail_log_list
def find_retx_within_a_range(QCATEntries, startIndex, endIndex, direction):
    tot_rlc_count = rw.initFullRRCMap(0.0)
    retx_rlc_count = rw.initFullRRCMap(0.0)
    # method 2
    exist_sn_set = set([])
    for index in range(startIndex, endIndex+1):
        cur_entry = QCATEntries[index]
        if cur_entry.logID == const.UL_PDU_ID or \
           cur_entry.logID == const.DL_PDU_ID:
            cur_rrcID = cur_entry.rrcID
            cur_rlc_pdus = cur_entry.ul_pdu[0]
            if direction.lower() == "down":
                cur_rlc_pdus = cur_entry.dl_pdu[0]
            
            if cur_rrcID:
                # check current sequence number
                for sn in cur_rlc_pdus["sn"]:
                    if sn in exist_sn_set:
                        retx_rlc_count[cur_rrcID] += 1
                    else:
                        exist_sn_set.add(sn)
                    tot_rlc_count[cur_rrcID] += 1

    ratio = 0.0
    total_sum = float(sum(tot_rlc_count.values()))
    retx_sum = float(sum(retx_rlc_count.values()))
    if total_sum > 0.0:
        ratio = retx_sum / total_sum
        # ratio = retx_sum
    
    return tot_rlc_count, retx_rlc_count, ratio, total_sum
def UDP_loss_stats (QCATEntries, udp_clt_lookup_table, udp_srv_lookup_table, hash_target, srv_ip):
    # Statistic result
    udp_loss_per_rrc_map = rw.initFullRRCMap(0.0)
    udp_total_per_rrc_map = rw.initFullRRCMap(0.0)
    udp_srv_fail_recv_list = []  # list of UDP dropped over the internet
    udp_clt_fail_log_list = []

    # parse each UDP entry to check whether if appears on the server side table
    # use server ip to script the direction
    for hash_key, indexList in udp_clt_lookup_table.items():
        for entryIndex in indexList:
            cur_entry = QCATEntries[entryIndex]
            # count the src UDP packet
            udp_total_per_rrc_map[cur_entry.rrcID] += 1
            if not udp_srv_lookup_table.has_key(hash_key):
                udp_loss_per_rrc_map[cur_entry.rrcID] += 1
                udp_srv_fail_recv_list.append(entryIndex)

    # reverse map server side to the client side to check whether mis-log 
    for hash_key in udp_srv_lookup_table.keys():
        if not udp_clt_lookup_table.has_key(hash_key):
            udp_clt_fail_log_list.append(hash_key)

    return udp_loss_per_rrc_map, udp_total_per_rrc_map, udp_srv_fail_recv_list, udp_clt_fail_log_list
def cal_UDP_RTT_per_state (QCATEntries, direction, clt_up_table, clt_down_table):
    udp_rtt_per_state = rw.initFullRRCMap(0.0)
    for k in udp_rtt_per_state:
        udp_rtt_per_state[k] = []

    lookup_table = clt_up_table
    if direction.lower() != "up":
        lookup_table = clt_down_table

    for index_list in lookup_table.values():
        for index in index_list:
            cur_entry = QCATEntries[index]
            if cur_entry.rrcID and cur_entry.rtt["udp"] and cur_entry.rtt["udp"] > 0:
                udp_rtt_per_state[cur_entry.rrcID].append(cur_entry.rtt["udp"])

    return udp_rtt_per_state    
Beispiel #6
0
def cal_UDP_RTT_per_state(QCATEntries, direction, clt_up_table,
                          clt_down_table):
    udp_rtt_per_state = rw.initFullRRCMap(0.0)
    for k in udp_rtt_per_state:
        udp_rtt_per_state[k] = []

    lookup_table = clt_up_table
    if direction.lower() != "up":
        lookup_table = clt_down_table

    for index_list in lookup_table.values():
        for index in index_list:
            cur_entry = QCATEntries[index]
            if cur_entry.rrcID and cur_entry.rtt[
                    "udp"] and cur_entry.rtt["udp"] > 0:
                udp_rtt_per_state[cur_entry.rrcID].append(cur_entry.rtt["udp"])

    return udp_rtt_per_state
Beispiel #7
0
def get_gap_to_rtt_map(QCATEntries):
    gap_rtt_per_rrc_map = {}
    gap_rtt_list_map = {}
    index = 0
    entry_length = len(QCATEntries)

    while index < entry_length:
        cur_entry = QCATEntries[index]
        cur_gap = cur_entry.udp["gap"]

        if cur_entry.ip["tlp_id"] == const.UDP_ID and cur_gap >= 0:
            # find the last gap_period message
            last_map_index = find_last_same_gap_entry_index(
                QCATEntries, index, cur_gap)

            # update the RTT map table
            for temp_index in range(index, last_map_index + 1):
                temp_entry = QCATEntries[temp_index]
                cur_rtt = temp_entry.rtt["udp"]
                cur_rrc = temp_entry.rrcID
                # append to RTT list
                if cur_rtt:
                    if gap_rtt_list_map.has_key(cur_gap):
                        gap_rtt_list_map[cur_gap].append(cur_rtt)
                    else:
                        gap_rtt_list_map[cur_gap] = [cur_rtt]
                # update RRC map
                if cur_rrc:
                    if not gap_rtt_per_rrc_map.has_key(cur_gap):
                        gap_rtt_per_rrc_map[cur_gap] = rw.initFullRRCMap([])
                    gap_rtt_per_rrc_map[cur_gap][cur_rrc].append(cur_rtt)
            # leap the index
            index = last_map_index
        # update the index
        index += 1

    # display all the RTT timer
    if True:
        for k in sorted(gap_rtt_list_map.keys()):
            mean, stdev = util.meanStdevPair(gap_rtt_list_map[k])
            print "%f\t%f\t%f" % (k, mean, stdev)

    return gap_rtt_list_map, gap_rtt_per_rrc_map
def get_gap_to_rtt_map(QCATEntries):
    gap_rtt_per_rrc_map = {}
    gap_rtt_list_map = {}
    index = 0
    entry_length = len(QCATEntries)

    while index < entry_length:
        cur_entry = QCATEntries[index]
        cur_gap = cur_entry.udp["gap"]

        if cur_entry.ip["tlp_id"] == const.UDP_ID and cur_gap >= 0:
            # find the last gap_period message
            last_map_index = find_last_same_gap_entry_index(QCATEntries, index, cur_gap)
            
            # update the RTT map table
            for temp_index in range(index, last_map_index+1):
                temp_entry = QCATEntries[temp_index]
                cur_rtt = temp_entry.rtt["udp"]
                cur_rrc = temp_entry.rrcID
                # append to RTT list
                if cur_rtt:
                    if gap_rtt_list_map.has_key(cur_gap):
                        gap_rtt_list_map[cur_gap].append(cur_rtt)
                    else:
                        gap_rtt_list_map[cur_gap] = [cur_rtt]
                # update RRC map
                if cur_rrc:
                    if not gap_rtt_per_rrc_map.has_key(cur_gap):
                        gap_rtt_per_rrc_map[cur_gap] = rw.initFullRRCMap([])
                    gap_rtt_per_rrc_map[cur_gap][cur_rrc].append(cur_rtt)
            # leap the index
            index = last_map_index
        # update the index
        index += 1

    # display all the RTT timer
    if True:
        for k in sorted(gap_rtt_list_map.keys()):
            mean, stdev = util.meanStdevPair(gap_rtt_list_map[k])
            print "%f\t%f\t%f" % (k, mean, stdev)

    return gap_rtt_list_map, gap_rtt_per_rrc_map
Beispiel #9
0
def UDP_loss_cross_analysis(QCATEntries, loss_index_list, logID):
    # Loss over cellular network if
    # 1. exceeding max Retx count
    # 2. there is a reset PDU in between the mapped RLC list and the next control message
    udp_loss_in_cellular = {
        "reset": rw.initFullRRCMap(0.0),
        "max_retx": rw.initFullRRCMap(0.0)
    }
    udp_loss_in_internet = rw.initFullRRCMap(0.0)

    entry_len = len(QCATEntries)
    max_retx_count_overall = 0.0

    for loss_index in loss_index_list:
        cur_entry = QCATEntries[loss_index]
        mapped_rlc_tuple_list, mapped_sn_list = clw.cross_layer_mapping_WCDMA_uplink(
            QCATEntries, loss_index, logID)

        if mapped_rlc_tuple_list and cur_entry.rrcID:
            first_mapped_rlc_index = mapped_rlc_tuple_list[0][1]
            last_mapped_rlc_index = mapped_rlc_tuple_list[-1][1]
            first_mapped_rlc_sn = min(
                QCATEntries[first_mapped_rlc_index].ul_pdu[0]["sn"])
            last_mapped_rlc_sn = min(
                QCATEntries[last_mapped_rlc_index].ul_pdu[0]["sn"])

            max_tx_config = cur_entry.ul_config["max_tx"]
            next_ack_index = clw.findNextCtrlMsg(QCATEntries,
                                                 loss_index,
                                                 ctrl_type="ack",
                                                 cur_seq=last_mapped_rlc_sn)
            next_list_index = clw.findNextCtrlMsg(QCATEntries,
                                                  loss_index,
                                                  ctrl_type="list",
                                                  cur_seq=last_mapped_rlc_sn)

            ctrl_index = entry_len
            if next_ack_index:
                ctrl_index = min(next_ack_index, ctrl_index)
            if next_list_index:
                ctrl_index = min(next_list_index, ctrl_index)

            # check reset
            reset_index = clw.find_reset_ack(QCATEntries,
                                             last_mapped_rlc_index + 1,
                                             ctrl_index)
            # check for exceeding retx count
            rlc_tx_map = clw.find_SN_within_interval(
                QCATEntries, first_mapped_rlc_index + 1, ctrl_index)
            max_tx_count_num = 0
            if rlc_tx_map:
                max_tx_count_num = max([len(i) for i in rlc_tx_map.values()])
                if max_tx_count_num > max_retx_count_overall:
                    max_retx_count_overall = max_tx_count_num
            if reset_index:
                udp_loss_in_cellular["reset"][cur_entry.rrcID] += 1
                if DEBUG:
                    print "-------------- Detect Reset --------------"
            elif max_tx_config and max_tx_count_num >= max_tx_config:
                udp_loss_in_cellular["max_retx"][cur_entry.rrcID] += 1
                if DEBUG:
                    print "%%%%%%%%%%%% Max retx configued: ", max_tx_config
                    print "%%%%%%%%%%%% Cur retx configued: ", max_tx_count_num
            else:
                udp_loss_in_internet[cur_entry.rrcID] += 1
            """
            # print out retransmission over PCH promotion
            # investigate high PCH loss rate
            #if cur_entry.rrcID and cur_entry.rrcID == const.PCH_TO_FACH_ID:
            print "%"* 100
            print "%"* 40 + "Curious Case:" + "%"* 40
            pw.printUDPEntry(cur_entry)
            print "%"* 100
            print "%"* 100
            # find the lower bound of the range
            max_index = clw.find_nearest_status(QCATEntries, loss_index, max(mapped_sn_list))
            print "is max index correct %s" % (max_index > loss_index)
            target_sn_set = set(mapped_sn_list)
            dup_sn_map, rlc_tx_index_list = clw.loss_analysis_with_rlc_retx(QCATEntries, loss_index, max_index, target_sn_set)
            print "max # of retx is %d" % max([len(i) for i in dup_sn_map.values()])
            pw.print_loss_case(QCATEntries, loss_index, rlc_tx_index_list)
            """

    if CUR_DEBUG:
        print "Max RLC retx is ", max_retx_count_overall

    return udp_loss_in_cellular, udp_loss_in_internet
def UDP_loss_cross_analysis(QCATEntries, loss_index_list, logID):
    # Loss over cellular network if 
    # 1. exceeding max Retx count
    # 2. there is a reset PDU in between the mapped RLC list and the next control message
    udp_loss_in_cellular = {"reset": rw.initFullRRCMap(0.0), "max_retx": rw.initFullRRCMap(0.0)}
    udp_loss_in_internet = rw.initFullRRCMap(0.0)

    entry_len = len(QCATEntries)
    max_retx_count_overall = 0.0

    for loss_index in loss_index_list:
        cur_entry = QCATEntries[loss_index] 
        mapped_rlc_tuple_list, mapped_sn_list = clw.cross_layer_mapping_WCDMA_uplink(QCATEntries, loss_index, logID)
        
        if mapped_rlc_tuple_list and cur_entry.rrcID:
            first_mapped_rlc_index = mapped_rlc_tuple_list[0][1]
            last_mapped_rlc_index = mapped_rlc_tuple_list[-1][1]
            first_mapped_rlc_sn = min(QCATEntries[first_mapped_rlc_index].ul_pdu[0]["sn"])
            last_mapped_rlc_sn = min(QCATEntries[last_mapped_rlc_index].ul_pdu[0]["sn"])
            
            max_tx_config = cur_entry.ul_config["max_tx"]
            next_ack_index = clw.findNextCtrlMsg(QCATEntries, loss_index, ctrl_type = "ack", cur_seq = last_mapped_rlc_sn)
            next_list_index = clw.findNextCtrlMsg(QCATEntries, loss_index, ctrl_type = "list", cur_seq = last_mapped_rlc_sn)
            
            ctrl_index = entry_len
            if next_ack_index:
                ctrl_index = min(next_ack_index, ctrl_index)
            if next_list_index:
                ctrl_index = min(next_list_index, ctrl_index)
            
            # check reset
            reset_index = clw.find_reset_ack(QCATEntries, last_mapped_rlc_index + 1, ctrl_index)
            # check for exceeding retx count
            rlc_tx_map = clw.find_SN_within_interval(QCATEntries, first_mapped_rlc_index + 1, ctrl_index)
            max_tx_count_num = 0
            if rlc_tx_map:
                max_tx_count_num = max([len(i) for i in rlc_tx_map.values()])
                if max_tx_count_num > max_retx_count_overall:
                    max_retx_count_overall = max_tx_count_num
            if reset_index:
                udp_loss_in_cellular["reset"][cur_entry.rrcID] += 1
                if DEBUG:
                    print "-------------- Detect Reset --------------"
            elif max_tx_config and max_tx_count_num >= max_tx_config:
                udp_loss_in_cellular["max_retx"][cur_entry.rrcID] += 1
                if DEBUG:
                    print "%%%%%%%%%%%% Max retx configued: " , max_tx_config
                    print "%%%%%%%%%%%% Cur retx configued: " , max_tx_count_num
            else:
                udp_loss_in_internet[cur_entry.rrcID] += 1
           
            """
            # print out retransmission over PCH promotion
            # investigate high PCH loss rate
            #if cur_entry.rrcID and cur_entry.rrcID == const.PCH_TO_FACH_ID:
            print "%"* 100
            print "%"* 40 + "Curious Case:" + "%"* 40
            pw.printUDPEntry(cur_entry)
            print "%"* 100
            print "%"* 100
            # find the lower bound of the range
            max_index = clw.find_nearest_status(QCATEntries, loss_index, max(mapped_sn_list))
            print "is max index correct %s" % (max_index > loss_index)
            target_sn_set = set(mapped_sn_list)
            dup_sn_map, rlc_tx_index_list = clw.loss_analysis_with_rlc_retx(QCATEntries, loss_index, max_index, target_sn_set)
            print "max # of retx is %d" % max([len(i) for i in dup_sn_map.values()])
            pw.print_loss_case(QCATEntries, loss_index, rlc_tx_index_list)
            """

    if CUR_DEBUG:
        print "Max RLC retx is ", max_retx_count_overall

    return udp_loss_in_cellular, udp_loss_in_internet
def get_RRC_timer_map(QCATEntries, demote_accurate=False):
    # use two RRC log ID difference to measure the difference
    rrc_to_rrc_timer_map = rw.initFullRRCMap({}, const.RRC_ORIG_MAP)
    # use the RRC log ID to nearest IP packets as metric
    rrc_to_nearest_ip_timer_map = rw.initFullRRCMap({}, const.RRC_ORIG_MAP)
    # store the percentage of RRC_to_IP /  RRC_to_RRC
    percentage_map = rw.initFullRRCMap({}, const.RRC_ORIG_MAP)

    for k in rrc_to_rrc_timer_map:
        rrc_to_rrc_timer_map[k] = rw.initFullRRCMap([], const.RRC_ORIG_MAP)
        rrc_to_nearest_ip_timer_map[k] = rw.initFullRRCMap([],
                                                           const.RRC_ORIG_MAP)
        percentage_map[k] = rw.initFullRRCMap([], const.RRC_ORIG_MAP)

    rrcID_domain = set(const.RRC_ORIG_MAP)

    # check for the previous index
    priv_rrc_entry_index = None
    for index in range(len(QCATEntries)):
        cur_entry = QCATEntries[index]
        if cur_entry.logID == const.RRC_ID and cur_entry.rrcID in rrcID_domain:
            if priv_rrc_entry_index:
                priv_entry = QCATEntries[priv_rrc_entry_index]
                time_diff = cur_entry.timestamp - priv_entry.timestamp
                rrc_to_rrc_timer_map[priv_entry.rrcID][cur_entry.rrcID].append(
                    time_diff)
                # Find the nearest IP log
                ip_log_index = find_nearest_ip_index(QCATEntries, index - 1,
                                                     priv_rrc_entry_index + 1)

                # Assign RRC to IP timer map
                new_time_diff = time_diff
                if ip_log_index:
                    ip_log = QCATEntries[ip_log_index]
                    new_time_diff = cur_entry.timestamp - ip_log.timestamp
                rrc_to_nearest_ip_timer_map[priv_entry.rrcID][
                    cur_entry.rrcID].append(new_time_diff)
                if time_diff:
                    percentage_map[priv_entry.rrcID][cur_entry.rrcID].append(
                        new_time_diff / time_diff)
            priv_rrc_entry_index = index

    if DEBUG:
        print "FACH promote Timer:", len(
            rrc_to_rrc_timer_map[const.FACH_ID][const.DCH_ID])
        print util.listToStr(
            util.quartileResult(
                rrc_to_rrc_timer_map[const.FACH_ID][const.DCH_ID]))
        print "PCH promote Timer:", len(
            rrc_to_rrc_timer_map[const.PCH_ID][const.FACH_ID])
        print util.listToStr(
            util.quartileResult(
                rrc_to_rrc_timer_map[const.PCH_ID][const.FACH_ID]))
        print "DCH demotion Timer:", len(
            rrc_to_rrc_timer_map[const.DCH_ID][const.FACH_ID])
        print util.listToStr(
            util.quartileResult(
                rrc_to_rrc_timer_map[const.DCH_ID][const.FACH_ID]))
        print "FACH demotion Timer:", len(
            rrc_to_rrc_timer_map[const.FACH_ID][const.PCH_ID])
        print util.listToStr(
            util.quartileResult(
                rrc_to_rrc_timer_map[const.FACH_ID][const.PCH_ID]))

        print ">" * 50
        print "IP FACH promote Timer:", len(
            rrc_to_nearest_ip_timer_map[const.FACH_ID][const.DCH_ID])
        print util.listToStr(
            util.quartileResult(
                rrc_to_nearest_ip_timer_map[const.FACH_ID][const.DCH_ID]))
        print "IP PCH promote Timer:", len(
            rrc_to_nearest_ip_timer_map[const.PCH_ID][const.FACH_ID])
        print util.listToStr(
            util.quartileResult(
                rrc_to_nearest_ip_timer_map[const.PCH_ID][const.FACH_ID]))
        print "IP DCH demotion Timer:", len(
            rrc_to_nearest_ip_timer_map[const.DCH_ID][const.FACH_ID])
        print util.listToStr(
            util.quartileResult(
                rrc_to_nearest_ip_timer_map[const.DCH_ID][const.FACH_ID]))
        print "IP FACH demotion Timer:", len(
            rrc_to_nearest_ip_timer_map[const.FACH_ID][const.PCH_ID])
        print util.listToStr(
            util.quartileResult(
                rrc_to_nearest_ip_timer_map[const.FACH_ID][const.PCH_ID]))

        print ">" * 50
        print "Percentage FACH promote Timer:", len(
            percentage_map[const.FACH_ID][const.DCH_ID])
        print util.listToStr(
            util.quartileResult(percentage_map[const.FACH_ID][const.DCH_ID]))
        print "Percentage PCH promote Timer:", len(
            percentage_map[const.PCH_ID][const.FACH_ID])
        print util.listToStr(
            util.quartileResult(percentage_map[const.PCH_ID][const.FACH_ID]))
        print "Percentage DCH demotion Timer:", len(
            percentage_map[const.DCH_ID][const.FACH_ID])
        print util.listToStr(
            util.quartileResult(percentage_map[const.DCH_ID][const.FACH_ID]))
        print "Percentage FACH demotion Timer:", len(
            percentage_map[const.FACH_ID][const.PCH_ID])
        print util.listToStr(
            util.quartileResult(percentage_map[const.FACH_ID][const.PCH_ID]))

    return (rrc_to_rrc_timer_map, rrc_to_nearest_ip_timer_map)
def get_RRC_timer_map(QCATEntries, demote_accurate = False):
    # use two RRC log ID difference to measure the difference
    rrc_to_rrc_timer_map = rw.initFullRRCMap({}, const.RRC_ORIG_MAP)
    # use the RRC log ID to nearest IP packets as metric
    rrc_to_nearest_ip_timer_map = rw.initFullRRCMap({}, const.RRC_ORIG_MAP)
    # store the percentage of RRC_to_IP /  RRC_to_RRC
    percentage_map = rw.initFullRRCMap({}, const.RRC_ORIG_MAP)

    for k in rrc_to_rrc_timer_map:
        rrc_to_rrc_timer_map[k] = rw.initFullRRCMap([], const.RRC_ORIG_MAP)
        rrc_to_nearest_ip_timer_map[k] = rw.initFullRRCMap([], const.RRC_ORIG_MAP)
        percentage_map[k] = rw.initFullRRCMap([], const.RRC_ORIG_MAP)

    rrcID_domain = set(const.RRC_ORIG_MAP)

    # check for the previous index
    priv_rrc_entry_index = None
    for index in range(len(QCATEntries)):
        cur_entry = QCATEntries[index]
        if cur_entry.logID == const.RRC_ID and cur_entry.rrcID in rrcID_domain:
            if priv_rrc_entry_index:
                priv_entry = QCATEntries[priv_rrc_entry_index]
                time_diff = cur_entry.timestamp - priv_entry.timestamp
                rrc_to_rrc_timer_map[priv_entry.rrcID][cur_entry.rrcID].append(time_diff)
                # Find the nearest IP log
                ip_log_index = find_nearest_ip_index(QCATEntries, index - 1, priv_rrc_entry_index + 1)

                # Assign RRC to IP timer map
                new_time_diff = time_diff
                if ip_log_index:
                    ip_log = QCATEntries[ip_log_index]
                    new_time_diff = cur_entry.timestamp - ip_log.timestamp
                rrc_to_nearest_ip_timer_map[priv_entry.rrcID][cur_entry.rrcID].append(new_time_diff)
                if time_diff:
                    percentage_map[priv_entry.rrcID][cur_entry.rrcID].append(new_time_diff/time_diff)
            priv_rrc_entry_index = index

    if DEBUG:
        print "FACH promote Timer:", len(rrc_to_rrc_timer_map[const.FACH_ID][const.DCH_ID])   
        print util.listToStr(util.quartileResult(rrc_to_rrc_timer_map[const.FACH_ID][const.DCH_ID]))
        print "PCH promote Timer:", len(rrc_to_rrc_timer_map[const.PCH_ID][const.FACH_ID])
        print util.listToStr(util.quartileResult(rrc_to_rrc_timer_map[const.PCH_ID][const.FACH_ID]))
        print "DCH demotion Timer:", len(rrc_to_rrc_timer_map[const.DCH_ID][const.FACH_ID])   
        print util.listToStr(util.quartileResult(rrc_to_rrc_timer_map[const.DCH_ID][const.FACH_ID]))
        print "FACH demotion Timer:", len(rrc_to_rrc_timer_map[const.FACH_ID][const.PCH_ID])
        print util.listToStr(util.quartileResult(rrc_to_rrc_timer_map[const.FACH_ID][const.PCH_ID]))

        print ">"*50
        print "IP FACH promote Timer:", len(rrc_to_nearest_ip_timer_map[const.FACH_ID][const.DCH_ID])   
        print util.listToStr(util.quartileResult(rrc_to_nearest_ip_timer_map[const.FACH_ID][const.DCH_ID]))
        print "IP PCH promote Timer:", len(rrc_to_nearest_ip_timer_map[const.PCH_ID][const.FACH_ID])
        print util.listToStr(util.quartileResult(rrc_to_nearest_ip_timer_map[const.PCH_ID][const.FACH_ID]))
        print "IP DCH demotion Timer:", len(rrc_to_nearest_ip_timer_map[const.DCH_ID][const.FACH_ID])   
        print util.listToStr(util.quartileResult(rrc_to_nearest_ip_timer_map[const.DCH_ID][const.FACH_ID]))
        print "IP FACH demotion Timer:", len(rrc_to_nearest_ip_timer_map[const.FACH_ID][const.PCH_ID])
        print util.listToStr(util.quartileResult(rrc_to_nearest_ip_timer_map[const.FACH_ID][const.PCH_ID]))

        print ">"*50
        print "Percentage FACH promote Timer:", len(percentage_map[const.FACH_ID][const.DCH_ID])   
        print util.listToStr(util.quartileResult(percentage_map[const.FACH_ID][const.DCH_ID]))
        print "Percentage PCH promote Timer:", len(percentage_map[const.PCH_ID][const.FACH_ID])
        print util.listToStr(util.quartileResult(percentage_map[const.PCH_ID][const.FACH_ID]))
        print "Percentage DCH demotion Timer:", len(percentage_map[const.DCH_ID][const.FACH_ID])   
        print util.listToStr(util.quartileResult(percentage_map[const.DCH_ID][const.FACH_ID]))
        print "Percentage FACH demotion Timer:", len(percentage_map[const.FACH_ID][const.PCH_ID])
        print util.listToStr(util.quartileResult(percentage_map[const.FACH_ID][const.PCH_ID]))

    return (rrc_to_rrc_timer_map, rrc_to_nearest_ip_timer_map)