You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

316 lines
13 KiB

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CoreAgent.ProtocolClient.Models;
using Microsoft.Extensions.Logging;
namespace CoreAgent.ProtocolClient.Context.UeStateManager
{
/// <summary>
/// UeIdentifierManager TMSI匹配部分
/// </summary>
public partial class UeIdentifierManager
{
#region TMSI匹配方法
/// <summary>
/// 根据TMSI匹配生成请求UE ID和接收UE ID的对应关系
/// 使用TmsiMatchProcessor处理匹配逻辑
/// </summary>
/// <returns>TMSI匹配结果列表</returns>
public List<TmsiMatchResult> GenerateTmsiMatches()
{
try
{
var processor = new TmsiMatchProcessor(TmsiToUeId, RequestTmsiToUeId, ImsiToUeId);
var results = processor.GenerateTmsiMatches();
_logger?.LogDebug("生成TMSI匹配结果,共 {Count} 个匹配", results.Count);
return results;
}
catch (Exception ex)
{
_logger?.LogError(ex, "生成TMSI匹配失败");
throw new GeneralUeIdentifierManagerException("GenerateTmsiMatches", "生成TMSI匹配失败", ex);
}
}
/// <summary>
/// 根据UE ID获取对应的IMSI
/// 优先查找当前UE ID,如果未找到则查找整个UE链中的IMSI
/// </summary>
/// <param name="ueId">UE ID</param>
/// <returns>对应的IMSI,如果未找到则返回空字符串</returns>
private string GetImsiForUeId(int ueId)
{
if (ueId <= 0)
{
_logger?.LogWarning("尝试获取无效UE ID的IMSI: {UeId}", ueId);
return string.Empty;
}
try
{
// 1. 首先查找当前UE ID对应的IMSI
var currentImsiMapping = ImsiToUeId.FirstOrDefault(kvp => kvp.Value.Contains(ueId));
if (!string.IsNullOrEmpty(currentImsiMapping.Key))
{
return currentImsiMapping.Key;
}
// 2. 如果当前UE ID没有IMSI,查找整个UE链中的IMSI
var anyImsiMapping = ImsiToUeId.FirstOrDefault(kvp => !string.IsNullOrEmpty(kvp.Key));
return anyImsiMapping.Key ?? string.Empty;
}
catch (Exception ex)
{
_logger?.LogError(ex, "获取UE {UeId} 的IMSI失败", ueId);
return string.Empty;
}
}
/// <summary>
/// 获取UE链的统计信息
/// </summary>
/// <returns>UE链统计信息</returns>
public UeChainStats GetUeChainStats()
{
try
{
var processor = new TmsiMatchProcessor(TmsiToUeId, RequestTmsiToUeId, ImsiToUeId);
var stats = processor.GetUeChainStats();
_logger?.LogDebug("获取UE链统计信息成功");
return stats;
}
catch (Exception ex)
{
_logger?.LogError(ex, "获取UE链统计信息失败");
throw new GeneralUeIdentifierManagerException("GetUeChainStats", "获取UE链统计信息失败", ex);
}
}
/// <summary>
/// 获取所有UE链的详细信息
/// </summary>
/// <returns>UE链详细信息列表</returns>
public List<UeChainInfo> GetUeChainDetails()
{
try
{
var processor = new TmsiMatchProcessor(TmsiToUeId, RequestTmsiToUeId, ImsiToUeId);
var details = processor.GetUeChainDetails();
_logger?.LogDebug("获取UE链详细信息成功,共 {Count} 个链", details.Count);
return details;
}
catch (Exception ex)
{
_logger?.LogError(ex, "获取UE链详细信息失败");
throw new GeneralUeIdentifierManagerException("GetUeChainDetails", "获取UE链详细信息失败", ex);
}
}
/// <summary>
/// 将 SrTmsiToUeId 平铺成 SrTmsiMapping 列表,并与 GenerateTmsiMatches 结果匹配更新 IMSI、Root UE ID 和 PLMN
/// 性能优化:使用LINQ提高查找效率
/// </summary>
/// <returns>平铺后的 SrTmsiMapping 列表,包含匹配的 IMSI、Root UE ID 和 PLMN 信息</returns>
public List<SrTmsiMapping> GenerateSrTmsiMappings(List<TmsiMatchResult> tmsiMatches)
{
if (tmsiMatches == null)
{
throw new ArgumentNullException(nameof(tmsiMatches));
}
try
{
var srTmsiMappings = new List<SrTmsiMapping>();
// 1. 平铺 SrTmsiToUeId 字典数据
foreach (var kvp in SrTmsiToUeId)
{
uint tmsi = kvp.Key;
var ueIds = kvp.Value;
foreach (int ueId in ueIds)
{
var mapping = new SrTmsiMapping(string.Empty, tmsi, ueId);
srTmsiMappings.Add(mapping);
}
}
// 2. 获取 UE 链信息以获取最外层的 Root UE ID
var ueChainDetails = GetUeChainDetails();
// 3. 根据 TMSI 匹配结果更新 SrTmsiMapping 的 IMSI 和 Root UE ID
foreach (var srMapping in srTmsiMappings)
{
UpdateSrTmsiMapping(srMapping, tmsiMatches, ueChainDetails);
}
// 4. 根据 RootUeId 从 PlmnToUeId 映射表更新 PLMN 信息
foreach (var srMapping in srTmsiMappings)
{
UpdateSrTmsiMappingPlmn(srMapping, ueChainDetails);
}
_logger?.LogDebug("生成Service Request TMSI映射成功,共 {Count} 个映射", srTmsiMappings.Count);
return srTmsiMappings;
}
catch (Exception ex)
{
_logger?.LogError(ex, "生成Service Request TMSI映射失败");
throw new GeneralUeIdentifierManagerException("GenerateSrTmsiMappings", "生成Service Request TMSI映射失败", ex);
}
}
#endregion
#region 私有辅助方法
/// <summary>
/// 更新 SrTmsiMapping 的 IMSI 和 Root UE ID
/// </summary>
/// <param name="srMapping">Service Request TMSI映射</param>
/// <param name="tmsiMatches">TMSI匹配结果</param>
/// <param name="ueChainDetails">UE链详细信息</param>
private void UpdateSrTmsiMapping(SrTmsiMapping srMapping, List<TmsiMatchResult> tmsiMatches, List<UeChainInfo> ueChainDetails)
{
// 查找匹配的 TMSI 结果
var matchingResult = tmsiMatches.FirstOrDefault(match => match.Tmsi == srMapping.Tmsi);
if (matchingResult != null && !string.IsNullOrEmpty(matchingResult.Imsi))
{
// 更新 IMSI
srMapping.Imsi = matchingResult.Imsi;
// 查找对应的最外层 Root UE ID
var chainInfo = ueChainDetails.FirstOrDefault(chain =>
chain.UeIds.Contains(srMapping.UeId));
if (chainInfo != null)
{
srMapping.RootUeId = chainInfo.RootUeId;
}
else
{
// 如果当前 UE ID 不在任何链中,尝试从匹配结果中查找
chainInfo = ueChainDetails.FirstOrDefault(chain =>
chain.UeIds.Contains(matchingResult.RequestUeId) ||
chain.UeIds.Contains(matchingResult.ReceiveUeId));
if (chainInfo != null)
{
srMapping.RootUeId = chainInfo.RootUeId;
}
}
}
else
{
// 如果 TMSI 匹配中没有找到,尝试从 ImsiToUeId 映射中查找
string imsi = GetImsiForUeId(srMapping.UeId);
if (!string.IsNullOrEmpty(imsi))
{
srMapping.Imsi = imsi;
// 查找对应的最外层 Root UE ID
var chainInfo = ueChainDetails.FirstOrDefault(chain =>
chain.UeIds.Contains(srMapping.UeId));
if (chainInfo != null)
{
srMapping.RootUeId = chainInfo.RootUeId;
}
}
}
}
/// <summary>
/// 更新 SrTmsiMapping 的 PLMN 信息
/// </summary>
/// <param name="srMapping">Service Request TMSI映射</param>
private void UpdateSrTmsiMappingPlmn(SrTmsiMapping srMapping, List<UeChainInfo> ueChainDetails)
{
try
{
_logger?.LogDebug("开始更新SrTmsiMapping PLMN信息 - TMSI: {Tmsi}, UeId: {UeId}, RootUeId: {RootUeId}",
srMapping.Tmsi, srMapping.UeId, srMapping.RootUeId);
if (srMapping.RootUeId > 0)
{
_logger?.LogDebug("使用RootUeId {RootUeId} 查找PLMN映射", srMapping.RootUeId);
// 查找包含 RootUeId 的 PLMN 映射
var plmnMapping = PlmnToUeId.FirstOrDefault(kvp => kvp.Value.Contains(srMapping.RootUeId));
if (!string.IsNullOrEmpty(plmnMapping.Key))
{
srMapping.Plmn = plmnMapping.Key;
_logger?.LogDebug("通过RootUeId找到PLMN: {Plmn}", plmnMapping.Key);
}
else
{
_logger?.LogDebug("未找到RootUeId {RootUeId} 对应的PLMN映射", srMapping.RootUeId);
}
}
else if (srMapping.UeId > 0)
{
_logger?.LogDebug("使用UeId {UeId} 和TMSI {Tmsi} 查找PLMN映射", srMapping.UeId, srMapping.Tmsi);
// 使用TryGetValue检查TMSI是否存在并获取对应的UeId
if (TmsiToUeId.TryGetValue(srMapping.Tmsi, out int filterUeId) && filterUeId > 0)
{
_logger?.LogDebug("找到TMSI {Tmsi} 对应的UeId: {FilterUeId}", srMapping.Tmsi, filterUeId);
// 如果 RootUeId 为空,尝试使用 UeId 查找 PLMN
var chainInfo = ueChainDetails?.FirstOrDefault(chain =>
chain?.UeIds?.Contains(filterUeId) == true);
if (chainInfo != null)
{
_logger?.LogDebug("找到包含UeId {FilterUeId} 的UE链,RootUeId: {ChainRootUeId}",
filterUeId, chainInfo.RootUeId);
var plmnMapping = PlmnToUeId.FirstOrDefault(kvp =>
kvp.Value?.Contains(filterUeId) == true);
if (!string.IsNullOrEmpty(plmnMapping.Key))
{
srMapping.Plmn = plmnMapping.Key;
srMapping.RootUeId = chainInfo.RootUeId;
_logger?.LogDebug("通过UeId找到PLMN: {Plmn}, 更新RootUeId: {RootUeId}",
plmnMapping.Key, chainInfo.RootUeId);
}
else
{
_logger?.LogDebug("未找到UeId {FilterUeId} 对应的PLMN映射", filterUeId);
}
}
else
{
_logger?.LogDebug("未找到包含UeId {FilterUeId} 的UE链", filterUeId);
}
}
else
{
_logger?.LogDebug("TMSI {Tmsi} 对应的UeId无效或为0", srMapping.Tmsi);
}
}
else
{
_logger?.LogDebug("SrTmsiMapping的UeId和RootUeId都无效,跳过PLMN更新");
}
_logger?.LogDebug("SrTmsiMapping PLMN信息更新完成 - TMSI: {Tmsi}, UeId: {UeId}, RootUeId: {RootUeId}, PLMN: {Plmn}",
srMapping.Tmsi, srMapping.UeId, srMapping.RootUeId, srMapping.Plmn);
}
catch (Exception ex)
{
_logger?.LogError(ex, "更新SrTmsiMapping PLMN信息失败 - TMSI: {Tmsi}, UeId: {UeId}, RootUeId: {RootUeId}",
srMapping.Tmsi, srMapping.UeId, srMapping.RootUeId);
throw new GeneralUeIdentifierManagerException("UpdateSrTmsiMappingPlmn", "更新SrTmsiMapping PLMN信息失败", ex);
}
}
#endregion
}
}