1: using System;
2: using System.Collections.Generic;
3: using System.Linq;
4: using System.Text.RegularExpressions;
5:
6: namespace Ia.Ngn.Cl.Model.Business.Huawei
7: {
8: ////////////////////////////////////////////////////////////////////////////
9:
10: /// <summary publish="true">
11: /// Huawei's Dev support class of Optical Fiber Network (OFN) business model.
12: /// </summary>
13: ///
14: /// <remarks>
15: /// Copyright © 2016-2021 Jasem Y. Al-Shamlan (info@ia.com.kw), Integrated Applications - Kuwait. All Rights Reserved.
16: ///
17: /// This library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
18: /// the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
19: ///
20: /// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
21: /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
22: ///
23: /// You should have received a copy of the GNU General Public License along with this library. If not, see http://www.gnu.org/licenses.
24: ///
25: /// Copyright notice: This notice may not be removed or altered from any source distribution.
26: /// </remarks>
27: public class Dev
28: {
29: /// <summary/>
30: public static int MsanPortCapacity = 1028;
31:
32: private static int sequentialEmsDevDevQueueOriginalCount, sequentialEmsMsanDevPortQueueOriginalCount;
33: private static Queue<Ia.Ngn.Cl.Model.Huawei.EmsDev> sequentialEmsDevDevQueue = new Queue<Ia.Ngn.Cl.Model.Huawei.EmsDev>();
34: private static Queue<Ia.Ngn.Cl.Model.Huawei.EmsPort> sequentialEmsMsanDevPortQueue = new Queue<Ia.Ngn.Cl.Model.Huawei.EmsPort>();
35:
36: public enum Type { Olt, Mdu, Msan, Unknown };
37:
38: ////////////////////////////////////////////////////////////////////////////
39:
40: /// <summary>
41: ///
42: /// </summary>
43: public class MduDev
44: {
45: /// <summary/>
46: public int Did;
47:
48: /// <summary/>
49: public string Dev;
50:
51: /// <summary/>
52: public Ia.Ngn.Cl.Model.Business.Huawei.Dev.Type DevType;
53:
54: /// <summary/>
55: public string DevIp;
56:
57: /// <summary/>
58: public string AccessName;
59:
60: /// <summary/>
61: public string AccessId;
62:
63: /// <summary/>
64: public string NddOntId;
65:
66: /// <summary/>
67: public int TelPortCount;
68:
69: /// <summary/>
70: public int EthernetPortCount;
71:
72: /// <summary/>
73: public List<Ia.Ngn.Cl.Model.Business.Huawei.Default.FnSnPnPort> PossibleFnSnPnPortList;
74:
75: /// <summary/>
76: public Ia.Ngn.Cl.Model.Business.Huawei.Default.FnSnPnPort FirstFnSnPnPort;
77:
78: /// <summary/>
79: public List<Ia.Ngn.Cl.Model.Business.Huawei.Board.MduDevBoard> MduDevBoardList;
80:
81: ////////////////////////////////////////////////////////////////////////////
82:
83: /// <summary>
84: ///
85: /// </summary>
86: public MduDev(int did)
87: {
88: string dev, accessName, s;
89:
90: var didToDevDictionary = Ia.Ngn.Cl.Model.Data.Huawei.Dev.DidToDevDictionary;
91:
92: var ontAccessNameToOntIdDictionary = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntAccessNameToOntIdDictionary;
93: var ontAccessNameToOntAccessIdDictionary = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntAccessNameToOntAccessIdDictionary;
94:
95: if (didToDevDictionary.ContainsKey(did))
96: {
97: dev = didToDevDictionary[did];
98: s = Ia.Ngn.Cl.Model.Business.Huawei.Ems.HuaweiAccessNameFormatFromInaccurateHuaweiFileAndEmsNameFormat(dev);
99: accessName = Ia.Ngn.Cl.Model.Business.Default.StandardizeAccessNameInLegalFormatFromValue(s);
100:
101: this.Did = did;
102: this.Dev = dev;
103:
104: this.AccessName = accessName;
105:
106: this.NddOntId = ontAccessNameToOntIdDictionary.ContainsKey(accessName) ? ontAccessNameToOntIdDictionary[accessName] : this.NddOntId = string.Empty;
107: this.AccessId = ontAccessNameToOntAccessIdDictionary.ContainsKey(accessName) ? ontAccessNameToOntAccessIdDictionary[accessName] : this.AccessId = string.Empty;
108: }
109: else
110: {
111: //throw new System.Exception("DidToDevDictionary does not contain did key: " + did);
112: }
113: }
114:
115: ////////////////////////////////////////////////////////////////////////////
116:
117: /// <summary>
118: ///
119: /// </summary>
120: public int PortByFnSnPn(int fn, int sn, int pn)
121: {
122: int port;
123:
124: var list = this.PossibleFnSnPnPortList;
125:
126: if (list != null)
127: {
128: var fnSnPnPort = (from l in list where l.Fn == fn && l.Sn == sn && l.Pn == pn select l).SingleOrDefault();
129:
130: if (fnSnPnPort != null) port = fnSnPnPort.Port;
131: else port = Ia.Ngn.Cl.Model.Business.Default.PortUndefinedOrInvalidOrUnknown;
132: }
133: else port = Ia.Ngn.Cl.Model.Business.Default.PortUndefinedOrInvalidOrUnknown;
134:
135: return port;
136: }
137:
138: ////////////////////////////////////////////////////////////////////////////
139:
140: /// <summary>
141: ///
142: /// </summary>
143: public override string ToString()
144: {
145: string line;
146:
147: line = "Dev: " + this.Dev + ", AccessName: " + this.AccessName;
148:
149: return line;
150: }
151:
152: ////////////////////////////////////////////////////////////////////////////
153: ////////////////////////////////////////////////////////////////////////////
154: }
155:
156: ////////////////////////////////////////////////////////////////////////////
157: ////////////////////////////////////////////////////////////////////////////
158:
159: /// <summary>
160: ///
161: /// </summary>
162: public class MsanDev
163: {
164: private static int fixedLengthOfMsanDevId = Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Msan.FixedLengthOfMsanId + 2 + 2;
165:
166: /// <summary/>
167: public static int FixedLengthOfMsanDevId { get { return fixedLengthOfMsanDevId; } }
168:
169: /// <summary/>
170: public int Did, Cabinet, Frame, Capacity = 1028;
171:
172: /// <summary/>
173: public string Id, Dev;
174:
175: /// <summary/>
176: public List<Ia.Ngn.Cl.Model.Business.Huawei.Default.FnSnPnPort> PossibleFnSnPnList;
177:
178: /// <summary/>
179: public Ia.Ngn.Cl.Model.Business.Huawei.Default.FnSnPnPort FirstFnSnPn;
180:
181: /// <summary/>
182: public Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Msan Msan;
183:
184: ////////////////////////////////////////////////////////////////////////////
185:
186: /// <summary>
187: ///
188: /// </summary>
189: public class Lic
190: {
191: /// <summary/>
192: public string EmsVoipPstnUserId { get; set; }
193:
194: /// <summary/>
195: public int Did { get; set; }
196:
197: /// <summary/>
198: public int Fn { get; set; }
199:
200: /// <summary/>
201: public int Sn { get; set; }
202:
203: /// <summary/>
204: public int Pn { get; set; }
205:
206: /// <summary/>
207: public string Dn { get; set; }
208:
209: /// <summary/>
210: public string Service { get; set; }
211:
212: /// <summary/>
213: public int Cabinet { get; set; }
214:
215: /// <summary/>
216: public int Frame { get; set; }
217:
218: /// <summary/>
219: public string MsanId { get; set; }
220:
221: /// <summary/>
222: public string MsanNameSymbol { get; set; }
223:
224: /// <summary/>
225: public string MsanDevId { get; set; }
226:
227: /// <summary/>
228: public string MsanDevDev { get; set; }
229:
230: /// <summary/>
231: public string Name
232: {
233: get
234: {
235: return ToMsanNameSymbolCabinetFrameSnPnTextString();
236: }
237: }
238:
239: /// <summary/>
240: public DateTime Created { get; set; }
241:
242: /// <summary/>
243: public DateTime Updated { get; set; }
244:
245: ////////////////////////////////////////////////////////////////////////////
246:
247: /// <summary>
248: ///
249: /// </summary>
250: public Lic()
251: {
252: this.EmsVoipPstnUserId = string.Empty;
253: this.Did = 0;
254: this.Fn = 0;
255: this.Sn = 0;
256: this.Pn = 0;
257: this.Dn = string.Empty;
258: this.MsanId = string.Empty;
259: this.MsanNameSymbol = string.Empty;
260: this.MsanDevId = string.Empty;
261: this.MsanDevDev = string.Empty;
262: }
263:
264: ////////////////////////////////////////////////////////////////////////////
265:
266: /// <summary>
267: ///
268: /// </summary>
269: public string ToCabinetFrameSnPnTextString()
270: {
271: var s = this.Cabinet + "-" + this.Frame + "-" + this.Sn + "-" + this.Pn;
272:
273: return s;
274: }
275:
276: ////////////////////////////////////////////////////////////////////////////
277:
278: /// <summary>
279: ///
280: /// </summary>
281: public string ToMsanDevDevCabinetFrameFnSnPnTextString()
282: {
283: var s = this.MsanDevDev + "-" + this.Cabinet + "-" + this.Frame + "-" + this.Fn + "-" + this.Sn + "-" + this.Pn;
284:
285: return s;
286: }
287:
288: ////////////////////////////////////////////////////////////////////////////
289:
290: /// <summary>
291: ///
292: /// </summary>
293: public string ToMsanDevDevSnPnTextString()
294: {
295: var s = this.MsanDevDev + "-" + this.Sn + "-" + this.Pn;
296:
297: return s;
298: }
299:
300: ////////////////////////////////////////////////////////////////////////////
301:
302: /// <summary>
303: ///
304: /// </summary>
305: public string ToMsanNameSymbolCabinetFrameSnPnTextString()
306: {
307: var s = this.MsanNameSymbol + "-" + this.Cabinet + "-" + this.Frame + "-" + this.Sn + "-" + this.Pn;
308:
309: return s;
310: }
311:
312: ////////////////////////////////////////////////////////////////////////////
313:
314: /// <summary>
315: ///
316: /// </summary>
317: public static Lic Parse(string input)
318: {
319: Ia.Ngn.Cl.Model.Business.Huawei.Dev.MsanDev.Lic lic;
320:
321: if (Parse(input, out string msanNameSymbol, out int cabinet, out int frame, out int sn, out int pn))
322: {
323: var msan = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.MsanFromNameSymbol(msanNameSymbol);
324:
325: if (msan != null)
326: {
327: lic = Ia.Ngn.Cl.Model.Data.Huawei.VoipPstnUser.MsanDevLicByNddMsanAndCabinetAndFrameAndFnAndSnAndPn(msan, cabinet, frame, 0, sn, pn);
328: }
329: else lic = null;
330: }
331: else lic = null;
332:
333: return lic;
334: }
335:
336: ////////////////////////////////////////////////////////////////////////////
337:
338: /// <summary>
339: ///
340: /// </summary>
341: private static bool Parse(string input, out string msanSiteSymbolName, out int cabinet, out int frame, out int sn, out int pn)
342: {
343: bool parseSuccess;
344: int i;
345:
346: if (!string.IsNullOrEmpty(input))
347: {
348: var match = Regex.Match(input, @"^([a-zA-Z]{3})\-(\d{1,2})\-(\d{1,2})\-(\d{1,2})\-(\d{1,2})$", RegexOptions.Singleline);
349:
350: if (match.Success)
351: {
352: msanSiteSymbolName = match.Groups[1].Value.ToUpper();
353:
354: cabinet = int.TryParse(match.Groups[2].Value, out i) ? i : Ia.Ngn.Cl.Model.Business.Default.PortUndefinedOrInvalidOrUnknown;
355: frame = int.TryParse(match.Groups[3].Value, out i) ? i : Ia.Ngn.Cl.Model.Business.Default.PortUndefinedOrInvalidOrUnknown;
356: sn = int.TryParse(match.Groups[4].Value, out i) ? i : Ia.Ngn.Cl.Model.Business.Default.PortUndefinedOrInvalidOrUnknown;
357: pn = int.TryParse(match.Groups[5].Value, out i) ? i : Ia.Ngn.Cl.Model.Business.Default.PortUndefinedOrInvalidOrUnknown;
358:
359: parseSuccess = true;
360: }
361: else
362: {
363: msanSiteSymbolName = string.Empty;
364: cabinet = frame = sn = pn = -1;
365:
366: parseSuccess = false;
367: }
368: }
369: else
370: {
371: msanSiteSymbolName = string.Empty;
372: cabinet = frame = sn = pn = -1;
373:
374: parseSuccess = false;
375: }
376:
377: return parseSuccess;
378: }
379: }
380:
381: ////////////////////////////////////////////////////////////////////////////
382:
383: /// <summary>
384: ///
385: /// </summary>
386: public MsanDev(int did)
387: {
388: bool msanExists;
389: var didToDevDictionary = Ia.Ngn.Cl.Model.Data.Huawei.Dev.DidToDevDictionary;
390:
391: if (didToDevDictionary.ContainsKey(did))
392: {
393: var dev = didToDevDictionary[did];
394:
395: msanExists = ExtractMsanAndCabinetAndFrameFromDev(dev, out Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Msan msan, out int cabinet, out int frame);
396:
397: if (msanExists)
398: {
399: this.Dev = dev;
400: this.Did = did;
401: this.Msan = msan;
402: this.Cabinet = cabinet;
403: this.Frame = frame;
404:
405: this.Id = MsanDevId(msan.Id, cabinet, frame);
406: }
407: }
408: else
409: {
410: //throw new System.Exception("DidToDevDictionary does not contain did key: " + did);
411: }
412: }
413:
414: ////////////////////////////////////////////////////////////////////////////
415:
416: /// <summary>
417: ///
418: /// </summary>
419: private string MsanDevId(string msanId, int cabinet, int frame)
420: {
421: var id = msanId + cabinet.ToString().PadLeft(2, '0') + frame.ToString().PadLeft(2, '0');
422:
423: if (id.Length != fixedLengthOfMsanDevId)
424: {
425: throw new ArgumentOutOfRangeException(@"MsanDevId(): Id length is not " + fixedLengthOfMsanDevId);
426: }
427:
428: return id;
429: }
430:
431: ////////////////////////////////////////////////////////////////////////////
432:
433: /// <summary>
434: ///
435: /// </summary>
436: private bool ExtractMsanAndCabinetAndFrameFromDev(string dev, out Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Msan msan, out int cabinet, out int frame)
437: {
438: bool msanExists;
439: string msanNameSymbol;
440: Match match;
441:
442: if (!string.IsNullOrEmpty(dev))
443: {
444: // e.g. ARD_MSAN_Cabinet 1_Frame 0
445: match = Regex.Match(dev, @"^(.+)_MSAN_Cabinet (\d+)_Frame (\d+)$", RegexOptions.Singleline);
446:
447: if (match.Success)
448: {
449: msanNameSymbol = match.Groups[1].Value;
450: msan = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.MsanFromNameSymbol(msanNameSymbol);
451:
452: cabinet = int.Parse(match.Groups[2].Value);
453: frame = int.Parse(match.Groups[3].Value);
454: }
455: else
456: {
457: // e.g. SLM_MSAN_A01_F00 or SSB_MSAN_B01_F00
458: match = Regex.Match(dev, @"(\w+)_MSAN_\w(\d+)_\w(\d+)", RegexOptions.Singleline);
459:
460: if (match.Success)
461: {
462: msanNameSymbol = match.Groups[1].Value;
463: msan = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.MsanFromNameSymbol(msanNameSymbol);
464:
465: cabinet = int.Parse(match.Groups[2].Value);
466: frame = int.Parse(match.Groups[3].Value);
467: }
468: else
469: {
470: msan = null;
471: cabinet = frame = -1;
472: //throw new Exception("Dev format " + dev + " is not readable.");
473: }
474: }
475: }
476: else
477: {
478: msan = null;
479: cabinet = frame = -1;
480: //throw new Exception("Dev is null.");
481: }
482:
483: msanExists = msan != null;
484:
485: return msanExists;
486: }
487:
488: ////////////////////////////////////////////////////////////////////////////
489:
490: /// <summary>
491: ///
492: /// </summary>
493: public override string ToString()
494: {
495: string line;
496:
497: line = "Dev: " + this.Dev + ", MSAN name: " + this.Dev;
498:
499: return line;
500: }
501:
502: ////////////////////////////////////////////////////////////////////////////
503: ////////////////////////////////////////////////////////////////////////////
504: }
505:
506: ////////////////////////////////////////////////////////////////////////////
507: ////////////////////////////////////////////////////////////////////////////
508:
509: /// <summary>
510: ///
511: /// </summary>
512: public Dev() { }
513:
514: ////////////////////////////////////////////////////////////////////////////
515:
516: /// <summary>
517: ///
518: /// </summary>
519: public static int DevId(int did)
520: {
521: /*
522: * Id: OLT_01 Id-Frame-Slot-Port-OnuID
523: * FN SN PN ONTID
524: *
525: * Dev: did
526: * Board: FN SN
527: * Port: FN SN PN
528: * Ont: FN SN PN ONTID
529: *
530: * /// FN INTEGER 0-255 Indicates the subrack ID of the OLT.
531: * /// SN INTEGER 0-35 Indicates the slot ID of the OLT.
532: * /// PN INTEGER 0-63 Indicates the port ID of the OLT.
533: * /// ONTID INTEGER 0-255 NOTE If the UNI port is of 10G GPON, the value range is 0-255; if the UNI port is of 1G GPON, the value range is 0-127. Indicates the ONT ID.
534: */
535:
536: int id;
537:
538: id = did;
539:
540: return id;
541: }
542:
543: ////////////////////////////////////////////////////////////////////////////
544:
545: /// <summary>
546: ///
547: /// </summary>
548: public static Ia.Ngn.Cl.Model.Huawei.EmsDev SequentialEmsDevListItem(out int sequentialEmsDevDevQueueCount, out string progressCounterString)
549: {
550: Ia.Ngn.Cl.Model.Huawei.EmsDev item;
551: List<Ia.Ngn.Cl.Model.Huawei.EmsDev> list;
552:
553: if (sequentialEmsDevDevQueue.Count == 0)
554: {
555: list = Ia.Ngn.Cl.Model.Data.Huawei.Dev.List();
556: //list = Ia.Ngn.Cl.Model.Data.Huawei.Default.AccessListBy5616Or5878OntEquipmentId();
557:
558: sequentialEmsDevDevQueue = new Queue<Ia.Ngn.Cl.Model.Huawei.EmsDev>(list.Shuffle());
559:
560: sequentialEmsDevDevQueueOriginalCount = sequentialEmsDevDevQueue.Count;
561: }
562:
563: if (sequentialEmsDevDevQueue.Count > 0) item = sequentialEmsDevDevQueue.Dequeue();
564: else item = null;
565:
566: progressCounterString = "(" + sequentialEmsDevDevQueue.Count + "/" + sequentialEmsDevDevQueueOriginalCount + ")";
567:
568: sequentialEmsDevDevQueueCount = sequentialEmsDevDevQueue.Count;
569:
570: return item;
571: }
572:
573: ////////////////////////////////////////////////////////////////////////////
574:
575: /// <summary>
576: ///
577: /// </summary>
578: public static Ia.Ngn.Cl.Model.Huawei.EmsPort SequentialEmsMsanDevPortListItem(out int sequentialEmsMsanDevPortQueueCount, out string progressCounterString)
579: {
580: Ia.Ngn.Cl.Model.Huawei.EmsPort item;
581: List<Ia.Ngn.Cl.Model.Huawei.EmsPort> list;
582:
583: if (sequentialEmsMsanDevPortQueue.Count == 0)
584: {
585: var msan = Ia.Ngn.Cl.Model.Data.Huawei.Default.MsanDevList.RandomThenNext();
586:
587: list = Ia.Ngn.Cl.Model.Data.Huawei.Default.MsanPortList(msan);
588:
589: sequentialEmsMsanDevPortQueue = new Queue<Ia.Ngn.Cl.Model.Huawei.EmsPort>(list);
590:
591: sequentialEmsMsanDevPortQueueOriginalCount = sequentialEmsMsanDevPortQueue.Count;
592: }
593:
594: if (sequentialEmsMsanDevPortQueue.Count > 0) item = sequentialEmsMsanDevPortQueue.Dequeue();
595: else item = null;
596:
597: progressCounterString = "(" + sequentialEmsMsanDevPortQueue.Count + "/" + sequentialEmsMsanDevPortQueueOriginalCount + ")";
598:
599: sequentialEmsMsanDevPortQueueCount = sequentialEmsMsanDevPortQueue.Count;
600:
601: return item;
602: }
603:
604: ////////////////////////////////////////////////////////////////////////////
605: ////////////////////////////////////////////////////////////////////////////
606: }
607:
608: ////////////////////////////////////////////////////////////////////////////
609: ////////////////////////////////////////////////////////////////////////////
610: }