diff --git a/LTEMvcApp/Models/LTEClient.cs b/LTEMvcApp/Models/LTEClient.cs
index dc59e2e..c3a79bd 100644
--- a/LTEMvcApp/Models/LTEClient.cs
+++ b/LTEMvcApp/Models/LTEClient.cs
@@ -1,6 +1,6 @@
using System.Collections.Immutable;
using System.Text.RegularExpressions;
-using System.Text.Json.Serialization;
+using Newtonsoft.Json;
namespace LTEMvcApp.Models;
@@ -9,6 +9,124 @@ namespace LTEMvcApp.Models;
///
public class LTEClient
{
+ #region 常量定义
+
+ ///
+ /// HFN回绕阈值
+ ///
+ private const int HFN_WRAP_THRESHOLD = 512;
+
+ ///
+ /// 最大日志数量
+ ///
+ private const int LOGS_MAX = 2000000;
+
+ #endregion
+
+ #region 正则表达式
+
+ ///
+ /// PHY层日志正则表达式
+ ///
+ private static readonly Regex RegExpPhy = new(@"^([a-f0-9\-]+)\s+([a-f0-9\-]+)\s+([\d\.\-]+) (\w+): (.+)", RegexOptions.Compiled);
+
+ ///
+ /// 信息1正则表达式
+ ///
+ private static readonly Regex RegExpInfo1 = new(@"^([\w\-]+): (.+)", RegexOptions.Compiled);
+
+ ///
+ /// 信息2正则表达式
+ ///
+ private static readonly Regex RegExpInfo2 = new(@"^([\w]+) (.+)", RegexOptions.Compiled);
+
+ ///
+ /// IP日志正则表达式
+ ///
+ private static readonly Regex RegExpIP = new(@"^(len=\d+)\s+(\S+)\s+(.*)", RegexOptions.Compiled);
+
+ ///
+ /// IPsec日志正则表达式
+ ///
+ private static readonly Regex RegExpIPsec = new(@"^len=(\d+)\s+(.*)", RegexOptions.Compiled);
+
+ ///
+ /// SDU长度正则表达式
+ ///
+ private static readonly Regex RegExpSDULen = new(@"SDU_len=(\d+)", RegexOptions.Compiled);
+
+ ///
+ /// SIP日志正则表达式
+ ///
+ private static readonly Regex RegExpSIP = new(@"^([:\.\[\]\da-f]+)\s+(\S+) (.+)", RegexOptions.Compiled);
+
+ ///
+ /// 媒体请求正则表达式
+ ///
+ private static readonly Regex RegExpMediaReq = new(@"^(\S+) (.+)", RegexOptions.Compiled);
+
+ ///
+ /// 信号记录正则表达式
+ ///
+ private static readonly Regex RegExpSignalRecord = new(@"Link:\s([\w\d]+)@(\d+)", RegexOptions.Compiled);
+
+ ///
+ /// 小区ID正则表达式
+ ///
+ private static readonly Regex RegExpCellID = new(@"^([a-f0-9\-]+) (.+)", RegexOptions.Compiled);
+
+ ///
+ /// RRC UE ID正则表达式
+ ///
+ private static readonly Regex RegExpRRC_UE_ID = new(@"Changing UE_ID to 0x(\d+)", RegexOptions.Compiled);
+
+ ///
+ /// RRC TMSI正则表达式
+ ///
+ private static readonly Regex RegExpRRC_TMSI = new(@"(5G|m)-TMSI '([\dA-F]+)'H", RegexOptions.Compiled);
+
+ ///
+ /// RRC新ID正则表达式
+ ///
+ private static readonly Regex RegExpRRC_NEW_ID = new(@"newUE-Identity (['\dA-FH]+)", RegexOptions.Compiled);
+
+ ///
+ /// RRC CRNTI正则表达式
+ ///
+ private static readonly Regex RegExpRRC_CRNTI = new(@"c-RNTI '([\dA-F]+)'H", RegexOptions.Compiled);
+
+ ///
+ /// NAS TMSI正则表达式
+ ///
+ private static readonly Regex RegExpNAS_TMSI = new(@"m-TMSI = 0x([\da-f]+)", RegexOptions.Compiled);
+
+ ///
+ /// NAS 5G TMSI正则表达式
+ ///
+ private static readonly Regex RegExpNAS_5GTMSI = new(@"5G-TMSI = 0x([\da-f]+)", RegexOptions.Compiled);
+
+ ///
+ /// RRC频段组合正则表达式
+ ///
+ private static readonly Regex RegExpRRC_BC = new(@"(EUTRA|MRDC|NR|NRDC) band combinations", RegexOptions.Compiled);
+
+ ///
+ /// PDCCH正则表达式
+ ///
+ private static readonly Regex RegExpPDCCH = new(@"^\s*(.+)=(\d+)$", RegexOptions.Compiled);
+
+ ///
+ /// S1/NGAP正则表达式
+ ///
+ private static readonly Regex RegExpS1NGAP = new(@"^([\da-f\-]+)\s+([\da-f\-]+) (([^\s]+) .+)", RegexOptions.Compiled);
+
+ ///
+ /// 十六进制转储正则表达式
+ ///
+ private static readonly Regex RegExpHexDump = new(@"^[\da-f]+:(\s+[\da-f]{2}){1,16}\s+.{1,16}$", RegexOptions.Compiled);
+
+ #endregion
+
#region 基础属性
///
@@ -169,6 +287,25 @@ public class LTEClient
#endregion
+ #region 解析器私有字段
+
+ ///
+ /// 字符串到ID的映射缓存
+ ///
+ private readonly Dictionary _stringToIdCache = new();
+
+ ///
+ /// ID到字符串的映射缓存
+ ///
+ private readonly Dictionary _idToStringCache = new();
+
+ ///
+ /// 字符串ID计数器
+ ///
+ private int _stringIdCounter = 0;
+
+ #endregion
+
#region 构造函数
public LTEClient(ClientConfig config)
@@ -193,7 +330,7 @@ public class LTEClient
#endregion
- #region 公共方法
+ #region 客户端控制方法
///
/// 启动客户端
@@ -219,6 +356,10 @@ public class LTEClient
SetState(ClientState.Destroy);
}
+ #endregion
+
+ #region 日志管理方法
+
///
/// 重置日志
///
@@ -257,6 +398,10 @@ public class LTEClient
log.Id = GenerateLogId();
}
+ #endregion
+
+ #region 工具方法
+
///
/// 设置头信息
///
@@ -295,13 +440,497 @@ public class LTEClient
///
public int StringToId(string str)
{
- // 实现字符串转ID逻辑
- return 0;
+ if (_stringToIdCache.TryGetValue(str, out var id))
+ {
+ return id;
+ }
+
+ id = ++_stringIdCounter;
+ _stringToIdCache[str] = id;
+ _idToStringCache[id] = str;
+ return id;
+ }
+
+ ///
+ /// ID转字符串
+ ///
+ public string IdToString(int id)
+ {
+ return _idToStringCache.TryGetValue(id, out var str) ? str : "";
+ }
+
+ #endregion
+
+ #region 日志解析方法
+
+ ///
+ /// 解析日志列表 - 对应JavaScript的_logListParse方法
+ ///
+ /// 日志列表
+ /// 是否为WebSocket消息
+ public void ParseLogList(List logs, bool isWebSocket = false)
+ {
+ var length = logs.Count;
+
+ for (int i = 0; i < length; i++)
+ {
+ var log = logs[i];
+ log.Message = log.Message + "";
+
+ AddLog(log);
+
+ // 解析消息
+ switch (log.Layer)
+ {
+ case "PHY":
+ if (!ParsePhyLog(log, log.Message, isWebSocket)) continue;
+ ProcessPhyLog(log);
+ break;
+
+ case "RRC":
+ ParseCellId(log, isWebSocket);
+ var rrcUeIdMatch = RegExpRRC_UE_ID.Match(log.Message);
+ if (rrcUeIdMatch.Success)
+ {
+ SetSameUe(log, int.Parse(rrcUeIdMatch.Groups[1].Value, System.Globalization.NumberStyles.HexNumber));
+ continue;
+ }
+
+ var infoMatch = RegExpInfo1.Match(log.Message);
+ if (infoMatch.Success)
+ {
+ if (!SetLogInfo(log, infoMatch.Groups[1].Value)) continue;
+ log.Message = infoMatch.Groups[2].Value;
+ ProcessRrcLog(log);
+ }
+
+ var bcMatch = RegExpRRC_BC.Match(log.Message);
+ if (bcMatch.Success)
+ {
+ try
+ {
+ var data = log.GetDataString();
+ var jsonData = JsonConvert.DeserializeObject