using System; using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; namespace LTEMvcApp.Models { /// /// LTE能力解析器 /// public class LTECapabilities { public string UEId { get; set; } public List Bands { get; set; } = new List(); public int? Category { get; set; } public int? CategoryDL { get; set; } public int? CategoryUL { get; set; } public List> ASN1Data { get; set; } = new List>(); public Dictionary BandCombinations { get; set; } = new Dictionary(); public List> CA { get; set; } public List NRBands { get; set; } public string VoNR { get; set; } public List> MRDC { get; set; } private List _pendingData = new List(); private int _count = 0; public static readonly Dictionary UE_CAPS_MIMO = new Dictionary { ["twoLayers"] = 2, ["fourLayers"] = 4, ["eightLayers"] = 8 }; /// /// 获取类别信息 /// public string GetCategory() { var cat = new List(); if (CategoryDL.HasValue) cat.Add($"DL={CategoryDL}"); if (CategoryUL.HasValue) cat.Add($"UL={CategoryUL}"); if (cat.Count > 0) return string.Join(", ", cat); if (Category.HasValue) return Category.ToString(); return "?"; } /// /// 添加待解析数据 /// public void Add(string[] data) { if (data != null && data.Length > 0) { _pendingData.Add(data); } } /// /// 解析所有待处理数据 /// public LTECapabilities Parse() { while (_pendingData.Count > 0) { _count++; ParseASN1(ASN1Parser.FromGSER(_pendingData[0])); _pendingData.RemoveAt(0); } return _count > 0 ? this : null; } /// /// 解析ASN1数据 /// private void ParseASN1(Dictionary asn1) { if (asn1 == null) return; ASN1Data.Add(asn1); var ratList = ASN1Parser.Dig(asn1, "ueCapabilityInformation", "ueCapabilityInformation-r8", "ue-CapabilityRAT-ContainerList") as List ?? new List(); var ratList1 = ASN1Parser.Dig(asn1, "ueCapabilityInformation", "ueCapabilityInformation", "ue-CapabilityRAT-ContainerList") as List; if (ratList1 != null) { ratList.AddRange(ratList1); } foreach (var rat in ratList) { if (rat is Dictionary ratDict) { var ratType = ratDict.GetValueOrDefault("rat-Type")?.ToString(); var container = ratDict.GetValueOrDefault("ueCapabilityRAT-Container") ?? ratDict.GetValueOrDefault("ue-CapabilityRAT-Container"); switch (ratType) { case "eutra": ParseRatEUTRA(container as Dictionary); break; case "nr": ParseRatNR(container as Dictionary); break; case "eutra-nr": ParseRatEUTRA_NR(container as Dictionary); break; } } } if (Category == null) { ParseR13(asn1); } } /// /// 解析R13版本 /// private void ParseR13(Dictionary asn1) { var root = ASN1Parser.Dig(asn1, "ueCapabilityInformation-r13", "ueCapabilityInformation-r13", "ue-Capability-Container-r13") as Dictionary; if (root != null) { // Category if (root.ContainsKey("ue-Category-NB-r13")) { Category = Convert.ToInt32(root["ue-Category-NB-r13"]); } var bands = ASN1Parser.Dig(root, "rf-Parameters-r13", "supportedBandList-r13") as List; if (bands != null) { var mappedBands = ASN1Parser.Map(bands, b => { if (b is Dictionary bandDict) { return new BandInfo { Band = Convert.ToInt32(bandDict["band-r13"]) }; } return new BandInfo(); }); if (mappedBands != null && mappedBands.Count > 0) { //Bands = mappedBands.Cast().ToList(); } } } } /// /// 解析EUTRA RAT /// private void ParseRatEUTRA(Dictionary asn1) { if (asn1 == null) return; if (asn1.ContainsKey("ue-Category")) { Category = Convert.ToInt32(asn1["ue-Category"]); } var mimo = 1; if (Category >= 5) { mimo = 4; } else if (Category >= 2) { mimo = 2; } // Bands var extBands = new List(); var bands = ASN1Parser.Dig(asn1, "rf-Parameters", "supportedBandListEUTRA") as List; if (bands != null) { var mappedBands = ASN1Parser.Map(bands, (b, i) => { if (b is Dictionary bandDict) { var band = Convert.ToInt32(bandDict["bandEUTRA"]); if (band == 64) { extBands.Add(i); } return new BandInfo { Band = band }; } return new BandInfo(); }); if (mappedBands != null && mappedBands.Count > 0) { //Bands = mappedBands.Cast().ToList(); var ext = ASN1Parser.Dig(asn1, 2, "nonCriticalExtension", "lateNonCriticalExtension", 3, "nonCriticalExtension", "rf-Parameters-v9e0", "supportedBandListEUTRA-v9e0") as List; if (ext != null) { foreach (var b in extBands) { if (b < ext.Count && ext[b] is Dictionary extBand) { Bands[b].Band = Convert.ToInt32(extBand["bandEUTRA-v9e0"]); } } } } } // CA var ca = ASN1Parser.Dig(asn1, 2, "nonCriticalExtension") as Dictionary; if (ca != null) { try { extBands.Clear(); var ca1 = ca.GetValueOrDefault("nonCriticalExtension") as Dictionary; if (ca1 != null) { if (ca1.ContainsKey("ue-Category-v1020")) { Category = Convert.ToInt32(ca1["ue-Category-v1020"]); } var rfParams = ca1.GetValueOrDefault("rf-Parameters-v1020") as Dictionary; if (rfParams != null) { var supportedBandComb = rfParams.GetValueOrDefault("supportedBandCombination-r10") as List; if (supportedBandComb != null) { CA = ASN1Parser.Map>(supportedBandComb, (c0, i0) => { if (c0 is List c0List) { return ASN1Parser.Map(c0List, (c1, i1) => { if (c1 is Dictionary c1Dict) { var band = Convert.ToInt32(c1Dict["bandEUTRA-r10"]); if (band == 64) { //extBands.Add(new[] { i0, i1 }); } var dl = c1Dict.GetValueOrDefault("bandParametersDL-r10") as List; var ul = c1Dict.GetValueOrDefault("bandParametersUL-r10") as List; var result = new BandCombinationInfo { Band = band, MIMO = mimo }; if (dl != null && dl.Count > 0 && dl[0] is Dictionary dlDict) { result.DL = dlDict.GetValueOrDefault("ca-BandwidthClassDL-r10")?.ToString(); if (dlDict.ContainsKey("supportedMIMO-CapabilityDL-r10")) { var mimoCap = dlDict["supportedMIMO-CapabilityDL-r10"].ToString(); result.MIMO_9_10 = UE_CAPS_MIMO.GetValueOrDefault(mimoCap, mimo); } } if (ul != null && ul.Count > 0 && ul[0] is Dictionary ulDict) { result.UL = ulDict.GetValueOrDefault("ca-BandwidthClassUL-r10")?.ToString(); } return result; } return new BandCombinationInfo(); }); } return new List(); }); } } } } catch (Exception) { } } if (Bands != null && Bands.Count > 0) { //Bands = Bands.OrderBy(b => b.Band).ToList(); } } /// /// 解析NR RAT /// private void ParseRatNR(Dictionary asn1) { if (asn1 == null) return; // Bands var bands = ASN1Parser.Dig(asn1, "rf-Parameters", "supportedBandListNR") as List; if (bands != null) { var mappedBands = ASN1Parser.Map(bands, b => { if (b is Dictionary bandDict) { return new BandInfo { Band = Convert.ToInt32(bandDict["bandNR"]) }; } return new BandInfo(); }); if (mappedBands != null && mappedBands.Count > 0) { NRBands = mappedBands; } } // VoNR var v1540 = ASN1Parser.Dig(asn1, 2, "nonCriticalExtension") as Dictionary; if (v1540 != null) { var vonr = new List(); if (ASN1Parser.Dig(v1540, "ims-Parameters", "ims-ParametersFRX-Diff", "voiceOverNR")?.ToString() == "supported") { vonr.AddRange(new[] { "FR1", "FR2" }); } else { if (ASN1Parser.Dig(v1540, "fr1-Add-UE-NR-Capabilities-v1540", "ims-ParametersFRX-Diff", "voiceOverNR")?.ToString() == "supported") vonr.Add("FR1"); if (ASN1Parser.Dig(v1540, "fr2-Add-UE-NR-Capabilities-v1540", "ims-ParametersFRX-Diff", "voiceOverNR")?.ToString() == "supported") vonr.Add("FR2"); } if (vonr.Count > 0) { VoNR = string.Join(", ", vonr); } } } /// /// 解析EUTRA-NR RAT /// private void ParseRatEUTRA_NR(Dictionary asn1) { if (asn1 == null) return; var bands = ASN1Parser.Dig(asn1, "rf-ParametersMRDC", "supportedBandCombinationList") as List; if (bands != null) { MRDC = ASN1Parser.Map>(bands, band => { if (band is Dictionary bandDict) { var bl = bandDict.GetValueOrDefault("bandList") as Dictionary; if (bl != null) { var result = new List(); var nr = bl.GetValueOrDefault("nr") as List; if (nr != null) { result.AddRange(ASN1Parser.Map(nr, b => { if (b is Dictionary bDict) { return new BandCombinationInfo { Band = Convert.ToInt32(bDict["bandNR"]), BandType = "NR", DL = bDict.GetValueOrDefault("ca-BandwidthClassDL-NR")?.ToString(), UL = bDict.GetValueOrDefault("ca-BandwidthClassUL-NR")?.ToString() }; } return new BandCombinationInfo(); })); } var eutra = bl.GetValueOrDefault("eutra") as List; if (eutra != null) { result.AddRange(ASN1Parser.Map(eutra, b => { if (b is Dictionary bDict) { return new BandCombinationInfo { Band = Convert.ToInt32(bDict["bandEUTRA"]), DL = bDict.GetValueOrDefault("ca-BandwidthClassDL-EUTRA")?.ToString(), UL = bDict.GetValueOrDefault("ca-BandwidthClassUL-EUTRA")?.ToString() }; } return new BandCombinationInfo(); })); } return result; } } return new List(); }); } } /// /// 设置频段组合 /// public void SetBandComb(Dictionary json, string ratType) { BandCombinations[ratType] = json; } } /// /// 频段信息 /// public class BandInfo { public int Band { get; set; } public bool DL256QAM { get; set; } public string BandType { get; set; } = "LTE"; } /// /// 频段组合信息 /// public class BandCombinationInfo { public int Band { get; set; } public string DL { get; set; } public string UL { get; set; } public int MIMO { get; set; } public int? MIMO_9_10 { get; set; } public bool MIMO4_3_4 { get; set; } public string BandType { get; set; } = "LTE"; } }