using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using CoreAgent.ProtocolClient.Context; using CoreAgent.ProtocolClient.Enums; using CoreAgent.ProtocolClient.Models; namespace CoreAgent.ProtocolClient.BuildProtocolParser { public class NASProtocolParser : IGeneralProtocolParser { private readonly ProtocolClientContext context; public NASProtocolParser(ProtocolClientContext context) { this.context = context; } public void GeneralParse(ref BuildProtocolLog log) { var nasInfoMatch = ProtocolLogPatterns.RegExpInfo1.Match(log.Message); if (nasInfoMatch.Success) { var info = context.UeIdentifier.StringToId(nasInfoMatch.Groups[1].Value); if (info == -1) return; log.Info = info; log.Message = nasInfoMatch.Groups[2].Value; ProcessNasLog(log); } } /// /// 处理NAS日志 /// private void ProcessNasLog(BuildProtocolLog log) { if (log?.Data == null || !log.UeId.HasValue) return; var messageType = log.Message.ToLowerInvariant(); switch (messageType) { case "attach accept": BuildPLMNFromComponents(log); ProcessTmsiFromLog(log, ProtocolLogPatterns.RegExpNAS_TMSI, TmsiType.Accept); break; case "registration accept": BuildPLMNFromComponents(log); ProcessTmsiFromLog(log, ProtocolLogPatterns.RegExpNAS_5GTMSI, TmsiType.Accept); break; case "attach request": ProcessImsiFromLog(log); ProcessTmsiFromLog(log, ProtocolLogPatterns.RegExpNAS_TMSI, TmsiType.Request); break; case "service request": ProcessTmsiFromLog(log, ProtocolLogPatterns.RegExpNAS_5GTMSI, TmsiType.ServiceRequest); break; case "identity response": ProcessImsiFromLog(log); break; case "registration request": ProcessImsiFromLog(log); //BuildPLMNFromComponents(log); ProcessTmsiFromLog(log, ProtocolLogPatterns.RegExpNAS_5GTMSI, TmsiType.Request); break; } } /// /// 从日志中处理TMSI信息 /// private void ProcessTmsiFromLog(BuildProtocolLog log, Regex tmsiPattern, TmsiType type) { var tmsiMatch = tmsiPattern.FindData(log.Data); if (tmsiMatch?.Success != true || !log.UeId.HasValue) return; var tmsiValue = tmsiMatch.Groups[1].Value; var ueId = log.UeId.Value; switch (type) { case TmsiType.Accept: context.UeIdentifier.SetTmsi(ueId, tmsiValue); break; case TmsiType.Request: context.UeIdentifier.SetRequestTmsi(ueId, tmsiValue); break; case TmsiType.ServiceRequest: context.UeIdentifier.SetSrTmsi(ueId, tmsiValue); break; } } /// /// 从日志中处理IMSI信息 /// private void ProcessImsiFromLog(BuildProtocolLog log) { var imsi = ExtractImsiFromLog(log); if (!string.IsNullOrWhiteSpace(imsi) && log.UeId.HasValue) { context.UeIdentifier.SetImsi(log.UeId.Value, imsi); } } /// /// 从日志中提取IMSI信息 /// private string ExtractImsiFromLog(BuildProtocolLog log) { // 优先尝试直接获取IMSI var imsi = ExtractValueFromLog(log.Data, ProtocolLogPatterns.RegIMSIPattern); if (!string.IsNullOrWhiteSpace(imsi)) return imsi; // 如果直接获取失败,尝试从MSIN、MNC、MCC构建 return BuildIMSIFromComponents(log); } /// /// 从日志数据中提取指定正则表达式的第一个匹配值 /// private string ExtractValueFromLog(List data, Regex pattern) { return data?.Select(line => pattern.Match(line)) .Where(match => match.Success) .Select(match => match.Groups[1].Value) .FirstOrDefault() ?? string.Empty; } /// /// 根据 MSIN、MNC 和 MCC 构建 IMSI(International Mobile Subscriber Identity) /// /// 协议日志 /// 完整的 IMSI 字符串,如果组件不完整则返回空字符串 private string BuildIMSIFromComponents(BuildProtocolLog log) { var components = ExtractPLMNComponents(log); // 检查所有组件是否都存在 if (string.IsNullOrWhiteSpace(components.Msin) || string.IsNullOrWhiteSpace(components.Mnc) || string.IsNullOrWhiteSpace(components.Mcc)) return string.Empty; context.UeIdentifier.SetPlmn(log!.UeId.Value, components.Mcc + components.Mnc); return components.Mcc + components.Mnc + components.Msin; } /// /// 根据 MCC 和 MNC 构建 PLMN(Public Land Mobile Network) /// /// 协议日志 /// 完整的 PLMN 字符串,如果组件不完整则返回空字符串 private string BuildPLMNFromComponents(BuildProtocolLog log) { var components = ExtractPLMNComponents(log); // 检查所有组件是否都存在 if (string.IsNullOrWhiteSpace(components.Mnc) || string.IsNullOrWhiteSpace(components.Mcc)) return string.Empty; context.UeIdentifier.SetPlmn(log!.UeId.Value, components.Mcc + components.Mnc); return components.Mcc + components.Mnc; } /// /// 从日志中提取PLMN相关组件(MCC、MNC、MSIN) /// /// 协议日志 /// 包含MCC、MNC、MSIN的组件结构 private (string Mcc, string Mnc, string Msin) ExtractPLMNComponents(BuildProtocolLog log) { var mcc = ExtractValueFromLog(log.Data, ProtocolLogPatterns.RegMccPattern); var mnc = ExtractValueFromLog(log.Data, ProtocolLogPatterns.RegMncPattern); var msin = ExtractValueFromLog(log.Data, ProtocolLogPatterns.RegMSINPattern); return (mcc, mnc, msin); } } }