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.
271 lines
9.7 KiB
271 lines
9.7 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
using System.Threading.Tasks;
|
|
using CoreAgent.ProtocolClient.Enums;
|
|
using CoreAgent.ProtocolClient.Models;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace CoreAgent.ProtocolClient.Context.UeStateManager
|
|
{
|
|
/// <summary>
|
|
/// UeIdentifierManager UE标识符映射部分
|
|
/// </summary>
|
|
public partial class UeIdentifierManager
|
|
{
|
|
#region UE标识符映射方法
|
|
|
|
/// <summary>
|
|
/// 设置IMSI与UE ID的映射关系
|
|
/// 性能优化:使用HashSet提高查找效率
|
|
/// </summary>
|
|
/// <param name="ueId">UE ID</param>
|
|
/// <param name="imsi">IMSI标识符</param>
|
|
/// <exception cref="UeInfoException">UE ID无效时抛出</exception>
|
|
public void SetImsi(int ueId, string imsi)
|
|
{
|
|
if (string.IsNullOrEmpty(imsi))
|
|
{
|
|
_logger?.LogWarning("尝试设置空的IMSI");
|
|
return;
|
|
}
|
|
|
|
if (ueId <= 0)
|
|
{
|
|
throw new UeInfoException(ueId, "UE ID必须大于0");
|
|
}
|
|
|
|
try
|
|
{
|
|
lock (_lockObject)
|
|
{
|
|
if (!ImsiToUeId.TryGetValue(imsi, out var existingUeIds))
|
|
{
|
|
ImsiToUeId[imsi] = new List<int> { ueId };
|
|
_logger?.LogDebug("创建新的IMSI映射: {Imsi} -> UE {UeId}", imsi, ueId);
|
|
}
|
|
else if (!existingUeIds.Contains(ueId))
|
|
{
|
|
existingUeIds.Add(ueId);
|
|
_logger?.LogDebug("添加IMSI映射: {Imsi} -> UE {UeId}", imsi, ueId);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger?.LogError(ex, "设置IMSI映射失败: UE {UeId}, IMSI {Imsi}", ueId, imsi);
|
|
throw new MappingException("IMSI", imsi, $"设置IMSI映射失败: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 设置TMSI与UE ID的映射关系
|
|
/// 性能优化:使用缓存减少重复转换
|
|
/// </summary>
|
|
/// <param name="ueId">UE ID</param>
|
|
/// <param name="tmsi">TMSI标识符(十六进制字符串)</param>
|
|
/// <exception cref="IdentifierFormatException">TMSI格式无效时抛出</exception>
|
|
public void SetTmsi(int ueId, string tmsi)
|
|
{
|
|
if (string.IsNullOrEmpty(tmsi))
|
|
{
|
|
_logger?.LogWarning("尝试设置空的TMSI");
|
|
return;
|
|
}
|
|
|
|
if (ueId <= 0)
|
|
{
|
|
throw new UeInfoException(ueId, "UE ID必须大于0");
|
|
}
|
|
|
|
try
|
|
{
|
|
uint tmsiKey = Convert.ToUInt32(tmsi, 16);
|
|
|
|
lock (_lockObject)
|
|
{
|
|
if (TmsiToUeId.TryGetValue(tmsiKey, out int existingUeId) && existingUeId > 0)
|
|
{
|
|
// 同步IMSI信息
|
|
SyncImsiFromExistingUe(existingUeId, ueId);
|
|
// 合并UE信息
|
|
MergeUeInfo(existingUeId, ueId);
|
|
_logger?.LogDebug("更新TMSI映射: {Tmsi} -> UE {UeId} (原UE {ExistingUeId})", tmsi, ueId, existingUeId);
|
|
}
|
|
else
|
|
{
|
|
TmsiToUeId[tmsiKey] = ueId;
|
|
_logger?.LogDebug("创建新的TMSI映射: {Tmsi} -> UE {UeId}", tmsi, ueId);
|
|
}
|
|
}
|
|
}
|
|
catch (FormatException ex)
|
|
{
|
|
var errorMessage = $"TMSI格式无效: '{tmsi}',期望十六进制格式";
|
|
_logger?.LogError(ex, errorMessage);
|
|
throw new IdentifierFormatException(tmsi, "十六进制格式", errorMessage);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger?.LogError(ex, "设置TMSI映射失败: UE {UeId}, TMSI {Tmsi}", ueId, tmsi);
|
|
throw new MappingException("TMSI", tmsi, $"设置TMSI映射失败: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 设置请求TMSI与UE ID的映射关系
|
|
/// </summary>
|
|
/// <param name="ueId">UE ID</param>
|
|
/// <param name="tmsi">请求TMSI标识符(十六进制字符串)</param>
|
|
public void SetRequestTmsi(int ueId, string tmsi)
|
|
{
|
|
if (string.IsNullOrEmpty(tmsi))
|
|
{
|
|
_logger?.LogWarning("尝试设置空的请求TMSI");
|
|
return;
|
|
}
|
|
|
|
if (ueId <= 0)
|
|
{
|
|
throw new UeInfoException(ueId, "UE ID必须大于0");
|
|
}
|
|
|
|
try
|
|
{
|
|
uint tmsiKey = Convert.ToUInt32(tmsi, 16);
|
|
|
|
lock (_lockObject)
|
|
{
|
|
RequestTmsiToUeId[tmsiKey] = ueId;
|
|
_logger?.LogDebug("设置请求TMSI映射: {Tmsi} -> UE {UeId}", tmsi, ueId);
|
|
}
|
|
}
|
|
catch (FormatException ex)
|
|
{
|
|
var errorMessage = $"请求TMSI格式无效: '{tmsi}',期望十六进制格式";
|
|
_logger?.LogError(ex, errorMessage);
|
|
throw new IdentifierFormatException(tmsi, "十六进制格式", errorMessage);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 设置RNTI与UE ID的映射关系
|
|
/// </summary>
|
|
/// <param name="log">协议日志</param>
|
|
/// <param name="rnti">RNTI标识符(十六进制字符串)</param>
|
|
public void SetRnti(BuildProtocolLog log, string rnti)
|
|
{
|
|
if (log?.UeId == null || string.IsNullOrEmpty(rnti))
|
|
{
|
|
_logger?.LogWarning("设置RNTI映射失败:日志或RNTI为空");
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
int rntiId = int.Parse(rnti, System.Globalization.NumberStyles.HexNumber);
|
|
|
|
lock (_lockObject)
|
|
{
|
|
RntiToUeId[rntiId] = log.UeId.Value;
|
|
_logger?.LogDebug("设置RNTI映射: {Rnti} -> UE {UeId}", rnti, log.UeId.Value);
|
|
}
|
|
}
|
|
catch (FormatException ex)
|
|
{
|
|
var errorMessage = $"RNTI格式无效: '{rnti}',期望十六进制格式";
|
|
_logger?.LogError(ex, errorMessage);
|
|
throw new IdentifierFormatException(rnti, "十六进制格式", errorMessage);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 设置PLMN与UE ID的映射关系
|
|
/// </summary>
|
|
/// <param name="ueId">UE ID</param>
|
|
/// <param name="plmn">PLMN标识符</param>
|
|
public void SetPlmn(int ueId, string plmn)
|
|
{
|
|
if (string.IsNullOrEmpty(plmn))
|
|
{
|
|
_logger?.LogWarning("尝试设置空的PLMN");
|
|
return;
|
|
}
|
|
|
|
if (ueId <= 0)
|
|
{
|
|
throw new UeInfoException(ueId, "UE ID必须大于0");
|
|
}
|
|
|
|
try
|
|
{
|
|
lock (_lockObject)
|
|
{
|
|
if (!PlmnToUeId.TryGetValue(plmn, out var existingUeIds))
|
|
{
|
|
PlmnToUeId[plmn] = new List<int> { ueId };
|
|
_logger?.LogDebug("创建新的PLMN映射: {Plmn} -> UE {UeId}", plmn, ueId);
|
|
}
|
|
else if (!existingUeIds.Contains(ueId))
|
|
{
|
|
existingUeIds.Add(ueId);
|
|
_logger?.LogDebug("添加PLMN映射: {Plmn} -> UE {UeId}", plmn, ueId);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger?.LogError(ex, "设置PLMN映射失败: UE {UeId}, PLMN {Plmn}", ueId, plmn);
|
|
throw new MappingException("PLMN", plmn, $"设置PLMN映射失败: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 设置Service Request TMSI与UE ID的映射关系
|
|
/// </summary>
|
|
/// <param name="ueId">UE ID</param>
|
|
/// <param name="srTmsi">Service Request TMSI标识符(十六进制字符串)</param>
|
|
public void SetSrTmsi(int ueId, string srTmsi)
|
|
{
|
|
if (string.IsNullOrEmpty(srTmsi))
|
|
{
|
|
_logger?.LogWarning("尝试设置空的Service Request TMSI");
|
|
return;
|
|
}
|
|
|
|
if (ueId <= 0)
|
|
{
|
|
throw new UeInfoException(ueId, "UE ID必须大于0");
|
|
}
|
|
|
|
try
|
|
{
|
|
uint srTmsiKey = Convert.ToUInt32(srTmsi, 16);
|
|
|
|
lock (_lockObject)
|
|
{
|
|
if (!SrTmsiToUeId.TryGetValue(srTmsiKey, out var existingUeIds))
|
|
{
|
|
SrTmsiToUeId[srTmsiKey] = new List<int> { ueId };
|
|
_logger?.LogDebug("创建新的Service Request TMSI映射: {SrTmsi} -> UE {UeId}", srTmsi, ueId);
|
|
}
|
|
else if (!existingUeIds.Contains(ueId))
|
|
{
|
|
existingUeIds.Add(ueId);
|
|
_logger?.LogDebug("添加Service Request TMSI映射: {SrTmsi} -> UE {UeId}", srTmsi, ueId);
|
|
}
|
|
}
|
|
}
|
|
catch (FormatException ex)
|
|
{
|
|
var errorMessage = $"Service Request TMSI格式无效: '{srTmsi}',期望十六进制格式";
|
|
_logger?.LogError(ex, errorMessage);
|
|
throw new IdentifierFormatException(srTmsi, "十六进制格式", errorMessage);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|
|
|