10 changed files with 1384 additions and 308 deletions
@ -0,0 +1,34 @@ |
|||||
|
namespace CoreAgent.Domain.Models.Protocol; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 日志方向类型枚举
|
||||
|
/// 定义了协议日志的传输方向
|
||||
|
/// 遵循DDD(领域驱动设计)原则,作为领域模型的一部分
|
||||
|
/// </summary>
|
||||
|
public enum DirectionLogsType |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 未知方向
|
||||
|
/// </summary>
|
||||
|
Unknown = 0, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 上行方向(UE到网络)
|
||||
|
/// </summary>
|
||||
|
Uplink = 1, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 下行方向(网络到UE)
|
||||
|
/// </summary>
|
||||
|
Downlink = 2, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 双向
|
||||
|
/// </summary>
|
||||
|
Bidirectional = 3, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 内部处理
|
||||
|
/// </summary>
|
||||
|
Internal = 4 |
||||
|
} |
@ -0,0 +1,200 @@ |
|||||
|
using Newtonsoft.Json; |
||||
|
|
||||
|
namespace CoreAgent.Domain.Models.Protocol; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 移动用户身份信息
|
||||
|
/// 用于存储移动网络用户的基本身份和位置信息
|
||||
|
/// 遵循DDD(领域驱动设计)原则,作为领域模型的一部分
|
||||
|
/// </summary>
|
||||
|
public class MobileUserIdentity |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 公共陆地移动网络标识
|
||||
|
/// Public Land Mobile Network Identifier
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("plmn")] |
||||
|
public string? Plmn { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 旧的临时移动用户标识
|
||||
|
/// Old Temporary Mobile Subscriber Identity
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("oldTmsi")] |
||||
|
public string? OldTmsi { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 临时移动用户标识
|
||||
|
/// Temporary Mobile Subscriber Identity
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("tmsi")] |
||||
|
public string? Tmsi { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 国际移动用户标识
|
||||
|
/// International Mobile Subscriber Identity
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("imsi")] |
||||
|
public string? Imsi { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 小区ID
|
||||
|
/// Cell Identifier
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("cellId")] |
||||
|
public int? CellId { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 用户设备ID
|
||||
|
/// User Equipment Identifier
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("ueId")] |
||||
|
public int? UeId { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 初始化移动用户身份信息的新实例
|
||||
|
/// </summary>
|
||||
|
public MobileUserIdentity() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 初始化移动用户身份信息的新实例
|
||||
|
/// </summary>
|
||||
|
/// <param name="plmn">公共陆地移动网络标识</param>
|
||||
|
/// <param name="oldTmsi">旧的临时移动用户标识</param>
|
||||
|
/// <param name="tmsi">临时移动用户标识</param>
|
||||
|
/// <param name="imsi">国际移动用户标识</param>
|
||||
|
/// <param name="cellId">小区ID</param>
|
||||
|
/// <param name="ueId">用户设备ID</param>
|
||||
|
public MobileUserIdentity( |
||||
|
string? plmn = null, |
||||
|
string? oldTmsi = null, |
||||
|
string? tmsi = null, |
||||
|
string? imsi = null, |
||||
|
int? cellId = null, |
||||
|
int? ueId = null) |
||||
|
{ |
||||
|
Plmn = plmn; |
||||
|
OldTmsi = oldTmsi; |
||||
|
Tmsi = tmsi; |
||||
|
Imsi = imsi; |
||||
|
CellId = cellId; |
||||
|
UeId = ueId; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 检查是否包含有效的用户身份信息
|
||||
|
/// </summary>
|
||||
|
/// <returns>是否包含有效信息</returns>
|
||||
|
public bool HasValidIdentity() |
||||
|
{ |
||||
|
return !string.IsNullOrWhiteSpace(Imsi) || |
||||
|
!string.IsNullOrWhiteSpace(Tmsi) || |
||||
|
UeId.HasValue; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 检查是否包含位置信息
|
||||
|
/// </summary>
|
||||
|
/// <returns>是否包含位置信息</returns>
|
||||
|
public bool HasLocationInfo() |
||||
|
{ |
||||
|
return !string.IsNullOrWhiteSpace(Plmn) || CellId.HasValue; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 获取用户身份摘要信息
|
||||
|
/// </summary>
|
||||
|
/// <returns>摘要信息</returns>
|
||||
|
public string GetIdentitySummary() |
||||
|
{ |
||||
|
var parts = new List<string>(); |
||||
|
|
||||
|
if (!string.IsNullOrWhiteSpace(Imsi)) |
||||
|
parts.Add($"IMSI:{Imsi}"); |
||||
|
|
||||
|
if (!string.IsNullOrWhiteSpace(Tmsi)) |
||||
|
parts.Add($"TMSI:{Tmsi}"); |
||||
|
|
||||
|
if (UeId.HasValue) |
||||
|
parts.Add($"UE:{UeId}"); |
||||
|
|
||||
|
if (!string.IsNullOrWhiteSpace(Plmn)) |
||||
|
parts.Add($"PLMN:{Plmn}"); |
||||
|
|
||||
|
if (CellId.HasValue) |
||||
|
parts.Add($"Cell:{CellId}"); |
||||
|
|
||||
|
return parts.Count > 0 ? string.Join(" | ", parts) : "No Identity Info"; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 检查TMSI是否发生变化
|
||||
|
/// </summary>
|
||||
|
/// <returns>TMSI是否发生变化</returns>
|
||||
|
public bool HasTmsiChanged() |
||||
|
{ |
||||
|
return !string.IsNullOrWhiteSpace(OldTmsi) && |
||||
|
!string.IsNullOrWhiteSpace(Tmsi) && |
||||
|
!OldTmsi.Equals(Tmsi, StringComparison.OrdinalIgnoreCase); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 创建身份信息的副本
|
||||
|
/// </summary>
|
||||
|
/// <returns>新的移动用户身份信息</returns>
|
||||
|
public MobileUserIdentity Copy() |
||||
|
{ |
||||
|
return new MobileUserIdentity |
||||
|
{ |
||||
|
Plmn = Plmn, |
||||
|
OldTmsi = OldTmsi, |
||||
|
Tmsi = Tmsi, |
||||
|
Imsi = Imsi, |
||||
|
CellId = CellId, |
||||
|
UeId = UeId |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 更新TMSI信息
|
||||
|
/// </summary>
|
||||
|
/// <param name="newTmsi">新的TMSI</param>
|
||||
|
public void UpdateTmsi(string? newTmsi) |
||||
|
{ |
||||
|
if (!string.IsNullOrWhiteSpace(Tmsi)) |
||||
|
{ |
||||
|
OldTmsi = Tmsi; |
||||
|
} |
||||
|
Tmsi = newTmsi; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 转换为JSON字符串
|
||||
|
/// </summary>
|
||||
|
/// <returns>JSON字符串</returns>
|
||||
|
public string ToJson() |
||||
|
{ |
||||
|
return JsonConvert.SerializeObject(this, Formatting.Indented); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 从JSON字符串创建移动用户身份信息
|
||||
|
/// </summary>
|
||||
|
/// <param name="json">JSON字符串</param>
|
||||
|
/// <returns>移动用户身份信息</returns>
|
||||
|
public static MobileUserIdentity FromJson(string json) |
||||
|
{ |
||||
|
return JsonConvert.DeserializeObject<MobileUserIdentity>(json) ?? new MobileUserIdentity(); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 重写ToString方法
|
||||
|
/// </summary>
|
||||
|
/// <returns>字符串表示</returns>
|
||||
|
public override string ToString() |
||||
|
{ |
||||
|
return GetIdentitySummary(); |
||||
|
} |
||||
|
} |
@ -0,0 +1,242 @@ |
|||||
|
namespace CoreAgent.Domain.Models.Protocol; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 协议层类型枚举
|
||||
|
/// 定义了系统中支持的各种协议层类型
|
||||
|
/// 遵循DDD(领域驱动设计)原则,作为领域模型的一部分
|
||||
|
/// </summary>
|
||||
|
public enum ProtocolLayerType |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 无协议层类型
|
||||
|
/// </summary>
|
||||
|
NONE = 0, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// GTP-U协议层
|
||||
|
/// GPRS Tunnelling Protocol User Plane
|
||||
|
/// </summary>
|
||||
|
GTPU = 1, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// LPPa协议层
|
||||
|
/// LTE Positioning Protocol Annex
|
||||
|
/// </summary>
|
||||
|
LPPa = 2, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// M2AP协议层
|
||||
|
/// M2 Application Protocol
|
||||
|
/// </summary>
|
||||
|
M2AP = 3, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// MAC协议层
|
||||
|
/// Medium Access Control
|
||||
|
/// </summary>
|
||||
|
MAC = 4, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// NAS协议层
|
||||
|
/// Non-Access Stratum
|
||||
|
/// </summary>
|
||||
|
NAS = 5, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// NGAP协议层
|
||||
|
/// Next Generation Application Protocol
|
||||
|
/// </summary>
|
||||
|
NGAP = 6, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// NRPPa协议层
|
||||
|
/// NR Positioning Protocol Annex
|
||||
|
/// </summary>
|
||||
|
NRPPa = 7, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// PDCP协议层
|
||||
|
/// Packet Data Convergence Protocol
|
||||
|
/// </summary>
|
||||
|
PDCP = 8, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// PROD协议层
|
||||
|
/// Production Protocol
|
||||
|
/// </summary>
|
||||
|
PROD = 9, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// PHY协议层
|
||||
|
/// Physical Layer
|
||||
|
/// </summary>
|
||||
|
PHY = 10, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// RLC协议层
|
||||
|
/// Radio Link Control
|
||||
|
/// </summary>
|
||||
|
RLC = 11, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// RRC协议层
|
||||
|
/// Radio Resource Control
|
||||
|
/// </summary>
|
||||
|
RRC = 12, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// S1AP协议层
|
||||
|
/// S1 Application Protocol
|
||||
|
/// </summary>
|
||||
|
S1AP = 13, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// TRX协议层
|
||||
|
/// Transceiver Protocol
|
||||
|
/// </summary>
|
||||
|
TRX = 14, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// X2AP协议层
|
||||
|
/// X2 Application Protocol
|
||||
|
/// </summary>
|
||||
|
X2AP = 15, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// XnAP协议层
|
||||
|
/// Xn Application Protocol
|
||||
|
/// </summary>
|
||||
|
XnAP = 16, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// IP协议层
|
||||
|
/// Internet Protocol
|
||||
|
/// </summary>
|
||||
|
IP = 17, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// IMS协议层
|
||||
|
/// IP Multimedia Subsystem
|
||||
|
/// </summary>
|
||||
|
IMS = 18, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// CX协议层
|
||||
|
/// Diameter CX Interface
|
||||
|
/// </summary>
|
||||
|
CX = 19, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// RX协议层
|
||||
|
/// Diameter RX Interface
|
||||
|
/// </summary>
|
||||
|
RX = 20, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// S6协议层
|
||||
|
/// Diameter S6 Interface
|
||||
|
/// </summary>
|
||||
|
S6 = 21, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// S13协议层
|
||||
|
/// Diameter S13 Interface
|
||||
|
/// </summary>
|
||||
|
S13 = 22, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// SGsAP协议层
|
||||
|
/// SGs Application Protocol
|
||||
|
/// </summary>
|
||||
|
SGsAP = 23, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// SBcAP协议层
|
||||
|
/// SBc Application Protocol
|
||||
|
/// </summary>
|
||||
|
SBcAP = 24, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// LCSAP协议层
|
||||
|
/// LCS Application Protocol
|
||||
|
/// </summary>
|
||||
|
LCSAP = 25, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// N12协议层
|
||||
|
/// Diameter N12 Interface
|
||||
|
/// </summary>
|
||||
|
N12 = 26, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// N8协议层
|
||||
|
/// Diameter N8 Interface
|
||||
|
/// </summary>
|
||||
|
N8 = 27, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// N17协议层
|
||||
|
/// Diameter N17 Interface
|
||||
|
/// </summary>
|
||||
|
N17 = 28, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// N50协议层
|
||||
|
/// Diameter N50 Interface
|
||||
|
/// </summary>
|
||||
|
N50 = 29, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// N13协议层
|
||||
|
/// Diameter N13 Interface
|
||||
|
/// </summary>
|
||||
|
N13 = 30, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// NL1协议层
|
||||
|
/// Network Layer 1
|
||||
|
/// </summary>
|
||||
|
NL1 = 31, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// HTTP2协议层
|
||||
|
/// Hypertext Transfer Protocol 2
|
||||
|
/// </summary>
|
||||
|
HTTP2 = 32, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// EPDG协议层
|
||||
|
/// Evolved Packet Data Gateway
|
||||
|
/// </summary>
|
||||
|
EPDG = 33, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// IKEV2协议层
|
||||
|
/// Internet Key Exchange Version 2
|
||||
|
/// </summary>
|
||||
|
IKEV2 = 34, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// IPSEC协议层
|
||||
|
/// Internet Protocol Security
|
||||
|
/// </summary>
|
||||
|
IPSEC = 35, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// MEDIA协议层
|
||||
|
/// Media Protocol
|
||||
|
/// </summary>
|
||||
|
MEDIA = 36, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// MMS协议层
|
||||
|
/// Multimedia Messaging Service
|
||||
|
/// </summary>
|
||||
|
MMS = 37, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// SIP协议层
|
||||
|
/// Session Initiation Protocol
|
||||
|
/// </summary>
|
||||
|
SIP = 38 |
||||
|
} |
@ -0,0 +1,258 @@ |
|||||
|
using System.ComponentModel; |
||||
|
using System.Reflection; |
||||
|
|
||||
|
namespace CoreAgent.Domain.Models.Protocol; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// ProtocolLayerType 枚举扩展方法
|
||||
|
/// 提供协议层类型的实用功能
|
||||
|
/// </summary>
|
||||
|
public static class ProtocolLayerTypeExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 获取协议层类型的描述信息
|
||||
|
/// </summary>
|
||||
|
/// <param name="protocolLayerType">协议层类型</param>
|
||||
|
/// <returns>描述信息</returns>
|
||||
|
public static string GetDescription(this ProtocolLayerType protocolLayerType) |
||||
|
{ |
||||
|
var field = protocolLayerType.GetType().GetField(protocolLayerType.ToString()); |
||||
|
var attribute = field?.GetCustomAttribute<DescriptionAttribute>(); |
||||
|
return attribute?.Description ?? protocolLayerType.ToString(); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 获取协议层类型的显示名称
|
||||
|
/// </summary>
|
||||
|
/// <param name="protocolLayerType">协议层类型</param>
|
||||
|
/// <returns>显示名称</returns>
|
||||
|
public static string GetDisplayName(this ProtocolLayerType protocolLayerType) |
||||
|
{ |
||||
|
return protocolLayerType switch |
||||
|
{ |
||||
|
ProtocolLayerType.NONE => "无", |
||||
|
ProtocolLayerType.GTPU => "GTP-U", |
||||
|
ProtocolLayerType.LPPa => "LPPa", |
||||
|
ProtocolLayerType.M2AP => "M2AP", |
||||
|
ProtocolLayerType.MAC => "MAC", |
||||
|
ProtocolLayerType.NAS => "NAS", |
||||
|
ProtocolLayerType.NGAP => "NGAP", |
||||
|
ProtocolLayerType.NRPPa => "NRPPa", |
||||
|
ProtocolLayerType.PDCP => "PDCP", |
||||
|
ProtocolLayerType.PROD => "PROD", |
||||
|
ProtocolLayerType.PHY => "PHY", |
||||
|
ProtocolLayerType.RLC => "RLC", |
||||
|
ProtocolLayerType.RRC => "RRC", |
||||
|
ProtocolLayerType.S1AP => "S1AP", |
||||
|
ProtocolLayerType.TRX => "TRX", |
||||
|
ProtocolLayerType.X2AP => "X2AP", |
||||
|
ProtocolLayerType.XnAP => "XnAP", |
||||
|
ProtocolLayerType.IP => "IP", |
||||
|
ProtocolLayerType.IMS => "IMS", |
||||
|
ProtocolLayerType.CX => "CX", |
||||
|
ProtocolLayerType.RX => "RX", |
||||
|
ProtocolLayerType.S6 => "S6", |
||||
|
ProtocolLayerType.S13 => "S13", |
||||
|
ProtocolLayerType.SGsAP => "SGsAP", |
||||
|
ProtocolLayerType.SBcAP => "SBcAP", |
||||
|
ProtocolLayerType.LCSAP => "LCSAP", |
||||
|
ProtocolLayerType.N12 => "N12", |
||||
|
ProtocolLayerType.N8 => "N8", |
||||
|
ProtocolLayerType.N17 => "N17", |
||||
|
ProtocolLayerType.N50 => "N50", |
||||
|
ProtocolLayerType.N13 => "N13", |
||||
|
ProtocolLayerType.NL1 => "NL1", |
||||
|
ProtocolLayerType.HTTP2 => "HTTP/2", |
||||
|
ProtocolLayerType.EPDG => "EPDG", |
||||
|
ProtocolLayerType.IKEV2 => "IKEv2", |
||||
|
ProtocolLayerType.IPSEC => "IPSec", |
||||
|
ProtocolLayerType.MEDIA => "MEDIA", |
||||
|
ProtocolLayerType.MMS => "MMS", |
||||
|
ProtocolLayerType.SIP => "SIP", |
||||
|
_ => protocolLayerType.ToString() |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 判断是否为RAN相关协议层
|
||||
|
/// </summary>
|
||||
|
/// <param name="protocolLayerType">协议层类型</param>
|
||||
|
/// <returns>是否为RAN协议层</returns>
|
||||
|
public static bool IsRanProtocol(this ProtocolLayerType protocolLayerType) |
||||
|
{ |
||||
|
return protocolLayerType switch |
||||
|
{ |
||||
|
ProtocolLayerType.GTPU or |
||||
|
ProtocolLayerType.LPPa or |
||||
|
ProtocolLayerType.M2AP or |
||||
|
ProtocolLayerType.MAC or |
||||
|
ProtocolLayerType.NAS or |
||||
|
ProtocolLayerType.NGAP or |
||||
|
ProtocolLayerType.NRPPa or |
||||
|
ProtocolLayerType.PDCP or |
||||
|
ProtocolLayerType.PHY or |
||||
|
ProtocolLayerType.RLC or |
||||
|
ProtocolLayerType.RRC or |
||||
|
ProtocolLayerType.S1AP or |
||||
|
ProtocolLayerType.TRX or |
||||
|
ProtocolLayerType.X2AP or |
||||
|
ProtocolLayerType.XnAP => true, |
||||
|
_ => false |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 判断是否为IMS相关协议层
|
||||
|
/// </summary>
|
||||
|
/// <param name="protocolLayerType">协议层类型</param>
|
||||
|
/// <returns>是否为IMS协议层</returns>
|
||||
|
public static bool IsImsProtocol(this ProtocolLayerType protocolLayerType) |
||||
|
{ |
||||
|
return protocolLayerType switch |
||||
|
{ |
||||
|
ProtocolLayerType.IMS or |
||||
|
ProtocolLayerType.CX or |
||||
|
ProtocolLayerType.RX or |
||||
|
ProtocolLayerType.S6 or |
||||
|
ProtocolLayerType.S13 or |
||||
|
ProtocolLayerType.SGsAP or |
||||
|
ProtocolLayerType.SBcAP or |
||||
|
ProtocolLayerType.LCSAP or |
||||
|
ProtocolLayerType.N12 or |
||||
|
ProtocolLayerType.N8 or |
||||
|
ProtocolLayerType.N17 or |
||||
|
ProtocolLayerType.N50 or |
||||
|
ProtocolLayerType.N13 or |
||||
|
ProtocolLayerType.HTTP2 or |
||||
|
ProtocolLayerType.EPDG or |
||||
|
ProtocolLayerType.IKEV2 or |
||||
|
ProtocolLayerType.IPSEC or |
||||
|
ProtocolLayerType.MEDIA or |
||||
|
ProtocolLayerType.MMS or |
||||
|
ProtocolLayerType.SIP => true, |
||||
|
_ => false |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 判断是否为Diameter协议层
|
||||
|
/// </summary>
|
||||
|
/// <param name="protocolLayerType">协议层类型</param>
|
||||
|
/// <returns>是否为Diameter协议层</returns>
|
||||
|
public static bool IsDiameterProtocol(this ProtocolLayerType protocolLayerType) |
||||
|
{ |
||||
|
return protocolLayerType switch |
||||
|
{ |
||||
|
ProtocolLayerType.CX or |
||||
|
ProtocolLayerType.RX or |
||||
|
ProtocolLayerType.S6 or |
||||
|
ProtocolLayerType.S13 or |
||||
|
ProtocolLayerType.N12 or |
||||
|
ProtocolLayerType.N8 or |
||||
|
ProtocolLayerType.N17 or |
||||
|
ProtocolLayerType.N50 or |
||||
|
ProtocolLayerType.N13 => true, |
||||
|
_ => false |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 获取协议层类型的分类
|
||||
|
/// </summary>
|
||||
|
/// <param name="protocolLayerType">协议层类型</param>
|
||||
|
/// <returns>协议层分类</returns>
|
||||
|
public static string GetCategory(this ProtocolLayerType protocolLayerType) |
||||
|
{ |
||||
|
return protocolLayerType switch |
||||
|
{ |
||||
|
ProtocolLayerType.NONE => "None", |
||||
|
ProtocolLayerType.GTPU or |
||||
|
ProtocolLayerType.LPPa or |
||||
|
ProtocolLayerType.M2AP or |
||||
|
ProtocolLayerType.MAC or |
||||
|
ProtocolLayerType.NAS or |
||||
|
ProtocolLayerType.NGAP or |
||||
|
ProtocolLayerType.NRPPa or |
||||
|
ProtocolLayerType.PDCP or |
||||
|
ProtocolLayerType.PHY or |
||||
|
ProtocolLayerType.RLC or |
||||
|
ProtocolLayerType.RRC or |
||||
|
ProtocolLayerType.S1AP or |
||||
|
ProtocolLayerType.TRX or |
||||
|
ProtocolLayerType.X2AP or |
||||
|
ProtocolLayerType.XnAP => "RAN", |
||||
|
ProtocolLayerType.IMS or |
||||
|
ProtocolLayerType.CX or |
||||
|
ProtocolLayerType.RX or |
||||
|
ProtocolLayerType.S6 or |
||||
|
ProtocolLayerType.S13 or |
||||
|
ProtocolLayerType.SGsAP or |
||||
|
ProtocolLayerType.SBcAP or |
||||
|
ProtocolLayerType.LCSAP or |
||||
|
ProtocolLayerType.N12 or |
||||
|
ProtocolLayerType.N8 or |
||||
|
ProtocolLayerType.N17 or |
||||
|
ProtocolLayerType.N50 or |
||||
|
ProtocolLayerType.N13 or |
||||
|
ProtocolLayerType.HTTP2 or |
||||
|
ProtocolLayerType.EPDG or |
||||
|
ProtocolLayerType.IKEV2 or |
||||
|
ProtocolLayerType.IPSEC or |
||||
|
ProtocolLayerType.MEDIA or |
||||
|
ProtocolLayerType.MMS or |
||||
|
ProtocolLayerType.SIP => "IMS", |
||||
|
ProtocolLayerType.IP => "Network", |
||||
|
ProtocolLayerType.NL1 => "Network", |
||||
|
ProtocolLayerType.PROD => "Production", |
||||
|
_ => "Other" |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 从字符串转换为ProtocolLayerType枚举
|
||||
|
/// </summary>
|
||||
|
/// <param name="value">字符串值</param>
|
||||
|
/// <returns>ProtocolLayerType枚举值,如果转换失败返回NONE</returns>
|
||||
|
public static ProtocolLayerType FromString(string value) |
||||
|
{ |
||||
|
if (string.IsNullOrWhiteSpace(value)) |
||||
|
return ProtocolLayerType.NONE; |
||||
|
|
||||
|
return Enum.TryParse<ProtocolLayerType>(value, true, out var result) |
||||
|
? result |
||||
|
: ProtocolLayerType.NONE; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 获取所有RAN协议层类型
|
||||
|
/// </summary>
|
||||
|
/// <returns>RAN协议层类型数组</returns>
|
||||
|
public static ProtocolLayerType[] GetRanProtocols() |
||||
|
{ |
||||
|
return Enum.GetValues<ProtocolLayerType>() |
||||
|
.Where(p => p.IsRanProtocol()) |
||||
|
.ToArray(); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 获取所有IMS协议层类型
|
||||
|
/// </summary>
|
||||
|
/// <returns>IMS协议层类型数组</returns>
|
||||
|
public static ProtocolLayerType[] GetImsProtocols() |
||||
|
{ |
||||
|
return Enum.GetValues<ProtocolLayerType>() |
||||
|
.Where(p => p.IsImsProtocol()) |
||||
|
.ToArray(); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 获取所有Diameter协议层类型
|
||||
|
/// </summary>
|
||||
|
/// <returns>Diameter协议层类型数组</returns>
|
||||
|
public static ProtocolLayerType[] GetDiameterProtocols() |
||||
|
{ |
||||
|
return Enum.GetValues<ProtocolLayerType>() |
||||
|
.Where(p => p.IsDiameterProtocol()) |
||||
|
.ToArray(); |
||||
|
} |
||||
|
} |
@ -0,0 +1,338 @@ |
|||||
|
using Newtonsoft.Json; |
||||
|
|
||||
|
namespace CoreAgent.Domain.Models.Protocol; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 协议日志解析结果
|
||||
|
/// 用于存储ProtocolLog解析后的分析结果,用于数据传输和处理
|
||||
|
/// 遵循DDD(领域驱动设计)原则,作为领域模型的一部分
|
||||
|
/// </summary>
|
||||
|
public class ProtocolLogParsedResult |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 唯一标识符
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("id")] |
||||
|
public string Id { get; set; } = Guid.NewGuid().ToString(); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 日志索引
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("index")] |
||||
|
public int? Index { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 消息ID
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("messageId")] |
||||
|
public int? MessageId { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 协议层类型
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("protocolLayer")] |
||||
|
public ProtocolLayerType ProtocolLayer { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 协议类型描述
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("protocolType")] |
||||
|
public string ProtocolType { get; set; } = string.Empty; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 用户设备ID
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("ueId")] |
||||
|
public int? UeId { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 公共陆地移动网络标识
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("plmn")] |
||||
|
public string? Plmn { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 临时移动用户标识
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("tmsi")] |
||||
|
public string? Tmsi { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 国际移动设备标识
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("imei")] |
||||
|
public string? Imei { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 国际移动用户标识
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("imsi")] |
||||
|
public string? Imsi { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 小区ID
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("cellId")] |
||||
|
public int? CellId { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 小区信息
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("cell")] |
||||
|
public string? Cell { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 日志信息
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("info")] |
||||
|
public string? Info { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 消息内容
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("message")] |
||||
|
public string? Message { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 消息数据数组
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("messageData")] |
||||
|
public string[]? MessageData { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 时间间隔
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("time")] |
||||
|
public TimeSpan Time { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 时间戳
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("timestamp")] |
||||
|
public long Timestamp { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 日志方向
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("direction")] |
||||
|
public DirectionLogsType Direction { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 协议层分类
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("category")] |
||||
|
public string Category => ProtocolLayer.GetCategory(); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 协议层显示名称
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("displayName")] |
||||
|
public string DisplayName => ProtocolLayer.GetDisplayName(); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 初始化协议日志解析结果的新实例
|
||||
|
/// </summary>
|
||||
|
public ProtocolLogParsedResult() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 初始化协议日志解析结果的新实例
|
||||
|
/// </summary>
|
||||
|
/// <param name="messageId">消息ID</param>
|
||||
|
/// <param name="index">日志索引</param>
|
||||
|
/// <param name="protocolLayer">协议层类型</param>
|
||||
|
/// <param name="ueId">用户设备ID</param>
|
||||
|
/// <param name="plmn">公共陆地移动网络标识</param>
|
||||
|
/// <param name="tmsi">临时移动用户标识</param>
|
||||
|
/// <param name="imei">国际移动设备标识</param>
|
||||
|
/// <param name="imsi">国际移动用户标识</param>
|
||||
|
/// <param name="cellId">小区ID</param>
|
||||
|
/// <param name="cell">小区信息</param>
|
||||
|
/// <param name="info">日志信息</param>
|
||||
|
/// <param name="message">消息内容</param>
|
||||
|
/// <param name="messageData">消息数据数组</param>
|
||||
|
/// <param name="direction">日志方向</param>
|
||||
|
public ProtocolLogParsedResult( |
||||
|
int? messageId = null, |
||||
|
int? index = null, |
||||
|
ProtocolLayerType protocolLayer = ProtocolLayerType.NONE, |
||||
|
int? ueId = null, |
||||
|
string? plmn = null, |
||||
|
string? tmsi = null, |
||||
|
string? imei = null, |
||||
|
string? imsi = null, |
||||
|
int? cellId = null, |
||||
|
string? cell = null, |
||||
|
string? info = null, |
||||
|
string? message = null, |
||||
|
string[]? messageData = null, |
||||
|
DirectionLogsType direction = DirectionLogsType.Unknown) |
||||
|
{ |
||||
|
MessageId = messageId; |
||||
|
Index = index; |
||||
|
ProtocolLayer = protocolLayer; |
||||
|
UeId = ueId; |
||||
|
Plmn = plmn; |
||||
|
Tmsi = tmsi; |
||||
|
Imei = imei; |
||||
|
Imsi = imsi; |
||||
|
CellId = cellId; |
||||
|
Cell = cell; |
||||
|
Info = info; |
||||
|
Message = message; |
||||
|
MessageData = messageData; |
||||
|
Direction = direction; |
||||
|
ProtocolType = protocolLayer.GetDisplayName(); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 从ProtocolLog创建ProtocolLogParsedResult
|
||||
|
/// </summary>
|
||||
|
/// <param name="protocolLog">协议日志</param>
|
||||
|
/// <param name="index">日志索引</param>
|
||||
|
/// <returns>协议日志解析结果</returns>
|
||||
|
public static ProtocolLogParsedResult FromProtocolLog(ProtocolLog protocolLog, int? index = null) |
||||
|
{ |
||||
|
// 处理时间戳转换
|
||||
|
long timestamp; |
||||
|
if (protocolLog.Time.HasValue) |
||||
|
{ |
||||
|
// 如果 Time 是秒为单位,转换为毫秒
|
||||
|
timestamp = (long)(protocolLog.Time.Value * 1000); |
||||
|
} |
||||
|
else if (protocolLog.Utc.HasValue) |
||||
|
{ |
||||
|
// 如果 Utc 是秒为单位,转换为毫秒
|
||||
|
timestamp = (long)(protocolLog.Utc.Value * 1000); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
// 默认使用当前时间
|
||||
|
timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); |
||||
|
} |
||||
|
|
||||
|
return new ProtocolLogParsedResult |
||||
|
{ |
||||
|
MessageId = protocolLog.MessageId, |
||||
|
Index = index, |
||||
|
ProtocolLayer = ProtocolLayerType.NONE, // 需要根据实际内容解析
|
||||
|
Message = protocolLog.Message, |
||||
|
MessageData = protocolLog.Headers, |
||||
|
Timestamp = timestamp, |
||||
|
Time = TimeSpan.FromMilliseconds(protocolLog.Time ?? 0), |
||||
|
Direction = DirectionLogsType.Unknown, |
||||
|
ProtocolType = protocolLog.Type ?? string.Empty |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 从ProtocolLogDetail创建ProtocolLogParsedResult
|
||||
|
/// </summary>
|
||||
|
/// <param name="detail">协议日志明细</param>
|
||||
|
/// <param name="index">日志索引</param>
|
||||
|
/// <returns>协议日志解析结果</returns>
|
||||
|
public static ProtocolLogParsedResult FromProtocolLogDetail(ProtocolLogDetail detail, int? index = null) |
||||
|
{ |
||||
|
return new ProtocolLogParsedResult |
||||
|
{ |
||||
|
Index = index ?? detail.Idx, |
||||
|
ProtocolLayer = ProtocolLayerTypeExtensions.FromString(detail.Layer), |
||||
|
UeId = detail.UeId, |
||||
|
CellId = detail.Cell, |
||||
|
Info = detail.Src, |
||||
|
MessageData = detail.Data?.ToArray(), |
||||
|
Timestamp = detail.Timestamp, |
||||
|
Time = TimeSpan.FromMilliseconds(detail.Timestamp), |
||||
|
Direction = ParseDirection(detail.Dir), |
||||
|
ProtocolType = detail.Layer |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 解析方向字符串为DirectionLogsType
|
||||
|
/// </summary>
|
||||
|
/// <param name="direction">方向字符串</param>
|
||||
|
/// <returns>方向类型</returns>
|
||||
|
private static DirectionLogsType ParseDirection(string? direction) |
||||
|
{ |
||||
|
if (string.IsNullOrWhiteSpace(direction)) |
||||
|
return DirectionLogsType.Unknown; |
||||
|
|
||||
|
return direction.ToLower() switch |
||||
|
{ |
||||
|
"up" or "uplink" or "ul" => DirectionLogsType.Uplink, |
||||
|
"down" or "downlink" or "dl" => DirectionLogsType.Downlink, |
||||
|
"bidirectional" or "bi" => DirectionLogsType.Bidirectional, |
||||
|
"internal" or "int" => DirectionLogsType.Internal, |
||||
|
_ => DirectionLogsType.Unknown |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 检查解析结果是否包含有效数据
|
||||
|
/// </summary>
|
||||
|
/// <returns>是否包含有效数据</returns>
|
||||
|
public bool HasValidData() |
||||
|
{ |
||||
|
return !string.IsNullOrEmpty(Id) && |
||||
|
(ProtocolLayer != ProtocolLayerType.NONE || !string.IsNullOrEmpty(ProtocolType)); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 获取解析结果摘要信息
|
||||
|
/// </summary>
|
||||
|
/// <returns>摘要信息</returns>
|
||||
|
public string GetSummary() |
||||
|
{ |
||||
|
return $"ProtocolLogParsed[{Id}] - {ProtocolLayer.GetDisplayName()} - {Direction} - UE:{UeId} - Cell:{CellId}"; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 创建解析结果的副本
|
||||
|
/// </summary>
|
||||
|
/// <returns>新的协议日志解析结果</returns>
|
||||
|
public ProtocolLogParsedResult Copy() |
||||
|
{ |
||||
|
return new ProtocolLogParsedResult |
||||
|
{ |
||||
|
Id = Guid.NewGuid().ToString(), // 生成新的ID
|
||||
|
Index = Index, |
||||
|
MessageId = MessageId, |
||||
|
ProtocolLayer = ProtocolLayer, |
||||
|
ProtocolType = ProtocolType, |
||||
|
UeId = UeId, |
||||
|
Plmn = Plmn, |
||||
|
Tmsi = Tmsi, |
||||
|
Imei = Imei, |
||||
|
Imsi = Imsi, |
||||
|
CellId = CellId, |
||||
|
Cell = Cell, |
||||
|
Info = Info, |
||||
|
Message = Message, |
||||
|
MessageData = MessageData?.Clone() as string[], |
||||
|
Time = Time, |
||||
|
Timestamp = Timestamp, |
||||
|
Direction = Direction |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 转换为JSON字符串
|
||||
|
/// </summary>
|
||||
|
/// <returns>JSON字符串</returns>
|
||||
|
public string ToJson() |
||||
|
{ |
||||
|
return JsonConvert.SerializeObject(this, Formatting.Indented); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 从JSON字符串创建解析结果
|
||||
|
/// </summary>
|
||||
|
/// <param name="json">JSON字符串</param>
|
||||
|
/// <returns>协议日志解析结果</returns>
|
||||
|
public static ProtocolLogParsedResult FromJson(string json) |
||||
|
{ |
||||
|
return JsonConvert.DeserializeObject<ProtocolLogParsedResult>(json) ?? new ProtocolLogParsedResult(); |
||||
|
} |
||||
|
} |
@ -0,0 +1,219 @@ |
|||||
|
using Newtonsoft.Json; |
||||
|
|
||||
|
namespace CoreAgent.Domain.Models.Protocol; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 用户网络身份信息
|
||||
|
/// 用于存储移动网络用户的基本身份和位置信息
|
||||
|
/// 遵循DDD(领域驱动设计)原则,作为领域模型的一部分
|
||||
|
/// </summary>
|
||||
|
public class UserNetworkIdentity |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 公共陆地移动网络标识
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("plmn")] |
||||
|
public string? Plmn { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 旧的临时移动用户标识
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("oldTmsi")] |
||||
|
public string? OldTmsi { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 临时移动用户标识
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("tmsi")] |
||||
|
public string? Tmsi { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 国际移动用户标识
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("imsi")] |
||||
|
public string? Imsi { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 小区ID
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("cellId")] |
||||
|
public int? CellId { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 用户设备ID
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("ueId")] |
||||
|
public int? UeId { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 初始化用户网络身份信息的新实例
|
||||
|
/// </summary>
|
||||
|
public UserNetworkIdentity() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 初始化用户网络身份信息的新实例
|
||||
|
/// </summary>
|
||||
|
/// <param name="plmn">公共陆地移动网络标识</param>
|
||||
|
/// <param name="oldTmsi">旧的临时移动用户标识</param>
|
||||
|
/// <param name="tmsi">临时移动用户标识</param>
|
||||
|
/// <param name="imsi">国际移动用户标识</param>
|
||||
|
/// <param name="cellId">小区ID</param>
|
||||
|
/// <param name="ueId">用户设备ID</param>
|
||||
|
public UserNetworkIdentity( |
||||
|
string? plmn = null, |
||||
|
string? oldTmsi = null, |
||||
|
string? tmsi = null, |
||||
|
string? imsi = null, |
||||
|
int? cellId = null, |
||||
|
int? ueId = null) |
||||
|
{ |
||||
|
Plmn = plmn; |
||||
|
OldTmsi = oldTmsi; |
||||
|
Tmsi = tmsi; |
||||
|
Imsi = imsi; |
||||
|
CellId = cellId; |
||||
|
UeId = ueId; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 检查是否包含有效的用户身份信息
|
||||
|
/// </summary>
|
||||
|
/// <returns>是否包含有效信息</returns>
|
||||
|
public bool HasValidIdentity() |
||||
|
{ |
||||
|
return !string.IsNullOrWhiteSpace(Imsi) || |
||||
|
!string.IsNullOrWhiteSpace(Tmsi) || |
||||
|
UeId.HasValue; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 检查是否包含位置信息
|
||||
|
/// </summary>
|
||||
|
/// <returns>是否包含位置信息</returns>
|
||||
|
public bool HasLocationInfo() |
||||
|
{ |
||||
|
return !string.IsNullOrWhiteSpace(Plmn) || CellId.HasValue; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 获取用户身份摘要信息
|
||||
|
/// </summary>
|
||||
|
/// <returns>摘要信息</returns>
|
||||
|
public string GetIdentitySummary() |
||||
|
{ |
||||
|
var parts = new List<string>(); |
||||
|
|
||||
|
if (!string.IsNullOrWhiteSpace(Imsi)) |
||||
|
parts.Add($"IMSI:{Imsi}"); |
||||
|
|
||||
|
if (!string.IsNullOrWhiteSpace(Tmsi)) |
||||
|
parts.Add($"TMSI:{Tmsi}"); |
||||
|
|
||||
|
if (UeId.HasValue) |
||||
|
parts.Add($"UE:{UeId}"); |
||||
|
|
||||
|
if (!string.IsNullOrWhiteSpace(Plmn)) |
||||
|
parts.Add($"PLMN:{Plmn}"); |
||||
|
|
||||
|
if (CellId.HasValue) |
||||
|
parts.Add($"Cell:{CellId}"); |
||||
|
|
||||
|
return parts.Count > 0 ? string.Join(" | ", parts) : "No Identity Info"; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 检查TMSI是否发生变化
|
||||
|
/// </summary>
|
||||
|
/// <returns>TMSI是否发生变化</returns>
|
||||
|
public bool HasTmsiChanged() |
||||
|
{ |
||||
|
return !string.IsNullOrWhiteSpace(OldTmsi) && |
||||
|
!string.IsNullOrWhiteSpace(Tmsi) && |
||||
|
!OldTmsi.Equals(Tmsi, StringComparison.OrdinalIgnoreCase); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 获取TMSI变化信息
|
||||
|
/// </summary>
|
||||
|
/// <returns>TMSI变化信息</returns>
|
||||
|
public string GetTmsiChangeInfo() |
||||
|
{ |
||||
|
if (HasTmsiChanged()) |
||||
|
{ |
||||
|
return $"TMSI Changed: {OldTmsi} -> {Tmsi}"; |
||||
|
} |
||||
|
return "TMSI Unchanged"; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 创建用户网络身份信息的副本
|
||||
|
/// </summary>
|
||||
|
/// <returns>新的用户网络身份信息</returns>
|
||||
|
public UserNetworkIdentity Copy() |
||||
|
{ |
||||
|
return new UserNetworkIdentity |
||||
|
{ |
||||
|
Plmn = Plmn, |
||||
|
OldTmsi = OldTmsi, |
||||
|
Tmsi = Tmsi, |
||||
|
Imsi = Imsi, |
||||
|
CellId = CellId, |
||||
|
UeId = UeId |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 更新TMSI信息
|
||||
|
/// </summary>
|
||||
|
/// <param name="newTmsi">新的TMSI</param>
|
||||
|
public void UpdateTmsi(string? newTmsi) |
||||
|
{ |
||||
|
if (!string.IsNullOrWhiteSpace(Tmsi)) |
||||
|
{ |
||||
|
OldTmsi = Tmsi; |
||||
|
} |
||||
|
Tmsi = newTmsi; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 转换为JSON字符串
|
||||
|
/// </summary>
|
||||
|
/// <returns>JSON字符串</returns>
|
||||
|
public string ToJson() |
||||
|
{ |
||||
|
return JsonConvert.SerializeObject(this, Formatting.Indented); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 从JSON字符串创建用户网络身份信息
|
||||
|
/// </summary>
|
||||
|
/// <param name="json">JSON字符串</param>
|
||||
|
/// <returns>用户网络身份信息</returns>
|
||||
|
public static UserNetworkIdentity FromJson(string json) |
||||
|
{ |
||||
|
return JsonConvert.DeserializeObject<UserNetworkIdentity>(json) ?? new UserNetworkIdentity(); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 合并另一个用户网络身份信息
|
||||
|
/// </summary>
|
||||
|
/// <param name="other">另一个用户网络身份信息</param>
|
||||
|
/// <returns>合并后的用户网络身份信息</returns>
|
||||
|
public UserNetworkIdentity Merge(UserNetworkIdentity other) |
||||
|
{ |
||||
|
if (other == null) |
||||
|
return this; |
||||
|
|
||||
|
return new UserNetworkIdentity |
||||
|
{ |
||||
|
Plmn = Plmn ?? other.Plmn, |
||||
|
OldTmsi = OldTmsi ?? other.OldTmsi, |
||||
|
Tmsi = Tmsi ?? other.Tmsi, |
||||
|
Imsi = Imsi ?? other.Imsi, |
||||
|
CellId = CellId ?? other.CellId, |
||||
|
UeId = UeId ?? other.UeId |
||||
|
}; |
||||
|
} |
||||
|
} |
@ -0,0 +1,83 @@ |
|||||
|
using CoreAgent.Domain.Helpers; |
||||
|
using CoreAgent.Domain.Interfaces.ProtocolLogHandlers; |
||||
|
using CoreAgent.Domain.Models.Protocol; |
||||
|
using Microsoft.Extensions.Logging; |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Text; |
||||
|
using System.Text.RegularExpressions; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace CoreAgent.Infrastructure.Services.ProtocolLogHandlers |
||||
|
{ |
||||
|
|
||||
|
|
||||
|
|
||||
|
public class ProtocolLogsParesRanHandle : ProtocolParesHandleLogs |
||||
|
{ |
||||
|
private readonly ILogger logger; |
||||
|
private readonly IProtocolLogsProviderObserver observer; |
||||
|
public ProtocolLogsParesRanHandle(IProtocolLogsProviderObserver observer, ILogger logger) |
||||
|
{ |
||||
|
this.observer = observer; |
||||
|
this.logger = logger; |
||||
|
} |
||||
|
|
||||
|
public override async Task GetTryParesLogDataHandle(ProtocolLog model) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
if (model is { Logs: null }) |
||||
|
{ |
||||
|
logger.LogError($"logs is null =====>GetTryParesLogDataHandle Data {model?.ObjToJson()}"); |
||||
|
return; |
||||
|
} |
||||
|
var ParseJsonData = model.Logs.ToString().JsonToObj<ProtocolLogDetail[]>(); |
||||
|
var parseResultData = LogParsedResultHandle(ParseJsonData, (model.MessageId ?? 0)); |
||||
|
//if (parseResultData.Any())
|
||||
|
//{
|
||||
|
// var MsgData = new { data = parseResultData, MessageType = CSCIMessageType.ProtocolLogsRAN }.ObjToJson();
|
||||
|
// logger.LogInformation($"OnData:{MsgData}");
|
||||
|
// observer.OnData(MsgData);
|
||||
|
//}
|
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
logger.LogError($"GetTryParesLogDataHandle Data {model?.ObjToJson()}"); |
||||
|
logger.LogError(ex.ToString()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public ProtocolLogParsedResult[] LogParsedResultHandle(ProtocolLogDetail[] logDetails, int MessageId) |
||||
|
{ |
||||
|
List<ProtocolLogParsedResult> parsedResults = new List<ProtocolLogParsedResult>(); |
||||
|
|
||||
|
return parsedResults.ToArray(); |
||||
|
} |
||||
|
|
||||
|
public void LogListParse(ProtocolLogDetail[] list) |
||||
|
{ |
||||
|
int length = list.Length; |
||||
|
for (int i = 0; i < length; i++) |
||||
|
{ |
||||
|
var log= list[i]; |
||||
|
switch (log.Layer) |
||||
|
{ |
||||
|
case "PHY": |
||||
|
break; |
||||
|
case "MAC": |
||||
|
break; |
||||
|
case "RRC": |
||||
|
break; |
||||
|
case "NAS": |
||||
|
break; |
||||
|
|
||||
|
default: |
||||
|
break; |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
@ -1,284 +0,0 @@ |
|||||
using CoreAgent.Domain.Helpers; |
|
||||
using CoreAgent.Domain.Interfaces.ProtocolLogHandlers; |
|
||||
using CoreAgent.Domain.Models.Protocol; |
|
||||
using Microsoft.Extensions.Logging; |
|
||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Linq; |
|
||||
using System.Text; |
|
||||
using System.Text.RegularExpressions; |
|
||||
using System.Threading.Tasks; |
|
||||
|
|
||||
namespace CoreAgent.Infrastructure.Services.ProtocolLogHandlers |
|
||||
{ |
|
||||
|
|
||||
|
|
||||
|
|
||||
public class ProtocolLogsParesRanHandle : ProtocolParesHandleLogs |
|
||||
{ |
|
||||
private readonly ILogger logger; |
|
||||
private readonly IProtocolLogsProviderObserver observer; |
|
||||
public ProtocolLogsParesRanHandle(IProtocolLogsProviderObserver observer, ILogger logger) |
|
||||
{ |
|
||||
this.observer = observer; |
|
||||
this.logger = logger; |
|
||||
} |
|
||||
|
|
||||
public override async Task GetTryParesLogDataHandle(ProtocolLog model) |
|
||||
{ |
|
||||
try |
|
||||
{ |
|
||||
if (model is { Logs: null }) |
|
||||
{ |
|
||||
logger.LogError($"logs is null =====>GetTryParesLogDataHandle Data {model?.ObjToJson()}"); |
|
||||
return; |
|
||||
} |
|
||||
var ParseJsonData = model.Logs.ToString().JsonToObj<ProtocolLogDetail[]>(); |
|
||||
//var parseResultData = RanLogParseHandle(ParseJsonData, (model.MessageId ?? 0));
|
|
||||
//if (parseResultData.Any())
|
|
||||
//{
|
|
||||
// var MsgData = new { data = parseResultData, MessageType = CSCIMessageType.ProtocolLogsRAN }.ObjToJson();
|
|
||||
// logger.LogInformation($"OnData:{MsgData}");
|
|
||||
// observer.OnData(MsgData);
|
|
||||
//}
|
|
||||
} |
|
||||
catch (Exception ex) |
|
||||
{ |
|
||||
logger.LogError($"GetTryParesLogDataHandle Data {model?.ObjToJson()}"); |
|
||||
logger.LogError(ex.ToString()); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
|
|
||||
//#region 分析
|
|
||||
//private List<CellularNetworkProtocolLogsEntity> RanLogParseHandle(ProtocolLogDetail[] data, int MessageID)
|
|
||||
//{
|
|
||||
// List<CellularNetworkProtocolLogsEntity> cellulars = new List<CellularNetworkProtocolLogsEntity>();
|
|
||||
// try
|
|
||||
// {
|
|
||||
// foreach (var msg in data)
|
|
||||
// {
|
|
||||
// ProtocolLogslayerType LayerType;
|
|
||||
// Enum.TryParse(msg.layer, out LayerType);
|
|
||||
// string info = string.Empty;
|
|
||||
// string TMIS = string.Empty;
|
|
||||
// string MessageInfo = msg.data[0];
|
|
||||
// if (LayerType == ProtocolLogslayerType.RRC)
|
|
||||
// {
|
|
||||
// var reg = _regExpRRC_UE_ID.Match(MessageInfo);
|
|
||||
// if (reg is { Success: true })
|
|
||||
// {
|
|
||||
// int ue_id = Convert.ToInt32(reg.Groups[1].ToString(), 16);
|
|
||||
|
|
||||
// }
|
|
||||
// reg = _regExpInfo1.Match(MessageInfo);
|
|
||||
// if (reg.Success)
|
|
||||
// {
|
|
||||
// info = reg.Groups[1].Value;
|
|
||||
// MessageInfo = reg.Groups[2].Value;
|
|
||||
// GetlogListRRC(msg, MessageInfo);
|
|
||||
|
|
||||
// }
|
|
||||
// reg = _regExpRRC_BC.Match(MessageInfo);
|
|
||||
// if (reg is { Success: true })
|
|
||||
// {
|
|
||||
// string result = string.Join("\n", msg.data);
|
|
||||
|
|
||||
// }
|
|
||||
// }
|
|
||||
// else if (LayerType == ProtocolLogslayerType.NAS)
|
|
||||
// {
|
|
||||
// var reg = _regExpInfo1.Match(MessageInfo);
|
|
||||
// if (reg is { Success: true })
|
|
||||
// {
|
|
||||
// info = reg.Groups[1].Value;
|
|
||||
// MessageInfo = reg.Groups[2].Value;
|
|
||||
// TMIS = GetlogListNAS(msg, MessageInfo);
|
|
||||
// if (info.Equals("BCCH_NR"))
|
|
||||
// {
|
|
||||
|
|
||||
// }
|
|
||||
|
|
||||
// }
|
|
||||
// }
|
|
||||
// else if (LayerType == ProtocolLogslayerType.PHY)
|
|
||||
// {
|
|
||||
// var reg = _regExpPhy.Match(MessageInfo);
|
|
||||
// if (reg is { Success: true })
|
|
||||
// {
|
|
||||
// int cell = Convert.ToInt32(reg.Groups[1].Value, 16);
|
|
||||
// int rnti = Convert.ToInt32(reg.Groups[2].Value, 16);
|
|
||||
// var channel = reg.Groups[4].Value;
|
|
||||
// string[] frames = reg.Groups[3].Value.Split('.');
|
|
||||
// int frame = Convert.ToInt32(frames[0]) - 0;
|
|
||||
// int slot = Convert.ToInt32(frames[1]) - 0;
|
|
||||
// }
|
|
||||
|
|
||||
// }
|
|
||||
// else if (LayerType == ProtocolLogslayerType.MAC)
|
|
||||
// {
|
|
||||
// var reg = _regExpCellID.Match(MessageInfo);
|
|
||||
// if (reg is { Success: true })
|
|
||||
// {
|
|
||||
// int cell = Convert.ToInt32(reg.Groups[1].Value, 16);
|
|
||||
// MessageInfo = reg.Groups[2].Value;
|
|
||||
// }
|
|
||||
// }
|
|
||||
// CellularNetworkProtocolLogsEntity entity = new CellularNetworkProtocolLogsEntity
|
|
||||
// {
|
|
||||
// MessageID = MessageID,
|
|
||||
// CellID = msg.cell,
|
|
||||
// Timestamp = msg.timestamp,
|
|
||||
// UEID = msg.ue_id,
|
|
||||
// Time = msg.timestamp.UnixTimeStamp13ToBeijingTime().TimeOfDay,
|
|
||||
// ProtocolLayer = LayerType,
|
|
||||
// Info = info,
|
|
||||
// TMSI = TMIS,
|
|
||||
// Message = MessageInfo,
|
|
||||
// ProtocolType = msg.src,
|
|
||||
// Index = msg.idx,
|
|
||||
// Direction = msg.dir switch
|
|
||||
// {
|
|
||||
// "UL" => DirectionLogsType.UL,
|
|
||||
// "DL" => DirectionLogsType.DL,
|
|
||||
// _ => DirectionLogsType._
|
|
||||
// },
|
|
||||
// MessageData = msg.data.ToArray(),
|
|
||||
// };
|
|
||||
// cellulars.Add(entity);
|
|
||||
// }
|
|
||||
// return cellulars;
|
|
||||
// }
|
|
||||
// catch (Exception ex)
|
|
||||
// {
|
|
||||
// logger.Error("ran logs analysis combination" + ex.Message);
|
|
||||
// return cellulars;
|
|
||||
// }
|
|
||||
//}
|
|
||||
|
|
||||
//private void GetlogListRRC(ProtocolNetWorkCoreLogsDetailEntity log, string logType)
|
|
||||
//{
|
|
||||
// try
|
|
||||
// {
|
|
||||
// switch (logType.ToLower())
|
|
||||
// {
|
|
||||
// case "sib1":
|
|
||||
// break;
|
|
||||
// case "sib":
|
|
||||
// break;
|
|
||||
// case "rrc connection request":
|
|
||||
// var lte = GetFindData(log.data, _regExpRRC_TMSI);
|
|
||||
// if (lte is { Success: true })
|
|
||||
// {
|
|
||||
// int tmsi = GetTMSI(log, lte.Groups[2].Value.ToString());
|
|
||||
// }
|
|
||||
// break;
|
|
||||
// case "rrc connection reconfiguration":
|
|
||||
// var connection = GetFindData(log.data, _regExpRRC_TMSI);
|
|
||||
// if (connection is { Success: true })
|
|
||||
// {
|
|
||||
// int rnti = GetRNTI(log, connection.Groups[1].Value);
|
|
||||
// }
|
|
||||
// break;
|
|
||||
// case "rrc connection reestablishment request":
|
|
||||
// var request = GetFindData(log.data, _regExpRRC_TMSI);
|
|
||||
// if (request is { Success: true })
|
|
||||
// {
|
|
||||
// int rnti = GetRNTI(log, request.Groups[1].Value);
|
|
||||
// }
|
|
||||
// break;
|
|
||||
// case "rrc setup request":
|
|
||||
// var RRCrequest = GetFindData(log.data, _regExpRRC_TMSI);
|
|
||||
// break;
|
|
||||
// case "ue capability information":
|
|
||||
|
|
||||
// break;
|
|
||||
// default:
|
|
||||
// break;
|
|
||||
// }
|
|
||||
// }
|
|
||||
// catch (Exception ex)
|
|
||||
// {
|
|
||||
// logger.Error("GetlogListRRC" + ex.Message);
|
|
||||
// }
|
|
||||
//}
|
|
||||
|
|
||||
//private string GetlogListNAS(ProtocolNetWorkCoreLogsDetailEntity log, string logType)
|
|
||||
//{
|
|
||||
// switch (logType.ToLower())
|
|
||||
// {
|
|
||||
// case "attach accept":
|
|
||||
// var lte = GetFindData(log.data, _regExpNAS_TMSI);
|
|
||||
// if (lte is not null && !string.IsNullOrWhiteSpace(lte.Groups[1]?.ToString()))
|
|
||||
// {
|
|
||||
|
|
||||
// int tmsi = GetTMSI(log, lte.Groups[1].Value);
|
|
||||
// return lte.Groups[1].Value;
|
|
||||
|
|
||||
// }
|
|
||||
// break;
|
|
||||
// case "attach request":
|
|
||||
// var data = log.data;
|
|
||||
// break;
|
|
||||
// case "registration accept":
|
|
||||
// var Nr = GetFindData(log.data, _regExpNAS_5GTMSI);
|
|
||||
// if (Nr is not null && !string.IsNullOrWhiteSpace(Nr?.Groups[1]?.ToString()))
|
|
||||
// {
|
|
||||
// int tmsi = GetTMSI(log, Nr.Groups[1].Value);
|
|
||||
// return Nr.Groups[1].Value;
|
|
||||
// }
|
|
||||
// break;
|
|
||||
// case "registration request":
|
|
||||
// var requestData = log.data;
|
|
||||
// break;
|
|
||||
|
|
||||
// }
|
|
||||
// return string.Empty;
|
|
||||
|
|
||||
//}
|
|
||||
|
|
||||
//private Match GetFindData(List<string> data, Regex regExp)
|
|
||||
//{
|
|
||||
// if (data.Any())
|
|
||||
// {
|
|
||||
// for (var i = 0; i < data.Count; i++)
|
|
||||
// {
|
|
||||
// Match m = regExp.Match(data[i]);
|
|
||||
// if (m.Success)
|
|
||||
// return m;
|
|
||||
// }
|
|
||||
// }
|
|
||||
// return default;
|
|
||||
//}
|
|
||||
|
|
||||
//private int GetTMSI(ProtocolNetWorkCoreLogsDetailEntity log, string tmsi)
|
|
||||
//{
|
|
||||
// return Convert.ToInt32(tmsi, 16);
|
|
||||
//}
|
|
||||
|
|
||||
//private int GetRNTI(ProtocolNetWorkCoreLogsDetailEntity log, string rnti)
|
|
||||
//{
|
|
||||
// // 定义正则表达式模式
|
|
||||
// string pattern = @"'([\dA-F]+)'H";
|
|
||||
|
|
||||
// // 创建正则表达式对象
|
|
||||
// Regex regex = new Regex(pattern);
|
|
||||
|
|
||||
// // 进行匹配
|
|
||||
// Match match = regex.Match(rnti);
|
|
||||
|
|
||||
// // 检查是否有匹配
|
|
||||
// if (match.Success)
|
|
||||
// return Convert.ToInt32(match.Groups[1].Value, 16);
|
|
||||
// else return 0;
|
|
||||
//}
|
|
||||
|
|
||||
//private bool GetCheckLayerTypeInfo(string layer)
|
|
||||
//{
|
|
||||
// string[] ArraryLayer = new string[] { "PDSCH", "PDCCH", "EPDCCH", "PUSCH", "PUCCH", "NPDSCH", "NPUSCH", "NPBCH", "BCCH-NR", "HINTS", "SRS", "CSI", "SIM-Even", "IP-SIM" };
|
|
||||
// return ArraryLayer.Any(s => s.Equals(layer));
|
|
||||
//}
|
|
||||
//#endregion
|
|
||||
} |
|
||||
|
|
||||
} |
|
Loading…
Reference in new issue