|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Linq;
|
|
|
|
|
|
|
|
namespace CoreAgent.ProtocolClient.Models
|
|
|
|
{
|
|
|
|
/// <summary>
|
|
|
|
/// TMSI匹配处理器
|
|
|
|
/// 负责处理TMSI匹配和UE链的构建,从根节点获取IMSI并分配给整个链
|
|
|
|
/// </summary>
|
|
|
|
public class TmsiMatchProcessor
|
|
|
|
{
|
|
|
|
/// <summary>
|
|
|
|
/// TMSI到UE ID的映射表
|
|
|
|
/// </summary>
|
|
|
|
private readonly Dictionary<uint, int> _tmsiToUeId;
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 请求TMSI到UE ID的映射表
|
|
|
|
/// </summary>
|
|
|
|
private readonly Dictionary<uint, int> _requestTmsiToUeId;
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// IMSI到UE ID的映射表
|
|
|
|
/// </summary>
|
|
|
|
private readonly Dictionary<string, List<int>> _imsiToUeId;
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 构造函数
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="tmsiToUeId">TMSI到UE ID的映射表</param>
|
|
|
|
/// <param name="requestTmsiToUeId">请求TMSI到UE ID的映射表</param>
|
|
|
|
/// <param name="imsiToUeId">IMSI到UE ID的映射表</param>
|
|
|
|
public TmsiMatchProcessor(
|
|
|
|
Dictionary<uint, int> tmsiToUeId,
|
|
|
|
Dictionary<uint, int> requestTmsiToUeId,
|
|
|
|
Dictionary<string, List<int>> imsiToUeId)
|
|
|
|
{
|
|
|
|
_tmsiToUeId = tmsiToUeId ?? new Dictionary<uint, int>();
|
|
|
|
_requestTmsiToUeId = requestTmsiToUeId ?? new Dictionary<uint, int>();
|
|
|
|
_imsiToUeId = imsiToUeId ?? new Dictionary<string, List<int>>();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 生成TMSI匹配结果
|
|
|
|
/// 先构建树形结构,从根节点获取IMSI,然后平铺成列表
|
|
|
|
/// </summary>
|
|
|
|
/// <returns>TMSI匹配结果列表</returns>
|
|
|
|
public List<TmsiMatchResult> GenerateTmsiMatches()
|
|
|
|
{
|
|
|
|
var matches = new List<TmsiMatchResult>();
|
|
|
|
|
|
|
|
// 构建UE链的树形结构
|
|
|
|
var ueChains = BuildUeChains();
|
|
|
|
|
|
|
|
// 遍历RequestTmsiToUeId,查找在TmsiToUeId中是否有相同的TMSI
|
|
|
|
foreach (var requestKvp in _requestTmsiToUeId)
|
|
|
|
{
|
|
|
|
uint tmsi = requestKvp.Key;
|
|
|
|
int requestUeId = requestKvp.Value;
|
|
|
|
|
|
|
|
// 检查TmsiToUeId中是否存在相同的TMSI
|
|
|
|
if (_tmsiToUeId.TryGetValue(tmsi, out int receiveUeId))
|
|
|
|
{
|
|
|
|
// 从UE链中获取IMSI
|
|
|
|
string imsi = GetImsiFromUeChain(receiveUeId, ueChains);
|
|
|
|
|
|
|
|
// 创建匹配结果
|
|
|
|
var matchResult = new TmsiMatchResult(tmsi, requestUeId, receiveUeId, imsi);
|
|
|
|
matches.Add(matchResult);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return matches;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 构建UE链的树形结构
|
|
|
|
/// 根据RequestTmsiToUeId和TmsiToUeId的映射关系构建链式结构
|
|
|
|
/// </summary>
|
|
|
|
/// <returns>UE链的字典,键为链的根节点UE ID,值为链中的所有UE ID</returns>
|
|
|
|
private Dictionary<int, List<int>> BuildUeChains()
|
|
|
|
{
|
|
|
|
var ueChains = new Dictionary<int, List<int>>();
|
|
|
|
var processedUeIds = new HashSet<int>();
|
|
|
|
|
|
|
|
// 遍历所有TMSI匹配关系,构建链式结构
|
|
|
|
foreach (var requestKvp in _tmsiToUeId)
|
|
|
|
{
|
|
|
|
uint tmsi = requestKvp.Key;
|
|
|
|
int requestUeId = requestKvp.Value;
|
|
|
|
|
|
|
|
if (_requestTmsiToUeId.TryGetValue(tmsi, out int receiveUeId))
|
|
|
|
{
|
|
|
|
// 如果这个UE ID还没有被处理过
|
|
|
|
if (!processedUeIds.Contains(requestUeId) && !processedUeIds.Contains(receiveUeId))
|
|
|
|
{
|
|
|
|
var chain = BuildChainFromUe(requestUeId, receiveUeId);
|
|
|
|
if (chain.Count > 0)
|
|
|
|
{
|
|
|
|
// 使用链的根节点(最外层节点)作为键
|
|
|
|
int rootUeId = chain[0];
|
|
|
|
ueChains[rootUeId] = chain;
|
|
|
|
|
|
|
|
// 标记所有UE ID为已处理
|
|
|
|
foreach (int ueId in chain)
|
|
|
|
{
|
|
|
|
processedUeIds.Add(ueId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ueChains;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 从指定的UE ID开始构建链式结构
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="requestUeId">请求UE ID</param>
|
|
|
|
/// <param name="receiveUeId">接收UE ID</param>
|
|
|
|
/// <returns>链中的所有UE ID列表</returns>
|
|
|
|
private List<int> BuildChainFromUe(int requestUeId, int receiveUeId)
|
|
|
|
{
|
|
|
|
var chain = new List<int>();
|
|
|
|
var visited = new HashSet<int>();
|
|
|
|
|
|
|
|
// 从requestUeId开始,沿着链式关系查找
|
|
|
|
int currentUeId = requestUeId;
|
|
|
|
while (currentUeId > 0 && !visited.Contains(currentUeId))
|
|
|
|
{
|
|
|
|
chain.Add(currentUeId);
|
|
|
|
visited.Add(currentUeId);
|
|
|
|
|
|
|
|
// 查找下一个UE ID(在TmsiToUeId中查找当前UE ID作为receiveUeId的情况)
|
|
|
|
currentUeId = FindNextUeIdInChain(currentUeId);
|
|
|
|
}
|
|
|
|
|
|
|
|
return chain;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 在链中查找下一个UE ID
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="currentUeId">当前UE ID</param>
|
|
|
|
/// <returns>下一个UE ID,如果没有找到则返回-1</returns>
|
|
|
|
private int FindNextUeIdInChain(int currentUeId)
|
|
|
|
{
|
|
|
|
// 在RequestTmsiToUeId中查找当前UE ID作为receiveUeId的情况
|
|
|
|
foreach (var kvp in _requestTmsiToUeId)
|
|
|
|
{
|
|
|
|
if (_tmsiToUeId.TryGetValue(kvp.Key, out int receiveUeId) && receiveUeId == currentUeId)
|
|
|
|
{
|
|
|
|
return kvp.Value; // 返回对应的requestUeId
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1; // 没有找到下一个UE ID
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 从UE链中获取IMSI
|
|
|
|
/// 优先从链的根节点(最外层节点)获取IMSI
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="ueId">当前UE ID</param>
|
|
|
|
/// <param name="ueChains">UE链字典</param>
|
|
|
|
/// <returns>对应的IMSI,如果未找到则返回空字符串</returns>
|
|
|
|
private string GetImsiFromUeChain(int ueId, Dictionary<int, List<int>> ueChains)
|
|
|
|
{
|
|
|
|
// 查找当前UE ID所在的链
|
|
|
|
foreach (var chain in ueChains.Values)
|
|
|
|
{
|
|
|
|
if (chain.Contains(ueId))
|
|
|
|
{
|
|
|
|
// 从链的根节点(最外层节点)开始查找IMSI
|
|
|
|
foreach (int chainUeId in chain)
|
|
|
|
{
|
|
|
|
string imsi = GetImsiForUeId(chainUeId);
|
|
|
|
if (!string.IsNullOrEmpty(imsi))
|
|
|
|
{
|
|
|
|
return imsi;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return string.Empty;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 根据UE ID获取对应的IMSI
|
|
|
|
/// 优先查找当前UE ID,如果未找到则查找整个UE链中的IMSI
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="ueId">UE ID</param>
|
|
|
|
/// <returns>对应的IMSI,如果未找到则返回空字符串</returns>
|
|
|
|
private string GetImsiForUeId(int ueId)
|
|
|
|
{
|
|
|
|
// 1. 首先查找当前UE ID对应的IMSI
|
|
|
|
foreach (var imsiMapping in _imsiToUeId)
|
|
|
|
{
|
|
|
|
if (imsiMapping.Value.Contains(ueId))
|
|
|
|
{
|
|
|
|
return imsiMapping.Key;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 2. 如果当前UE ID没有IMSI,查找整个UE链中的IMSI
|
|
|
|
// 遍历所有IMSI映射,查找是否有任何UE ID对应的IMSI
|
|
|
|
foreach (var imsiMapping in _imsiToUeId)
|
|
|
|
{
|
|
|
|
if (!string.IsNullOrEmpty(imsiMapping.Key))
|
|
|
|
{
|
|
|
|
return imsiMapping.Key;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return string.Empty;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 获取UE链的统计信息
|
|
|
|
/// </summary>
|
|
|
|
/// <returns>UE链统计信息</returns>
|
|
|
|
public UeChainStats GetUeChainStats()
|
|
|
|
{
|
|
|
|
var ueChains = BuildUeChains();
|
|
|
|
|
|
|
|
return new UeChainStats
|
|
|
|
{
|
|
|
|
TotalChains = ueChains.Count,
|
|
|
|
TotalUeIds = ueChains.Values.Sum(chain => chain.Count),
|
|
|
|
AverageChainLength = ueChains.Count > 0 ? (double)ueChains.Values.Sum(chain => chain.Count) / ueChains.Count : 0,
|
|
|
|
MaxChainLength = ueChains.Count > 0 ? ueChains.Values.Max(chain => chain.Count) : 0,
|
|
|
|
MinChainLength = ueChains.Count > 0 ? ueChains.Values.Min(chain => chain.Count) : 0
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 获取所有UE链的详细信息
|
|
|
|
/// </summary>
|
|
|
|
/// <returns>UE链详细信息列表</returns>
|
|
|
|
public List<UeChainInfo> GetUeChainDetails()
|
|
|
|
{
|
|
|
|
var ueChains = BuildUeChains();
|
|
|
|
var chainInfos = new List<UeChainInfo>();
|
|
|
|
|
|
|
|
foreach (var kvp in ueChains)
|
|
|
|
{
|
|
|
|
int rootUeId = kvp.Key;
|
|
|
|
var chain = kvp.Value;
|
|
|
|
string imsi = GetImsiFromUeChain(rootUeId, ueChains);
|
|
|
|
|
|
|
|
chainInfos.Add(new UeChainInfo
|
|
|
|
{
|
|
|
|
RootUeId = rootUeId,
|
|
|
|
ChainLength = chain.Count,
|
|
|
|
UeIds = chain.ToList(),
|
|
|
|
Imsi = imsi
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
return chainInfos;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// UE链统计信息
|
|
|
|
/// </summary>
|
|
|
|
public class UeChainStats
|
|
|
|
{
|
|
|
|
/// <summary>
|
|
|
|
/// 总链数
|
|
|
|
/// </summary>
|
|
|
|
public int TotalChains { get; set; }
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 总UE ID数
|
|
|
|
/// </summary>
|
|
|
|
public int TotalUeIds { get; set; }
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 平均链长度
|
|
|
|
/// </summary>
|
|
|
|
public double AverageChainLength { get; set; }
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 最大链长度
|
|
|
|
/// </summary>
|
|
|
|
public int MaxChainLength { get; set; }
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 最小链长度
|
|
|
|
/// </summary>
|
|
|
|
public int MinChainLength { get; set; }
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// UE链详细信息
|
|
|
|
/// </summary>
|
|
|
|
public class UeChainInfo
|
|
|
|
{
|
|
|
|
/// <summary>
|
|
|
|
/// 根节点UE ID
|
|
|
|
/// </summary>
|
|
|
|
public int RootUeId { get; set; }
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 链长度
|
|
|
|
/// </summary>
|
|
|
|
public int ChainLength { get; set; }
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 链中的所有UE ID
|
|
|
|
/// </summary>
|
|
|
|
public List<int> UeIds { get; set; } = new List<int>();
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 对应的IMSI
|
|
|
|
/// </summary>
|
|
|
|
public string Imsi { get; set; } = string.Empty;
|
|
|
|
}
|
|
|
|
}
|